diff --git a/DEPS b/DEPS index 4f3f84b..8b4e9df 100644 --- a/DEPS +++ b/DEPS
@@ -121,11 +121,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '5820b0c3f3ceba23b9d80415e77a9db124b409b8', + 'skia_revision': '5f1692c60a43bfb9f9039e288862c82a9f7cbc8e', # 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': '686bde10b4672f2a67745b692f281d61ae0d9d5c', + 'v8_revision': '5df21f21f1704932e73a91c8935f68126d408092', # 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. @@ -133,7 +133,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': '225f08bf85a368f905362cdd1366e4795680452c', + 'angle_revision': 'e4109f27136d721659e7b545aaead2815fef2918', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. @@ -181,7 +181,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': 'ebf0d23ee62ec1b476cc8a0c8616b6d295271680', + 'catapult_revision': '51771a7cad87fdf00c949740c06205e71de8830a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -245,7 +245,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': '0b364067d04c49fa2f828905300bd7eb56dd3b9b', + 'dawn_revision': '93158ebede898d3f243c375d30fe287c069a69e7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -679,7 +679,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'c48496fe54a9ff1850b2b718697d29d4a1264ff4', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '8743424b5d6d73e0c62cc87a21f9ac17f151495e', 'condition': 'checkout_linux', }, @@ -694,7 +694,7 @@ # For Linux and Chromium OS. 'src/third_party/cros_system_api': { - 'url': Var('chromium_git') + '/chromiumos/platform2/system_api.git' + '@' + '825055dd83837f1bb88332a0bad712e95651eb67', + 'url': Var('chromium_git') + '/chromiumos/platform2/system_api.git' + '@' + 'ea44d5db9e74027d28ef383156c754627a68dfe1', 'condition': 'checkout_linux', }, @@ -704,7 +704,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '4ad409510d23a438265bf225b544d010e5b5f678', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '936a994608348285d6120127c906893ae1d37c24', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -1036,7 +1036,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '4f718c120c1ed81c4ec44867f2984c51d6fdc498', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '43f09d829d87e595baeb9c27bf4a859e079a675f', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78', @@ -1230,7 +1230,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@447d7854291eb3325cbc58c413f4a3f7b3faf263', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@dd0edf7144157d89448238b6c1ea828e6507147d', 'condition': 'checkout_src_internal', },
diff --git a/base/task/sequence_manager/task_queue_selector.cc b/base/task/sequence_manager/task_queue_selector.cc index fc28b9a..5f301b0 100644 --- a/base/task/sequence_manager/task_queue_selector.cc +++ b/base/task/sequence_manager/task_queue_selector.cc
@@ -20,8 +20,8 @@ TaskQueueSelector::TaskQueueSelector( scoped_refptr<AssociatedThreadId> associated_thread) : associated_thread_(std::move(associated_thread)), - delayed_work_queue_sets_(TaskQueue::kQueuePriorityCount, "delayed"), - immediate_work_queue_sets_(TaskQueue::kQueuePriorityCount, "immediate") {} + delayed_work_queue_sets_("delayed"), + immediate_work_queue_sets_("immediate") {} TaskQueueSelector::~TaskQueueSelector() = default;
diff --git a/base/task/sequence_manager/work_queue_sets.cc b/base/task/sequence_manager/work_queue_sets.cc index c936ad1..b940be9 100644 --- a/base/task/sequence_manager/work_queue_sets.cc +++ b/base/task/sequence_manager/work_queue_sets.cc
@@ -10,8 +10,7 @@ namespace sequence_manager { namespace internal { -WorkQueueSets::WorkQueueSets(size_t num_sets, const char* name) - : work_queue_heaps_(num_sets), name_(name) {} +WorkQueueSets::WorkQueueSets(const char* name) : name_(name) {} WorkQueueSets::~WorkQueueSets() = default;
diff --git a/base/task/sequence_manager/work_queue_sets.h b/base/task/sequence_manager/work_queue_sets.h index a1d6dcb0..4889b2f 100644 --- a/base/task/sequence_manager/work_queue_sets.h +++ b/base/task/sequence_manager/work_queue_sets.h
@@ -5,8 +5,8 @@ #ifndef BASE_TASK_SEQUENCE_MANAGER_WORK_QUEUE_SETS_H_ #define BASE_TASK_SEQUENCE_MANAGER_WORK_QUEUE_SETS_H_ +#include <array> #include <map> -#include <vector> #include "base/base_export.h" #include "base/logging.h" @@ -28,7 +28,7 @@ // values are kept in sorted order. class BASE_EXPORT WorkQueueSets { public: - WorkQueueSets(size_t num_sets, const char* name); + explicit WorkQueueSets(const char* name); ~WorkQueueSets(); // O(log num queues) @@ -92,7 +92,8 @@ // For each set |work_queue_heaps_| has a queue of WorkQueue ordered by the // oldest task in each WorkQueue. - std::vector<base::internal::IntrusiveHeap<OldestTaskEnqueueOrder>> + std::array<base::internal::IntrusiveHeap<OldestTaskEnqueueOrder>, + TaskQueue::kQueuePriorityCount> work_queue_heaps_; const char* const name_;
diff --git a/base/task/sequence_manager/work_queue_sets_unittest.cc b/base/task/sequence_manager/work_queue_sets_unittest.cc index 0ea6c80..c8426fe5 100644 --- a/base/task/sequence_manager/work_queue_sets_unittest.cc +++ b/base/task/sequence_manager/work_queue_sets_unittest.cc
@@ -19,9 +19,7 @@ class WorkQueueSetsTest : public testing::Test { public: - void SetUp() override { - work_queue_sets_.reset(new WorkQueueSets(kNumSets, "test")); - } + void SetUp() override { work_queue_sets_.reset(new WorkQueueSets("test")); } void TearDown() override { for (std::unique_ptr<WorkQueue>& work_queue : work_queues_) { @@ -31,10 +29,6 @@ } protected: - enum { - kNumSets = 5 // An arbitary choice. - }; - WorkQueue* NewTaskQueue(const char* queue_name) { WorkQueue* queue = new WorkQueue(nullptr, "test", WorkQueue::QueueType::kImmediate);
diff --git a/base/task/sequence_manager/work_queue_unittest.cc b/base/task/sequence_manager/work_queue_unittest.cc index 938dae30..23fc3ee 100644 --- a/base/task/sequence_manager/work_queue_unittest.cc +++ b/base/task/sequence_manager/work_queue_unittest.cc
@@ -47,7 +47,7 @@ work_queue_.reset(new WorkQueue(task_queue_.get(), "test", WorkQueue::QueueType::kImmediate)); - work_queue_sets_.reset(new WorkQueueSets(1, "test")); + work_queue_sets_.reset(new WorkQueueSets("test")); work_queue_sets_->AddQueue(work_queue_.get(), 0); }
diff --git a/cc/mojo_embedder/async_layer_tree_frame_sink.cc b/cc/mojo_embedder/async_layer_tree_frame_sink.cc index 7971821af..ef6328a 100644 --- a/cc/mojo_embedder/async_layer_tree_frame_sink.cc +++ b/cc/mojo_embedder/async_layer_tree_frame_sink.cc
@@ -329,7 +329,8 @@ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "step", "ReceiveBeginFrameDiscard"); // We had a race with SetNeedsBeginFrame(false) and still need to let the - // sink know that we didn't use this BeginFrame. + // sink know that we didn't use this BeginFrame. OnBeginFrame() can also be + // called to deliver presentation feedback. DidNotProduceFrame(viz::BeginFrameAck(args, false)); return; }
diff --git a/chrome/android/java/res/drawable/chip_bg.xml b/chrome/android/java/res/drawable/chip_bg.xml deleted file mode 100644 index 33b69db..0000000 --- a/chrome/android/java/res/drawable/chip_bg.xml +++ /dev/null
@@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- 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. ---> - -<shape xmlns:android="http://schemas.android.com/apk/res/android"> - <solid android:color="@color/chip_background_color" /> - <stroke android:width="1dp" android:color="@color/chip_stroke_color" /> - <corners android:radius="8dp" /> -</shape> \ No newline at end of file
diff --git a/chrome/android/java/res/layout-sw360dp/preference_spinner_single_line.xml b/chrome/android/java/res/layout-sw360dp/preference_spinner_single_line.xml index 471e705..3a5b5bb 100644 --- a/chrome/android/java/res/layout-sw360dp/preference_spinner_single_line.xml +++ b/chrome/android/java/res/layout-sw360dp/preference_spinner_single_line.xml
@@ -17,7 +17,7 @@ <TextView android:id="@+id/title" style="@style/PreferenceTitle" - android:textAppearance="@style/BlackHint1" + android:textAppearance="@style/TextAppearance.BlackHint1" android:textAlignment="viewStart" android:layout_height="wrap_content" android:layout_width="0dp"
diff --git a/chrome/android/java/res/layout/account_chooser_dialog_item.xml b/chrome/android/java/res/layout/account_chooser_dialog_item.xml index d6e2c139..78a8512 100644 --- a/chrome/android/java/res/layout/account_chooser_dialog_item.xml +++ b/chrome/android/java/res/layout/account_chooser_dialog_item.xml
@@ -31,14 +31,14 @@ android:layout_height="wrap_content" android:ellipsize="end" android:singleLine="true" - android:textAppearance="@style/BlackTitle1" /> + android:textAppearance="@style/TextAppearance.BlackTitle1" /> <TextView android:id="@+id/secondary_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ellipsize="end" android:singleLine="true" - android:textAppearance="@style/BlackBody" /> + android:textAppearance="@style/TextAppearance.BlackBody" /> </LinearLayout> <ImageButton android:id="@+id/psl_info_btn"
diff --git a/chrome/android/java/res/layout/account_chooser_dialog_title.xml b/chrome/android/java/res/layout/account_chooser_dialog_title.xml index e469af05..0bb6e45 100644 --- a/chrome/android/java/res/layout/account_chooser_dialog_title.xml +++ b/chrome/android/java/res/layout/account_chooser_dialog_title.xml
@@ -15,13 +15,13 @@ android:layout_height="wrap_content" android:ellipsize="end" android:lineSpacingExtra="4dp" - android:textAppearance="@style/BlackTitle1" /> + android:textAppearance="@style/TextAppearance.BlackTitle1" /> <TextView android:id="@+id/origin" android:layout_width="match_parent" android:layout_height="wrap_content" android:ellipsize="end" android:paddingTop="8dp" - android:textAppearance="@style/BlackBody" /> + android:textAppearance="@style/TextAppearance.BlackBody" /> </LinearLayout>
diff --git a/chrome/android/java/res/layout/account_picker_new_account_row.xml b/chrome/android/java/res/layout/account_picker_new_account_row.xml index 711ab28..0ca03ec 100644 --- a/chrome/android/java/res/layout/account_picker_new_account_row.xml +++ b/chrome/android/java/res/layout/account_picker_new_account_row.xml
@@ -11,4 +11,4 @@ android:gravity="center_vertical" android:padding="8dp" android:text="@string/signin_add_account" - android:textAppearance="@style/BlackBodyDefault"/> + android:textAppearance="@style/TextAppearance.BlackBodyDefault"/>
diff --git a/chrome/android/java/res/layout/account_picker_row.xml b/chrome/android/java/res/layout/account_picker_row.xml index 6afe019..044c66e 100644 --- a/chrome/android/java/res/layout/account_picker_row.xml +++ b/chrome/android/java/res/layout/account_picker_row.xml
@@ -28,7 +28,7 @@ android:layout_height="wrap_content" android:gravity="center_vertical" android:minHeight="20dp" - android:textAppearance="@style/BlackBodyDefault" + android:textAppearance="@style/TextAppearance.BlackBodyDefault" tools:text="John Doe"/> <TextView android:id="@+id/account_text_secondary" @@ -36,7 +36,7 @@ android:layout_height="wrap_content" android:gravity="center_vertical" android:minHeight="20dp" - android:textAppearance="@style/BlackCaption" + android:textAppearance="@style/TextAppearance.BlackCaption" tools:text="john.doe@example.com"/> </LinearLayout> <ImageView
diff --git a/chrome/android/java/res/layout/account_signin_view.xml b/chrome/android/java/res/layout/account_signin_view.xml index c6e80c5..359b8433 100644 --- a/chrome/android/java/res/layout/account_signin_view.xml +++ b/chrome/android/java/res/layout/account_signin_view.xml
@@ -41,7 +41,7 @@ android:paddingEnd="@dimen/signin_chooser_padding" android:paddingBottom="@dimen/signin_chooser_padding" android:background="@color/signin_head_background" - android:textAppearance="@style/BlackHeadline" + android:textAppearance="@style/TextAppearance.BlackHeadline" android:text="@string/sign_in_to_chrome"/> <View style="@style/HorizontalDivider"/> @@ -53,7 +53,7 @@ android:padding="@dimen/signin_chooser_padding" android:lineSpacingMultiplier="1.4" android:text="@string/signin_account_choice_description" - android:textAppearance="@style/BlackBodyDefault"/> + android:textAppearance="@style/TextAppearance.BlackBodyDefault"/> </LinearLayout> </org.chromium.chrome.browser.signin.AccountSigninChooseView> @@ -96,7 +96,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="8dp" - android:textAppearance="@style/BlackHeadline" + android:textAppearance="@style/TextAppearance.BlackHeadline" android:ellipsize="end" android:maxLines="1"/> @@ -105,7 +105,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" - android:textAppearance="@style/BlackBody" + android:textAppearance="@style/TextAppearance.BlackBody" android:ellipsize="end" android:maxLines="1"/> </LinearLayout> @@ -120,7 +120,7 @@ android:layout_marginBottom="8dp" android:paddingStart="16dp" android:paddingEnd="16dp" - android:textAppearance="@style/BlackTitle2" + android:textAppearance="@style/TextAppearance.BlackTitle2" android:drawableStart="@drawable/chrome_sync_logo" android:drawablePadding="16dp"/> @@ -132,7 +132,7 @@ android:paddingStart="56dp" android:paddingEnd="16dp" android:lineSpacingMultiplier="1.4" - android:textAppearance="@style/BlackBody" /> + android:textAppearance="@style/TextAppearance.BlackBody" /> <View style="@style/HorizontalDivider" @@ -147,7 +147,7 @@ android:layout_marginBottom="8dp" android:paddingStart="16dp" android:paddingEnd="16dp" - android:textAppearance="@style/BlackTitle2" + android:textAppearance="@style/TextAppearance.BlackTitle2" android:drawableStart="@drawable/ic_logo_googleg_24dp" android:drawablePadding="16dp"/> @@ -159,7 +159,7 @@ android:paddingStart="56dp" android:paddingEnd="16dp" android:lineSpacingMultiplier="1.4" - android:textAppearance="@style/BlackBody" /> + android:textAppearance="@style/TextAppearance.BlackBody" /> <org.chromium.ui.widget.TextViewWithClickableSpans android:id="@+id/signin_settings_control" @@ -169,7 +169,7 @@ android:paddingEnd="16dp" android:paddingBottom="36dp" android:lineSpacingMultiplier="1.4" - android:textAppearance="@style/BlackBody" /> + android:textAppearance="@style/TextAppearance.BlackBody" /> </LinearLayout> </org.chromium.chrome.browser.signin.AccountSigninConfirmationView> </FrameLayout>
diff --git a/chrome/android/java/res/layout/add_to_homescreen_dialog.xml b/chrome/android/java/res/layout/add_to_homescreen_dialog.xml index 108c38b..12259c2 100644 --- a/chrome/android/java/res/layout/add_to_homescreen_dialog.xml +++ b/chrome/android/java/res/layout/add_to_homescreen_dialog.xml
@@ -32,7 +32,7 @@ android:inputType="text" android:layout_width="match_parent" android:layout_height="32dp" - android:textSize="18sp" + android:textAppearance="@style/TextAppearance.AddToHomeScreenEditText" android:singleLine="true" android:paddingTop="0dp" android:layout_marginTop="10dp" @@ -56,8 +56,7 @@ android:id="@+id/name" android:layout_width="match_parent" android:layout_height="wrap_content" - android:textSize="20sp" - android:textAppearance="@style/BlackTitle1" /> + android:textAppearance="@style/TextAppearance.AddToHomeScreenWebAppName" /> <!-- The origin of the web app, displayed for security purposes. --> <TextView @@ -65,7 +64,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingBottom="2dp" - android:textAppearance="@style/BlackBody" /> + android:textAppearance="@style/TextAppearance.BlackBody" /> <!-- The rating bar used for Play Store app ratings for native apps. Displayed in place of the origin. -->
diff --git a/chrome/android/java/res/layout/autofill_billing_address_dropdown.xml b/chrome/android/java/res/layout/autofill_billing_address_dropdown.xml index 9948afe..d9c9dd9 100644 --- a/chrome/android/java/res/layout/autofill_billing_address_dropdown.xml +++ b/chrome/android/java/res/layout/autofill_billing_address_dropdown.xml
@@ -11,7 +11,7 @@ android:layout_marginStart="@dimen/pref_autofill_field_horizontal_padding" android:layout_marginEnd="@dimen/pref_autofill_field_horizontal_padding" android:labelFor="@+id/autofill_credit_card_editor_billing_address_spinner" - android:textAppearance="@style/BlackCaption" + android:textAppearance="@style/TextAppearance.BlackCaption" android:text="@string/autofill_credit_card_editor_billing_address" /> <android.support.v7.widget.AppCompatSpinner
diff --git a/chrome/android/java/res/layout/autofill_card_unmask_prompt.xml b/chrome/android/java/res/layout/autofill_card_unmask_prompt.xml index d4b957a..07609bc 100644 --- a/chrome/android/java/res/layout/autofill_card_unmask_prompt.xml +++ b/chrome/android/java/res/layout/autofill_card_unmask_prompt.xml
@@ -119,7 +119,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" - android:textAppearance="@style/BlueLink2" + android:textAppearance="@style/TextAppearance.BlueLink2" android:text="@string/autofill_card_unmask_new_card_link" android:visibility="gone" /> </LinearLayout> @@ -201,6 +201,6 @@ android:id="@+id/verification_message" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textAppearance="@style/BlueTitle2" /> + android:textAppearance="@style/TextAppearance.BlueTitle2" /> </LinearLayout> </RelativeLayout>
diff --git a/chrome/android/java/res/layout/autofill_local_card_editor.xml b/chrome/android/java/res/layout/autofill_local_card_editor.xml index fd3f1765..8b6ffa33 100644 --- a/chrome/android/java/res/layout/autofill_local_card_editor.xml +++ b/chrome/android/java/res/layout/autofill_local_card_editor.xml
@@ -60,7 +60,7 @@ android:layout_marginTop="@dimen/pref_autofill_field_top_margin" android:layout_marginStart="@dimen/pref_autofill_field_horizontal_padding" android:layout_marginEnd="@dimen/pref_autofill_field_horizontal_padding" - android:textAppearance="@style/BlackCaption" + android:textAppearance="@style/TextAppearance.BlackCaption" android:text="@string/autofill_credit_card_editor_expiration_date" /> <LinearLayout
diff --git a/chrome/android/java/res/layout/bookmark_add_edit_folder_activity.xml b/chrome/android/java/res/layout/bookmark_add_edit_folder_activity.xml index 3dd27a8a..e676be23 100644 --- a/chrome/android/java/res/layout/bookmark_add_edit_folder_activity.xml +++ b/chrome/android/java/res/layout/bookmark_add_edit_folder_activity.xml
@@ -31,7 +31,7 @@ android:hint="@string/title" android:imeOptions="flagNoExtractUi" android:inputType="textCapSentences|textAutoCorrect" - android:textAppearance="@style/BlackHeadline" + android:textAppearance="@style/TextAppearance.BlackHeadline" app:alertMessage="@string/bookmark_missing_title" /> <TextView @@ -42,7 +42,7 @@ android:layout_marginStart="16dp" android:layout_marginTop="24dp" android:text="@string/bookmark_parent_folder" - android:textAppearance="@style/BlackHint2" /> + android:textAppearance="@style/TextAppearance.BlackHint2" /> <TextView android:id="@+id/parent_folder" @@ -51,7 +51,7 @@ android:layout_marginStart="16dp" android:layout_marginTop="8dp" android:layout_marginBottom="32dp" - android:textAppearance="@style/BlackTitle1" /> + android:textAppearance="@style/TextAppearance.BlackTitle1" /> </LinearLayout> </ScrollView>
diff --git a/chrome/android/java/res/layout/chip.xml b/chrome/android/java/res/layout/chip.xml deleted file mode 100644 index 6474757..0000000 --- a/chrome/android/java/res/layout/chip.xml +++ /dev/null
@@ -1,34 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- 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. ---> - -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:minHeight="32dp" - android:orientation="horizontal" - android:gravity="center_vertical" - android:background="@drawable/chip_bg"> - <org.chromium.ui.widget.ChromeImageView - android:id="@+id/icon" - android:layout_width="20dp" - android:layout_height="20dp" - android:layout_marginStart="8dp" - android:gravity="center" - android:scaleType="fitCenter" - app:tint="@color/dark_mode_tint" /> - <TextView - android:id="@+id/text" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:gravity="center" - android:maxLines="1" - android:paddingStart="@dimen/chip_icon_padding" - android:paddingEnd="@dimen/chip_no_icon_padding" - android:textAlignment="center" - android:textAppearance="@style/TextAppearance.DownloadHomeChip" /> -</LinearLayout>
diff --git a/chrome/android/java/res/layout/confirm_import_sync_data.xml b/chrome/android/java/res/layout/confirm_import_sync_data.xml index 450b99d..37338bc 100644 --- a/chrome/android/java/res/layout/confirm_import_sync_data.xml +++ b/chrome/android/java/res/layout/confirm_import_sync_data.xml
@@ -22,7 +22,7 @@ android:id="@+id/sync_import_data_prompt" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textAppearance="@style/BlackTitle1" /> + android:textAppearance="@style/TextAppearance.BlackTitle1" /> <org.chromium.chrome.browser.widget.RadioButtonWithDescription android:id="@+id/sync_confirm_import_choice"
diff --git a/chrome/android/java/res/layout/connection_info.xml b/chrome/android/java/res/layout/connection_info.xml index c029a17..bf24168 100644 --- a/chrome/android/java/res/layout/connection_info.xml +++ b/chrome/android/java/res/layout/connection_info.xml
@@ -31,15 +31,14 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingBottom="@dimen/connection_info_padding_thin" - style="@style/RobotoMediumStyle" - android:textColor="@color/connection_info_popup_text" /> + android:textAppearance="@style/TextAppearance.ConnectionInfoHeadline" /> <TextView android:id="@+id/connection_info_description" android:layout_width="wrap_content" android:layout_height="wrap_content" android:lineSpacingExtra="6dp" - android:textColor="@color/connection_info_popup_text" /> + android:textAppearance="@style/TextAppearance.ConnectionInfoDescription" /> </LinearLayout> </LinearLayout>
diff --git a/chrome/android/java/res/layout/contact_view.xml b/chrome/android/java/res/layout/contact_view.xml index d2e0a9a..f044343 100644 --- a/chrome/android/java/res/layout/contact_view.xml +++ b/chrome/android/java/res/layout/contact_view.xml
@@ -36,7 +36,7 @@ android:layout_width="wrap_content" android:paddingTop="5dp" android:layout_toEndOf="@id/image" - style="@style/BlackTitle1" /> + style="@style/TextAppearance.BlackTitle1" /> <TextView android:id="@+id/details" @@ -45,7 +45,7 @@ android:paddingBottom="5dp" android:layout_below="@id/name" android:layout_alignStart="@id/name" - style="@style/BlackBody"/> + style="@style/TextAppearance.BlackBody"/> <ImageView android:id="@+id/selected"
diff --git a/chrome/android/java/res/layout/content_suggestions_all_dismissed_card_modern.xml b/chrome/android/java/res/layout/content_suggestions_all_dismissed_card_modern.xml index d7c3622..9cde1ac 100644 --- a/chrome/android/java/res/layout/content_suggestions_all_dismissed_card_modern.xml +++ b/chrome/android/java/res/layout/content_suggestions_all_dismissed_card_modern.xml
@@ -35,7 +35,7 @@ android:layout_marginBottom="8dp" android:gravity="center_horizontal" android:text="@string/ntp_title_no_suggestions" - android:textAppearance="@style/BlackTitle1" + android:textAppearance="@style/TextAppearance.BlackTitle1" app:leading="24dp" /> <org.chromium.ui.widget.TextViewWithLeading @@ -46,7 +46,7 @@ android:layout_alignParentStart="true" android:gravity="center_horizontal" android:text="@string/ntp_all_dismissed_body_text_morning" - android:textAppearance="@style/BlackBody" + android:textAppearance="@style/TextAppearance.BlackBody" app:leading="20dp" /> <org.chromium.ui.widget.ButtonCompat
diff --git a/chrome/android/java/res/layout/content_suggestions_card_modern_reversed.xml b/chrome/android/java/res/layout/content_suggestions_card_modern_reversed.xml index bc2aedf6..15a3df9 100644 --- a/chrome/android/java/res/layout/content_suggestions_card_modern_reversed.xml +++ b/chrome/android/java/res/layout/content_suggestions_card_modern_reversed.xml
@@ -63,7 +63,7 @@ android:maxLines="1" android:singleLine="true" android:ellipsize="end" - android:textAppearance="@style/BlackCaption" + android:textAppearance="@style/TextAppearance.BlackCaption" android:textDirection="locale" tools:text="chromium.org"/> <TextView @@ -71,7 +71,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:maxLines="1" - android:textAppearance="@style/BlackCaption" + android:textAppearance="@style/TextAppearance.BlackCaption" android:textDirection="locale" tools:text=" - 3 hours ago" />
diff --git a/chrome/android/java/res/layout/contextual_search_bar_banner_text_view.xml b/chrome/android/java/res/layout/contextual_search_bar_banner_text_view.xml index 6d342b9..d3fc9e6 100644 --- a/chrome/android/java/res/layout/contextual_search_bar_banner_text_view.xml +++ b/chrome/android/java/res/layout/contextual_search_bar_banner_text_view.xml
@@ -18,7 +18,7 @@ android:id="@+id/contextual_search_iph_tap_text" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textAppearance="@style/WhiteBody" + android:textAppearance="@style/TextAppearance.WhiteBody" android:text="@string/contextual_search_iph_tap" /> </LinearLayout>
diff --git a/chrome/android/java/res/layout/contextual_search_promo_view.xml b/chrome/android/java/res/layout/contextual_search_promo_view.xml index 4406a03..7e3263d 100644 --- a/chrome/android/java/res/layout/contextual_search_promo_view.xml +++ b/chrome/android/java/res/layout/contextual_search_promo_view.xml
@@ -26,7 +26,7 @@ android:layout_marginStart="16dp" android:layout_marginEnd="16dp" android:bufferType="spannable" - android:textAppearance="@style/BlackTitle1" /> + android:textAppearance="@style/TextAppearance.BlackTitle1" /> <org.chromium.ui.widget.ButtonCompat android:id="@+id/contextual_search_allow_button"
diff --git a/chrome/android/java/res/layout/contextual_suggestions_card_modern.xml b/chrome/android/java/res/layout/contextual_suggestions_card_modern.xml index 47b69ad3..0b597bf 100644 --- a/chrome/android/java/res/layout/contextual_suggestions_card_modern.xml +++ b/chrome/android/java/res/layout/contextual_suggestions_card_modern.xml
@@ -39,7 +39,7 @@ android:maxLines="1" android:singleLine="true" android:ellipsize="end" - android:textAppearance="@style/BlackCaption" + android:textAppearance="@style/TextAppearance.BlackCaption" android:textDirection="locale" tools:text="chromium.org"/> @@ -48,7 +48,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:maxLines="1" - android:textAppearance="@style/BlackCaption" + android:textAppearance="@style/TextAppearance.BlackCaption" android:textDirection="locale" tools:text=" - 3 hours ago" />
diff --git a/chrome/android/java/res/layout/contextual_suggestions_toolbar.xml b/chrome/android/java/res/layout/contextual_suggestions_toolbar.xml index dbda9da..aa5b2894 100644 --- a/chrome/android/java/res/layout/contextual_suggestions_toolbar.xml +++ b/chrome/android/java/res/layout/contextual_suggestions_toolbar.xml
@@ -35,7 +35,7 @@ android:layout_weight="1" android:singleLine="true" android:ellipsize="end" - android:textAppearance="@style/BlackTitle1" + android:textAppearance="@style/TextAppearance.BlackTitle1" android:focusable="true" android:focusableInTouchMode="true" />
diff --git a/chrome/android/java/res/layout/custom_tabs_toolbar.xml b/chrome/android/java/res/layout/custom_tabs_toolbar.xml index 9ddaf76..20cf50c 100644 --- a/chrome/android/java/res/layout/custom_tabs_toolbar.xml +++ b/chrome/android/java/res/layout/custom_tabs_toolbar.xml
@@ -46,7 +46,7 @@ android:inputType="none" android:maxLines="1" android:paddingEnd="@dimen/toolbar_edge_padding" - style="@style/BlackTitle1" + style="@style/TextAppearance.BlackTitle1" android:visibility="gone" /> <LinearLayout android:layout_width="wrap_content" @@ -61,7 +61,7 @@ android:ellipsize="end" android:maxLines="1" android:text="@string/location_bar_preview_lite_page_status" - style="@style/BlackCaptionDefault" + style="@style/TextAppearance.BlackCaptionDefault" android:visibility="gone" /> <!-- This separator is in line with text and is used in lieu @@ -84,7 +84,7 @@ android:inputType="none" android:singleLine="true" android:paddingEnd="@dimen/toolbar_edge_padding" - style="@style/BlackCaptionDefault" /> + style="@style/TextAppearance.BlackCaptionDefault" /> </LinearLayout> </view> </FrameLayout>
diff --git a/chrome/android/java/res/layout/data_reduction_main_menu_item.xml b/chrome/android/java/res/layout/data_reduction_main_menu_item.xml index 330172d..60fbb74 100644 --- a/chrome/android/java/res/layout/data_reduction_main_menu_item.xml +++ b/chrome/android/java/res/layout/data_reduction_main_menu_item.xml
@@ -42,13 +42,13 @@ android:id="@+id/menu_item_text" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textAppearance="@style/BlackTitle2" /> + android:textAppearance="@style/TextAppearance.BlackTitle2" /> <TextView android:id="@+id/menu_item_summary" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textAppearance="@style/BlackBody" /> + android:textAppearance="@style/TextAppearance.BlackBody" /> </LinearLayout> </FrameLayout>
diff --git a/chrome/android/java/res/layout/data_reduction_stats_layout.xml b/chrome/android/java/res/layout/data_reduction_stats_layout.xml index 87b6e0c..94d49b8 100644 --- a/chrome/android/java/res/layout/data_reduction_stats_layout.xml +++ b/chrome/android/java/res/layout/data_reduction_stats_layout.xml
@@ -15,7 +15,7 @@ android:layout_gravity="center" android:drawablePadding="3dp" android:text="@string/data_reduction_initial_title" - android:textAppearance="@style/BlackDisabledText1" /> + android:textAppearance="@style/TextAppearance.BlackDisabledText1" /> <LinearLayout android:id="@+id/data_reduction_stats_container" @@ -45,7 +45,7 @@ android:layout_marginTop="3dp" android:paddingStart="3dp" android:text="@string/data_reduction_savings_label" - android:textAppearance="@style/BlueLink2" /> + android:textAppearance="@style/TextAppearance.BlueLink2" /> </LinearLayout> @@ -61,14 +61,14 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" - android:textAppearance="@style/BlackBody" /> + android:textAppearance="@style/TextAppearance.BlackBody" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingStart="3dp" android:text="@string/data_reduction_usage_label" - android:textAppearance="@style/BlackBody" /> + android:textAppearance="@style/TextAppearance.BlackBody" /> </LinearLayout> <include layout="@layout/data_usage_chart" /> @@ -82,13 +82,13 @@ android:id="@+id/data_reduction_start_date" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textAppearance="@style/BlackBody" /> + android:textAppearance="@style/TextAppearance.BlackBody" /> <TextView android:id="@+id/data_reduction_end_date" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textAppearance="@style/BlackBody" /> + android:textAppearance="@style/TextAppearance.BlackBody" /> </FrameLayout>
diff --git a/chrome/android/java/res/layout/data_usage_breakdown.xml b/chrome/android/java/res/layout/data_usage_breakdown.xml index 9622d4f..a57a1b9 100644 --- a/chrome/android/java/res/layout/data_usage_breakdown.xml +++ b/chrome/android/java/res/layout/data_usage_breakdown.xml
@@ -20,7 +20,7 @@ android:paddingTop="26dp" android:singleLine="true" android:text="@string/details_link" - android:textAppearance="@style/BlueLink3" /> + android:textAppearance="@style/TextAppearance.BlueLink3" /> <TableLayout android:id="@+id/data_reduction_proxy_breakdown_table"
diff --git a/chrome/android/java/res/layout/default_search_engine_first_run_fragment.xml b/chrome/android/java/res/layout/default_search_engine_first_run_fragment.xml index 2158027..2e9df33 100644 --- a/chrome/android/java/res/layout/default_search_engine_first_run_fragment.xml +++ b/chrome/android/java/res/layout/default_search_engine_first_run_fragment.xml
@@ -42,7 +42,7 @@ android:paddingBottom="@dimen/signin_chooser_padding" android:background="@color/signin_head_background" android:importantForAccessibility="no" - android:textAppearance="@style/BlackHeadline" + android:textAppearance="@style/TextAppearance.BlackHeadline" android:text="@string/search_engine_dialog_title" /> <View style="@style/HorizontalDivider" /> @@ -62,7 +62,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/search_engine_dialog_footer" - android:textAppearance="@style/BlackBody" + android:textAppearance="@style/TextAppearance.BlackBody" android:padding="@dimen/signin_chooser_padding" /> <!--suppress ButtonStyle -->
diff --git a/chrome/android/java/res/layout/editable_option_editor_footer.xml b/chrome/android/java/res/layout/editable_option_editor_footer.xml index cb29a09..5e891b45 100644 --- a/chrome/android/java/res/layout/editable_option_editor_footer.xml +++ b/chrome/android/java/res/layout/editable_option_editor_footer.xml
@@ -12,7 +12,7 @@ android:layout_height="wrap_content" android:layout_marginTop="8dp" android:layout_marginBottom="16dp" - android:textAppearance="@style/BlackCaption" + android:textAppearance="@style/TextAppearance.BlackCaption" android:text="@string/payments_required_field_message" /> <include layout="@layout/autofill_editor_base_buttons" />
diff --git a/chrome/android/java/res/layout/editable_option_editor_icons.xml b/chrome/android/java/res/layout/editable_option_editor_icons.xml index c3044ed..328b728 100644 --- a/chrome/android/java/res/layout/editable_option_editor_icons.xml +++ b/chrome/android/java/res/layout/editable_option_editor_icons.xml
@@ -17,7 +17,7 @@ android:id="@+id/label" android:layout_width="match_parent" android:layout_height="wrap_content" - android:textAppearance="@style/BlackCaption" /> + android:textAppearance="@style/TextAppearance.BlackCaption" /> <org.chromium.chrome.browser.widget.prefeditor.ExpandableGridView android:id="@+id/icons_container"
diff --git a/chrome/android/java/res/layout/experimental_explore_sites_category_tile_view.xml b/chrome/android/java/res/layout/experimental_explore_sites_category_tile_view.xml index 8ef6b6a..1e7e3931 100644 --- a/chrome/android/java/res/layout/experimental_explore_sites_category_tile_view.xml +++ b/chrome/android/java/res/layout/experimental_explore_sites_category_tile_view.xml
@@ -27,5 +27,5 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" - android:textAppearance="@style/BlackCaptionDefault" /> + android:textAppearance="@style/TextAppearance.BlackCaptionDefault" /> </org.chromium.chrome.browser.explore_sites.ExperimentalExploreSitesCategoryTileView>
diff --git a/chrome/android/java/res/layout/experimental_explore_sites_section.xml b/chrome/android/java/res/layout/experimental_explore_sites_section.xml index caf602a..1198809 100644 --- a/chrome/android/java/res/layout/experimental_explore_sites_section.xml +++ b/chrome/android/java/res/layout/experimental_explore_sites_section.xml
@@ -11,7 +11,7 @@ android:gravity="center" > <TextView - style="@style/BlackCaption" + style="@style/TextAppearance.BlackCaption" android:id="@+id/experimental_explore_sites_title" android:layout_width="match_parent" android:layout_height="wrap_content"
diff --git a/chrome/android/java/res/layout/explore_sites_category_card_view.xml b/chrome/android/java/res/layout/explore_sites_category_card_view.xml index b20f6c0..003df8c 100644 --- a/chrome/android/java/res/layout/explore_sites_category_card_view.xml +++ b/chrome/android/java/res/layout/explore_sites_category_card_view.xml
@@ -18,7 +18,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" - android:textAppearance="@style/BlackTitle2" + android:textAppearance="@style/TextAppearance.BlackTitle2" android:minHeight="@dimen/explore_sites_category_title_height" tools:text="Category" />
diff --git a/chrome/android/java/res/layout/explore_sites_loading_error_view.xml b/chrome/android/java/res/layout/explore_sites_loading_error_view.xml index 240af0c..c369676 100644 --- a/chrome/android/java/res/layout/explore_sites_loading_error_view.xml +++ b/chrome/android/java/res/layout/explore_sites_loading_error_view.xml
@@ -25,14 +25,14 @@ android:text="@string/explore_sites_loading_error" android:layout_marginHorizontal="@dimen/explore_sites_page_padding" android:layout_marginBottom="@dimen/explore_sites_page_padding" - android:textAppearance="@style/BlackHeadline" /> + android:textAppearance="@style/TextAppearance.BlackHeadline" /> <org.chromium.ui.widget.TextViewWithLeading android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="start" android:layout_marginHorizontal="@dimen/explore_sites_page_padding" android:text="@string/explore_sites_loading_error_next_steps_tag" - android:textAppearance="@style/BlackCaptionDefault" + android:textAppearance="@style/TextAppearance.BlackCaptionDefault" app:leading="@dimen/text_size_small_leading" /> <org.chromium.ui.widget.TextViewWithLeading android:id="@+id/error_view_next_steps" @@ -41,6 +41,6 @@ android:gravity="start" android:layout_marginHorizontal="@dimen/explore_sites_page_padding" android:paddingStart="@dimen/explore_sites_page_padding" - android:textAppearance="@style/BlackCaptionDefault" + android:textAppearance="@style/TextAppearance.BlackCaptionDefault" app:leading="@dimen/text_size_small_leading" /> </LinearLayout>
diff --git a/chrome/android/java/res/layout/find_in_page.xml b/chrome/android/java/res/layout/find_in_page.xml index a5fca761..2cc2a159 100644 --- a/chrome/android/java/res/layout/find_in_page.xml +++ b/chrome/android/java/res/layout/find_in_page.xml
@@ -23,7 +23,7 @@ android:hint="@string/hint_find_in_page" android:imeOptions="actionSearch|flagNoExtractUi" android:singleLine="true" - android:textAppearance="@style/BlackTitle1" /> + android:textAppearance="@style/TextAppearance.BlackTitle1" /> <TextView android:id="@+id/find_status" android:layout_width="wrap_content" @@ -32,7 +32,7 @@ android:layout_marginEnd="16dp" android:background="@null" android:singleLine="true" - android:textAppearance="@style/BlackDisabledText1" /> + android:textAppearance="@style/TextAppearance.BlackDisabledText1" /> <View android:id="@+id/find_separator" android:layout_width="1dp"
diff --git a/chrome/android/java/res/layout/fre_data_reduction_proxy.xml b/chrome/android/java/res/layout/fre_data_reduction_proxy.xml index 082857c..a8a61d57 100644 --- a/chrome/android/java/res/layout/fre_data_reduction_proxy.xml +++ b/chrome/android/java/res/layout/fre_data_reduction_proxy.xml
@@ -62,7 +62,7 @@ android:gravity="start" android:lineSpacingMultiplier="1.4" android:text="@string/data_reduction_promo_summary" - android:textAppearance="@style/BlackBodyDefault" /> + android:textAppearance="@style/TextAppearance.BlackBodyDefault" /> <android.support.v7.widget.SwitchCompat android:id="@+id/enable_data_saver_switch" @@ -71,7 +71,7 @@ android:lineSpacingMultiplier="1.4" android:showText="false" android:text="@string/data_reduction_enabled_switch" - style="@style/BlackTitle2" /> + style="@style/TextAppearance.BlackTitle2" /> </LinearLayout> </LinearLayout>
diff --git a/chrome/android/java/res/layout/fre_tosanduma.xml b/chrome/android/java/res/layout/fre_tosanduma.xml index d6c30f0..2ef4e39 100644 --- a/chrome/android/java/res/layout/fre_tosanduma.xml +++ b/chrome/android/java/res/layout/fre_tosanduma.xml
@@ -62,7 +62,7 @@ android:layout_marginBottom="@dimen/fre_vertical_spacing" android:gravity="center" android:lineSpacingMultiplier="1.4" - android:textAppearance="@style/BlackBodyDefault" /> + android:textAppearance="@style/TextAppearance.BlackBodyDefault" /> <CheckBox android:id="@+id/send_report_checkbox" @@ -70,7 +70,7 @@ android:layout_height="wrap_content" android:lineSpacingMultiplier="1.4" android:text="@string/fre_send_report_check" - android:textAppearance="@style/BlackBodyDefault" /> + android:textAppearance="@style/TextAppearance.BlackBodyDefault" /> </LinearLayout> </LinearLayout> </LinearLayout>
diff --git a/chrome/android/java/res/layout/history_privacy_disclaimer_header.xml b/chrome/android/java/res/layout/history_privacy_disclaimer_header.xml index a28df8a..945e1cab 100644 --- a/chrome/android/java/res/layout/history_privacy_disclaimer_header.xml +++ b/chrome/android/java/res/layout/history_privacy_disclaimer_header.xml
@@ -16,7 +16,7 @@ android:layout_marginTop="6dp" android:layout_marginStart="@dimen/list_item_default_margin" android:layout_marginEnd="@dimen/list_item_default_margin" - android:textAppearance="@style/BlackBody" + android:textAppearance="@style/TextAppearance.BlackBody" android:lineSpacingExtra="6sp"/> <LinearLayout
diff --git a/chrome/android/java/res/layout/incognito_disclosure_dialog_content.xml b/chrome/android/java/res/layout/incognito_disclosure_dialog_content.xml index 0f4fc38..7f4644d 100644 --- a/chrome/android/java/res/layout/incognito_disclosure_dialog_content.xml +++ b/chrome/android/java/res/layout/incognito_disclosure_dialog_content.xml
@@ -9,7 +9,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/incognito_disclosure_text" - android:textAppearance="@style/BlackBodyDefault"/> + android:textAppearance="@style/TextAppearance.BlackBodyDefault"/> <CheckBox android:id="@+id/incognito_disclosure_close_incognito_checkbox" android:layout_width="wrap_content" @@ -17,5 +17,5 @@ android:layout_marginTop="15dp" android:layout_marginStart="-5dp" android:text="@string/incognito_disclosure_checkbox_text" - android:textAppearance="@style/BlackBodyDefault"/> + android:textAppearance="@style/TextAppearance.BlackBodyDefault"/> </LinearLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/infobar_control_description.xml b/chrome/android/java/res/layout/infobar_control_description.xml index 90e9edc..0e98ff33 100644 --- a/chrome/android/java/res/layout/infobar_control_description.xml +++ b/chrome/android/java/res/layout/infobar_control_description.xml
@@ -7,5 +7,5 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" - android:textAppearance="@style/BlackBody" + android:textAppearance="@style/TextAppearance.BlackBody" android:textColorLink="@color/infobar_accent_blue" /> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/infobar_control_icon_with_description.xml b/chrome/android/java/res/layout/infobar_control_icon_with_description.xml index 016e8e7..f32fc912 100644 --- a/chrome/android/java/res/layout/infobar_control_icon_with_description.xml +++ b/chrome/android/java/res/layout/infobar_control_icon_with_description.xml
@@ -28,13 +28,13 @@ android:id="@+id/control_message" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textAppearance="@style/BlackTitle1" /> + android:textAppearance="@style/TextAppearance.BlackTitle1" /> <TextView android:id="@+id/control_secondary_message" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textAppearance="@style/BlackHint1" /> + android:textAppearance="@style/TextAppearance.BlackHint1" /> </org.chromium.chrome.browser.widget.DualControlLayout>
diff --git a/chrome/android/java/res/layout/infobar_control_spinner_view.xml b/chrome/android/java/res/layout/infobar_control_spinner_view.xml index 6c7c772b..f6c834c9c 100644 --- a/chrome/android/java/res/layout/infobar_control_spinner_view.xml +++ b/chrome/android/java/res/layout/infobar_control_spinner_view.xml
@@ -14,12 +14,12 @@ <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textAppearance="@style/BlackHint1" /> + android:textAppearance="@style/TextAppearance.BlackHint1" /> <!-- Shows the actively selected item. --> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textAppearance="@style/BlackTitle1" /> + android:textAppearance="@style/TextAppearance.BlackTitle1" /> </org.chromium.chrome.browser.widget.DualControlLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/infobar_control_url_ellipsizer.xml b/chrome/android/java/res/layout/infobar_control_url_ellipsizer.xml index d111f7f..650411f 100644 --- a/chrome/android/java/res/layout/infobar_control_url_ellipsizer.xml +++ b/chrome/android/java/res/layout/infobar_control_url_ellipsizer.xml
@@ -14,7 +14,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0" - android:textAppearance="@style/BlueLink2" + android:textAppearance="@style/TextAppearance.BlueLink2" android:clickable="false" tools:text="https://" /> @@ -23,7 +23,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" - android:textAppearance="@style/BlueLink2" + android:textAppearance="@style/TextAppearance.BlueLink2" android:clickable="false" android:ellipsize="start" android:singleLine="true"
diff --git a/chrome/android/java/res/layout/item_chooser_dialog.xml b/chrome/android/java/res/layout/item_chooser_dialog.xml index 0a6d21e..080b40a 100644 --- a/chrome/android/java/res/layout/item_chooser_dialog.xml +++ b/chrome/android/java/res/layout/item_chooser_dialog.xml
@@ -19,7 +19,7 @@ android:paddingBottom="8dp" android:paddingStart="16dp" android:paddingEnd="16dp" - android:textAppearance="@style/BlackHint1" /> + android:textAppearance="@style/TextAppearance.BlackHint1" /> <!-- The "no item found" message. --> <org.chromium.ui.widget.TextViewWithClickableSpans @@ -29,7 +29,7 @@ android:layout_marginTop="8dp" android:layout_marginStart="16dp" android:layout_marginEnd="16dp" - android:textAppearance="@style/BlackHint1" + android:textAppearance="@style/TextAppearance.BlackHint1" android:visibility="gone" /> <!-- A layout containing a spinning progress bar that gets replaced with a @@ -65,7 +65,7 @@ android:layout_marginTop="12dp" android:paddingStart="16dp" android:paddingEnd="16dp" - android:textAppearance="@style/BlackBody" /> + android:textAppearance="@style/TextAppearance.BlackBody" /> <!-- Button row. --> <org.chromium.ui.widget.ButtonCompat
diff --git a/chrome/android/java/res/layout/keyboard_accessory_chip.xml b/chrome/android/java/res/layout/keyboard_accessory_chip.xml index ca663a5c..08d77ca 100644 --- a/chrome/android/java/res/layout/keyboard_accessory_chip.xml +++ b/chrome/android/java/res/layout/keyboard_accessory_chip.xml
@@ -19,5 +19,5 @@ android:layout_marginBottom="@dimen/keyboard_accessory_half_padding" android:layout_marginTop="@dimen/keyboard_accessory_half_padding" android:elevation="2dp" - android:textAppearance="@style/BlackTitle2" + android:textAppearance="@style/TextAppearance.BlackTitle2" android:background="@drawable/autofill_chip_inset"/>
diff --git a/chrome/android/java/res/layout/keyboard_accessory_sheet_tab_legacy_password_info.xml b/chrome/android/java/res/layout/keyboard_accessory_sheet_tab_legacy_password_info.xml index 6faf213..be89b6a2 100644 --- a/chrome/android/java/res/layout/keyboard_accessory_sheet_tab_legacy_password_info.xml +++ b/chrome/android/java/res/layout/keyboard_accessory_sheet_tab_legacy_password_info.xml
@@ -18,7 +18,7 @@ android:minHeight="@dimen/keyboard_accessory_suggestion_height" android:layout_height="wrap_content" android:layout_width="match_parent" - android:textAppearance="@style/BlackTitle1"/> + android:textAppearance="@style/TextAppearance.BlackTitle1"/> <TextView android:id="@+id/password_text" @@ -27,6 +27,6 @@ android:minHeight="@dimen/keyboard_accessory_suggestion_height" android:layout_height="wrap_content" android:layout_width="match_parent" - android:textAppearance="@style/BlackTitle1"/> + android:textAppearance="@style/TextAppearance.BlackTitle1"/> </LinearLayout>
diff --git a/chrome/android/java/res/layout/keyboard_accessory_suggestion.xml b/chrome/android/java/res/layout/keyboard_accessory_suggestion.xml index 901ced2..480b7060 100644 --- a/chrome/android/java/res/layout/keyboard_accessory_suggestion.xml +++ b/chrome/android/java/res/layout/keyboard_accessory_suggestion.xml
@@ -15,4 +15,4 @@ android:paddingTop="0dp" android:layout_marginBottom="@dimen/keyboard_accessory_half_padding" android:layout_marginTop="@dimen/keyboard_accessory_half_padding" - android:textAppearance="@style/BlackTitle2"/> + android:textAppearance="@style/TextAppearance.BlackTitle2"/>
diff --git a/chrome/android/java/res/layout/language_ask_prompt_row.xml b/chrome/android/java/res/layout/language_ask_prompt_row.xml index 9f24b37..8d60853 100644 --- a/chrome/android/java/res/layout/language_ask_prompt_row.xml +++ b/chrome/android/java/res/layout/language_ask_prompt_row.xml
@@ -24,7 +24,7 @@ android:id="@+id/ui_language_representation" android:layout_width="match_parent" android:layout_height="wrap_content" - android:textAppearance="@style/BlackTitle1" + android:textAppearance="@style/TextAppearance.BlackTitle1" android:ellipsize="end" android:singleLine="true" android:layout_toEndOf="@+id/language_ask_checkbox" /> @@ -33,7 +33,7 @@ android:id="@+id/native_language_representation" android:layout_width="match_parent" android:layout_height="wrap_content" - android:textAppearance="@style/BlackBody" + android:textAppearance="@style/TextAppearance.BlackBody" android:ellipsize="end" android:singleLine="true" android:layout_alignStart="@+id/ui_language_representation"
diff --git a/chrome/android/java/res/layout/lightweight_fre_tos.xml b/chrome/android/java/res/layout/lightweight_fre_tos.xml index 70934c4..82ff098 100644 --- a/chrome/android/java/res/layout/lightweight_fre_tos.xml +++ b/chrome/android/java/res/layout/lightweight_fre_tos.xml
@@ -32,7 +32,7 @@ android:lineSpacingMultiplier="1.64" android:paddingEnd="24dp" android:paddingStart="24dp" - android:textAppearance="@style/BlackBodyDefault" /> + android:textAppearance="@style/TextAppearance.BlackBodyDefault" /> <org.chromium.chrome.browser.widget.DualControlLayout android:id="@+id/lightweight_fre_buttons"
diff --git a/chrome/android/java/res/layout/modal_dialog_title.xml b/chrome/android/java/res/layout/modal_dialog_title.xml index 6a52c8c..51202bd4 100644 --- a/chrome/android/java/res/layout/modal_dialog_title.xml +++ b/chrome/android/java/res/layout/modal_dialog_title.xml
@@ -20,5 +20,5 @@ android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="match_parent" - android:textAppearance="@style/BlackHeadline" /> + android:textAppearance="@style/TextAppearance.BlackHeadline" /> </LinearLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/modal_dialog_view.xml b/chrome/android/java/res/layout/modal_dialog_view.xml index 35bb1af..4f990e9e 100644 --- a/chrome/android/java/res/layout/modal_dialog_view.xml +++ b/chrome/android/java/res/layout/modal_dialog_view.xml
@@ -33,7 +33,7 @@ <org.chromium.ui.widget.TextViewWithLeading android:id="@+id/message" - android:textAppearance="@style/BlackBody" + android:textAppearance="@style/TextAppearance.BlackBody" app:leading="20sp" style="@style/AlertDialogContent" />
diff --git a/chrome/android/java/res/layout/modern_list_item_view.xml b/chrome/android/java/res/layout/modern_list_item_view.xml index a7295ce..c7532eaf 100644 --- a/chrome/android/java/res/layout/modern_list_item_view.xml +++ b/chrome/android/java/res/layout/modern_list_item_view.xml
@@ -23,7 +23,7 @@ android:layout_height="wrap_content" android:maxLines="1" android:ellipsize="end" - android:textAppearance="@style/BlackTitle1" /> + android:textAppearance="@style/TextAppearance.BlackTitle1" /> <TextView android:id="@+id/description" @@ -31,7 +31,7 @@ android:layout_height="wrap_content" android:maxLines="1" android:ellipsize="end" - android:textAppearance="@style/BlackBody" /> + android:textAppearance="@style/TextAppearance.BlackBody" /> </LinearLayout> </merge> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/navigation_popup_item.xml b/chrome/android/java/res/layout/navigation_popup_item.xml index 83bd45d..eab0d34 100644 --- a/chrome/android/java/res/layout/navigation_popup_item.xml +++ b/chrome/android/java/res/layout/navigation_popup_item.xml
@@ -37,6 +37,6 @@ android:layout_height="wrap_content" android:layout_marginStart="@dimen/navigation_popup_default_padding" android:minHeight="@dimen/navigation_popup_item_height" - android:textAppearance="@style/BlackTitle1" + android:textAppearance="@style/TextAppearance.BlackTitle1" android:singleLine="true" /> </LinearLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/new_tab_page_footer.xml b/chrome/android/java/res/layout/new_tab_page_footer.xml index 9bd0dd6f..2bc13e5 100644 --- a/chrome/android/java/res/layout/new_tab_page_footer.xml +++ b/chrome/android/java/res/layout/new_tab_page_footer.xml
@@ -23,5 +23,5 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" - android:textAppearance="@style/BlackCaption" /> + android:textAppearance="@style/TextAppearance.BlackCaption" /> </FrameLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/new_tab_page_incognito.xml b/chrome/android/java/res/layout/new_tab_page_incognito.xml index 987598ee0..a5428bb 100644 --- a/chrome/android/java/res/layout/new_tab_page_incognito.xml +++ b/chrome/android/java/res/layout/new_tab_page_incognito.xml
@@ -46,7 +46,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/new_tab_incognito_header" - android:textAppearance="@style/WhiteHeadline" /> + android:textAppearance="@style/TextAppearance.WhiteHeadline" /> <TextView android:id="@+id/new_tab_incognito_message"
diff --git a/chrome/android/java/res/layout/new_tab_page_incognito_md.xml b/chrome/android/java/res/layout/new_tab_page_incognito_md.xml index ff3cc0de..81016e92 100644 --- a/chrome/android/java/res/layout/new_tab_page_incognito_md.xml +++ b/chrome/android/java/res/layout/new_tab_page_incognito_md.xml
@@ -42,13 +42,13 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/new_tab_otr_title" - android:textAppearance="@style/WhiteHeadline" /> + android:textAppearance="@style/TextAppearance.WhiteHeadline" /> <org.chromium.ui.widget.TextViewWithClickableSpans android:id="@+id/new_tab_incognito_subtitle" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textAppearance="@style/WhiteBodyIncognito" + android:textAppearance="@style/TextAppearance.WhiteBodyIncognito" android:lineSpacingExtra="@dimen/md_incognito_ntp_line_spacing" /> <LinearLayout @@ -62,14 +62,14 @@ android:id="@+id/new_tab_incognito_features" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textAppearance="@style/WhiteBodyIncognito" + android:textAppearance="@style/TextAppearance.WhiteBodyIncognito" android:lineSpacingExtra="@dimen/md_incognito_ntp_line_spacing" /> <TextView android:id="@+id/new_tab_incognito_warning" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textAppearance="@style/WhiteBodyIncognito" + android:textAppearance="@style/TextAppearance.WhiteBodyIncognito" android:lineSpacingExtra="@dimen/md_incognito_ntp_line_spacing" /> </LinearLayout>
diff --git a/chrome/android/java/res/layout/new_tab_page_snippets_expandable_header.xml b/chrome/android/java/res/layout/new_tab_page_snippets_expandable_header.xml index f43c7ba..7b8b754 100644 --- a/chrome/android/java/res/layout/new_tab_page_snippets_expandable_header.xml +++ b/chrome/android/java/res/layout/new_tab_page_snippets_expandable_header.xml
@@ -19,12 +19,12 @@ android:layout_height="wrap_content" android:layout_weight="1" android:textAlignment="viewStart" - android:textAppearance="@style/BlackCaption" /> + android:textAppearance="@style/TextAppearance.BlackCaption" /> <TextView android:id="@+id/header_status" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textAppearance="@style/BlueLink3" /> + android:textAppearance="@style/TextAppearance.BlueLink3" /> </org.chromium.chrome.browser.ntp.snippets.SectionHeaderView>
diff --git a/chrome/android/java/res/layout/number_roll_view.xml b/chrome/android/java/res/layout/number_roll_view.xml index 8542a43..018c5a1 100644 --- a/chrome/android/java/res/layout/number_roll_view.xml +++ b/chrome/android/java/res/layout/number_roll_view.xml
@@ -18,7 +18,7 @@ android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:singleLine="true" - android:textAppearance="@style/WhiteHeadline" /> + android:textAppearance="@style/TextAppearance.WhiteHeadline" /> <TextView android:id="@+id/down" @@ -26,5 +26,5 @@ android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:singleLine="true" - android:textAppearance="@style/WhiteHeadline" /> + android:textAppearance="@style/TextAppearance.WhiteHeadline" /> </org.chromium.chrome.browser.widget.NumberRollView>
diff --git a/chrome/android/java/res/layout/other_forms_of_history_dialog.xml b/chrome/android/java/res/layout/other_forms_of_history_dialog.xml index 50bcb7a7..4f5c62f4 100644 --- a/chrome/android/java/res/layout/other_forms_of_history_dialog.xml +++ b/chrome/android/java/res/layout/other_forms_of_history_dialog.xml
@@ -15,7 +15,7 @@ android:text="@string/clear_browsing_data_history_dialog_data_text" android:layout_width="match_parent" android:layout_height="wrap_content" - android:textAppearance="@style/BlackBody" + android:textAppearance="@style/TextAppearance.BlackBody" android:lineSpacingExtra="6sp" android:paddingTop="10dp" android:paddingBottom="20dp" />
diff --git a/chrome/android/java/res/layout/page_info.xml b/chrome/android/java/res/layout/page_info.xml index bb78e48..665cbe2d 100644 --- a/chrome/android/java/res/layout/page_info.xml +++ b/chrome/android/java/res/layout/page_info.xml
@@ -29,7 +29,7 @@ android:lineSpacingExtra="6dp" android:paddingTop="16dp" android:textAlignment="viewStart" - android:textAppearance="@style/BlackTitle1" /> + android:textAppearance="@style/TextAppearance.BlackTitle1" /> <TextView android:id="@+id/page_info_connection_summary" @@ -37,7 +37,7 @@ android:layout_height="wrap_content" android:lineSpacingExtra="3dp" android:paddingTop="16dp" - android:textAppearance="@style/BlackTitle1" + android:textAppearance="@style/TextAppearance.BlackTitle1" android:visibility="gone" /> <TextView @@ -46,7 +46,7 @@ android:layout_height="wrap_content" android:lineSpacingExtra="3dp" android:paddingTop="8dp" - android:textAppearance="@style/BlackBodyDefault" + android:textAppearance="@style/TextAppearance.BlackBodyDefault" android:visibility="gone" /> <View @@ -60,7 +60,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="14dp" - android:textAppearance="@style/BlackTitle1" + android:textAppearance="@style/TextAppearance.BlackTitle1" android:text="@string/page_info_preview_message" android:visibility="gone" /> @@ -68,7 +68,7 @@ android:id="@+id/page_info_stale_preview_timestamp" android:layout_width="match_parent" android:layout_height="wrap_content" - android:textAppearance="@style/BlackCaption" + android:textAppearance="@style/TextAppearance.BlackCaption" android:visibility="gone" /> <TextView @@ -76,7 +76,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="12dp" - android:textAppearance="@style/BlackTitle1" + android:textAppearance="@style/TextAppearance.BlackTitle1" android:visibility="gone" /> </LinearLayout>
diff --git a/chrome/android/java/res/layout/page_info_permission_row.xml b/chrome/android/java/res/layout/page_info_permission_row.xml index 66ed493..ae18519 100644 --- a/chrome/android/java/res/layout/page_info_permission_row.xml +++ b/chrome/android/java/res/layout/page_info_permission_row.xml
@@ -24,7 +24,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toEndOf="@id/page_info_permission_icon" - android:textAppearance="@style/BlackBodyDefault" /> + android:textAppearance="@style/TextAppearance.BlackBodyDefault" /> <org.chromium.ui.widget.TextViewWithLeading android:id="@+id/page_info_permission_unavailable_message" @@ -32,9 +32,9 @@ android:layout_height="wrap_content" android:layout_below="@id/page_info_permission_status" android:layout_toEndOf="@id/page_info_permission_icon" - android:textAppearance="@style/BlueLink2" + android:textAppearance="@style/TextAppearance.BlueLink2" android:visibility="gone" - app:leading="20dp" /> + app:leading="@dimen/text_size_medium_leading" /> <org.chromium.ui.widget.TextViewWithLeading android:id="@+id/page_info_permission_subtitle" @@ -42,8 +42,7 @@ android:layout_height="wrap_content" android:layout_below="@id/page_info_permission_status" android:layout_toEndOf="@id/page_info_permission_icon" - android:textSize="14sp" - android:textColor="@color/secondary_text_default_material_light" + android:textAppearance="@style/TextAppearance.PageInfoPermissionSubtitle" android:visibility="gone" - app:leading="20dp" /> + app:leading="@dimen/text_size_medium_leading" /> </RelativeLayout>
diff --git a/chrome/android/java/res/layout/password_accessory_sheet_label.xml b/chrome/android/java/res/layout/password_accessory_sheet_label.xml index bd6f9c51..d6dd326 100644 --- a/chrome/android/java/res/layout/password_accessory_sheet_label.xml +++ b/chrome/android/java/res/layout/password_accessory_sheet_label.xml
@@ -23,7 +23,7 @@ android:paddingTop="@dimen/keyboard_accessory_suggestion_offset" android:paddingBottom="@dimen/keyboard_accessory_suggestion_offset" android:gravity="center_vertical|start" - android:textAppearance="@style/BlackHint1" + android:textAppearance="@style/TextAppearance.BlackHint1" android:minHeight="@dimen/keyboard_accessory_height" app:leading="@dimen/text_size_large_leading" android:layout_height="wrap_content"
diff --git a/chrome/android/java/res/layout/password_accessory_sheet_legacy_option.xml b/chrome/android/java/res/layout/password_accessory_sheet_legacy_option.xml index 7288a8c..84c6ed6 100644 --- a/chrome/android/java/res/layout/password_accessory_sheet_legacy_option.xml +++ b/chrome/android/java/res/layout/password_accessory_sheet_legacy_option.xml
@@ -25,7 +25,7 @@ android:fillViewport="true" android:minHeight="@dimen/keyboard_accessory_suggestion_height" android:gravity="center_vertical|start" - android:textAppearance="@style/BlackTitle1" + android:textAppearance="@style/TextAppearance.BlackTitle1" android:layout_height="wrap_content" android:layout_width="match_parent" android:background="?android:attr/selectableItemBackground"/>
diff --git a/chrome/android/java/res/layout/password_generation_dialog.xml b/chrome/android/java/res/layout/password_generation_dialog.xml index d97af1c..3eed312e 100644 --- a/chrome/android/java/res/layout/password_generation_dialog.xml +++ b/chrome/android/java/res/layout/password_generation_dialog.xml
@@ -18,7 +18,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/generated_password" - android:textAppearance="@style/BlackTitle1" + android:textAppearance="@style/TextAppearance.BlackTitle1" app:leading="20sp" android:layout_marginBottom="24dp"/> @@ -26,6 +26,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/generation_save_explanation" - android:textAppearance="@style/BlackBody" + android:textAppearance="@style/TextAppearance.BlackBody" app:leading="20sp"/> </org.chromium.chrome.browser.password_manager.PasswordGenerationDialogCustomView> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/payment_request_editor_dropdown.xml b/chrome/android/java/res/layout/payment_request_editor_dropdown.xml index 7d2fc01f..e995af0 100644 --- a/chrome/android/java/res/layout/payment_request_editor_dropdown.xml +++ b/chrome/android/java/res/layout/payment_request_editor_dropdown.xml
@@ -17,7 +17,7 @@ android:id="@+id/spinner_label" android:layout_width="match_parent" android:layout_height="wrap_content" - android:textAppearance="@style/BlackCaption" /> + android:textAppearance="@style/TextAppearance.BlackCaption" /> <android.support.v7.widget.AppCompatSpinner android:id="@+id/spinner"
diff --git a/chrome/android/java/res/layout/payment_request_editor_label.xml b/chrome/android/java/res/layout/payment_request_editor_label.xml index 2d81a75d..dd40b93 100644 --- a/chrome/android/java/res/layout/payment_request_editor_label.xml +++ b/chrome/android/java/res/layout/payment_request_editor_label.xml
@@ -45,6 +45,6 @@ android:layout_below="@id/mid_label" android:layout_toStartOf="@id/icon" android:layout_alignParentStart="true" - android:textAppearance="@style/BlackCaption" /> + android:textAppearance="@style/TextAppearance.BlackCaption" /> </RelativeLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/payment_request_header.xml b/chrome/android/java/res/layout/payment_request_header.xml index 0214724..ab3ce57 100644 --- a/chrome/android/java/res/layout/payment_request_header.xml +++ b/chrome/android/java/res/layout/payment_request_header.xml
@@ -57,7 +57,7 @@ android:ellipsize="start" android:maxLines="1" android:singleLine="true" - android:textAppearance="@style/BlackBody" /> + android:textAppearance="@style/TextAppearance.BlackBody" /> </LinearLayout> <ImageView
diff --git a/chrome/android/java/res/layout/payment_request_spinny.xml b/chrome/android/java/res/layout/payment_request_spinny.xml index ddf8b6c..87a1507 100644 --- a/chrome/android/java/res/layout/payment_request_spinny.xml +++ b/chrome/android/java/res/layout/payment_request_spinny.xml
@@ -40,6 +40,6 @@ android:layout_marginEnd="@dimen/editor_dialog_section_large_spacing" android:layout_marginBottom="@dimen/editor_dialog_section_large_spacing" android:gravity="center_horizontal" - android:textAppearance="@style/BlackHint1" /> + android:textAppearance="@style/TextAppearance.BlackHint1" /> </FrameLayout>
diff --git a/chrome/android/java/res/layout/personalized_signin_promo_view_body.xml b/chrome/android/java/res/layout/personalized_signin_promo_view_body.xml index 2969c66..fc7d12b 100644 --- a/chrome/android/java/res/layout/personalized_signin_promo_view_body.xml +++ b/chrome/android/java/res/layout/personalized_signin_promo_view_body.xml
@@ -16,7 +16,7 @@ android:layout_marginStart="24dp" android:gravity="center" android:lineSpacingMultiplier="1.25" - android:textAppearance="@style/BlackBodyDefault" + android:textAppearance="@style/TextAppearance.BlackBodyDefault" tools:text="@string/signin_promo_description_settings"/> <org.chromium.ui.widget.ButtonCompat
diff --git a/chrome/android/java/res/layout/photo_picker_bitmap_view.xml b/chrome/android/java/res/layout/photo_picker_bitmap_view.xml index 737453a92..66832655d 100644 --- a/chrome/android/java/res/layout/photo_picker_bitmap_view.xml +++ b/chrome/android/java/res/layout/photo_picker_bitmap_view.xml
@@ -79,8 +79,6 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/photo_picker_label_gap" android:gravity="center" - android:textColor="@color/photo_picker_special_tile_color" - android:textSize="14sp" - style="@style/RobotoMediumStyle" /> + android:textAppearance="@style/TextAppearance.PhotoPickerSpecialTile" /> </LinearLayout> </view>
diff --git a/chrome/android/java/res/layout/powered_by_chrome_footer.xml b/chrome/android/java/res/layout/powered_by_chrome_footer.xml index 38963d05..88a7513 100644 --- a/chrome/android/java/res/layout/powered_by_chrome_footer.xml +++ b/chrome/android/java/res/layout/powered_by_chrome_footer.xml
@@ -17,7 +17,7 @@ android:gravity="start|center_vertical" android:text="@string/powered_by_chrome_message" android:maxLines="1" - style="@style/BlackCaption" /> + style="@style/TextAppearance.BlackCaption" /> <View android:layout_width="match_parent" android:layout_height="1dp"
diff --git a/chrome/android/java/res/layout/promo_dialog_layout.xml b/chrome/android/java/res/layout/promo_dialog_layout.xml index e523750..dfe814d 100644 --- a/chrome/android/java/res/layout/promo_dialog_layout.xml +++ b/chrome/android/java/res/layout/promo_dialog_layout.xml
@@ -65,7 +65,7 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/dialog_header_margin" android:layout_marginBottom="@dimen/dialog_header_margin" - android:textAppearance="@style/BlackHeadline" /> + android:textAppearance="@style/TextAppearance.BlackHeadline" /> <TextView android:id="@+id/subheader"
diff --git a/chrome/android/java/res/layout/radio_button_with_description.xml b/chrome/android/java/res/layout/radio_button_with_description.xml index 262a256..d4b6f0d 100644 --- a/chrome/android/java/res/layout/radio_button_with_description.xml +++ b/chrome/android/java/res/layout/radio_button_with_description.xml
@@ -19,7 +19,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toEndOf="@id/radio_button" - android:textAppearance="@style/BlackTitle1" /> + android:textAppearance="@style/TextAppearance.BlackTitle1" /> <!-- This TextView is hidden if it has no text, so the initial visibility should be "gone". --> <TextView @@ -28,6 +28,6 @@ android:layout_height="wrap_content" android:layout_alignStart="@id/title" android:layout_below="@id/title" - android:textAppearance="@style/BlackHint2" + android:textAppearance="@style/TextAppearance.BlackHint2" android:visibility="gone"/> </merge>
diff --git a/chrome/android/java/res/layout/recent_tabs_group_item.xml b/chrome/android/java/res/layout/recent_tabs_group_item.xml index 7352b229..75c0c35 100644 --- a/chrome/android/java/res/layout/recent_tabs_group_item.xml +++ b/chrome/android/java/res/layout/recent_tabs_group_item.xml
@@ -27,7 +27,7 @@ android:minHeight="24dp" android:singleLine="true" android:textAlignment="viewStart" - android:textAppearance="@style/BlackTitle1" /> + android:textAppearance="@style/TextAppearance.BlackTitle1" /> <TextView android:id="@+id/time_label" @@ -35,7 +35,7 @@ android:layout_width="match_parent" android:ellipsize="end" android:textAlignment="viewStart" - android:textAppearance="@style/BlackHint2" /> + android:textAppearance="@style/TextAppearance.BlackHint2" /> </LinearLayout> <ImageView
diff --git a/chrome/android/java/res/layout/recent_tabs_list_item.xml b/chrome/android/java/res/layout/recent_tabs_list_item.xml index def49c9..9e40f9ea 100644 --- a/chrome/android/java/res/layout/recent_tabs_list_item.xml +++ b/chrome/android/java/res/layout/recent_tabs_list_item.xml
@@ -32,7 +32,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:ellipsize="end" - android:textAppearance="@style/BlackTitle1" + android:textAppearance="@style/TextAppearance.BlackTitle1" android:singleLine="true"/> <TextView @@ -41,7 +41,7 @@ android:id="@+id/domain_row" android:ellipsize="end" android:singleLine="true" - android:textAppearance="@style/BlackBody" + android:textAppearance="@style/TextAppearance.BlackBody" android:visibility="gone" /> </LinearLayout>
diff --git a/chrome/android/java/res/layout/sad_tab.xml b/chrome/android/java/res/layout/sad_tab.xml index 9fa91538..68ceec27 100644 --- a/chrome/android/java/res/layout/sad_tab.xml +++ b/chrome/android/java/res/layout/sad_tab.xml
@@ -41,7 +41,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingBottom="16dp" - android:textAppearance="@style/BlackHeadline" + android:textAppearance="@style/TextAppearance.BlackHeadline" android:lineSpacingMultiplier="1.4" android:layout_gravity="start" />
diff --git a/chrome/android/java/res/layout/search_engine.xml b/chrome/android/java/res/layout/search_engine.xml index bdc78db..a43c347 100644 --- a/chrome/android/java/res/layout/search_engine.xml +++ b/chrome/android/java/res/layout/search_engine.xml
@@ -27,12 +27,12 @@ android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textAppearance="@style/BlackTitle1" /> + android:textAppearance="@style/TextAppearance.BlackTitle1" /> <TextView android:id="@+id/url" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textAppearance="@style/BlackBody" /> + android:textAppearance="@style/TextAppearance.BlackBody" /> <TextView android:id="@+id/location_permission" android:layout_width="wrap_content"
diff --git a/chrome/android/java/res/layout/search_engine_recent_title.xml b/chrome/android/java/res/layout/search_engine_recent_title.xml index 127329e..cdbdb552 100644 --- a/chrome/android/java/res/layout/search_engine_recent_title.xml +++ b/chrome/android/java/res/layout/search_engine_recent_title.xml
@@ -7,8 +7,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/search_engine_recently_visited" - android:textColor="@color/default_text_color_link" - style="@style/RobotoMediumStyle" + android:textAppearance="@style/TextAppearance.SearchEngineRecentTitle" android:gravity="center_vertical" android:paddingBottom="16dp" android:paddingTop="16dp"
diff --git a/chrome/android/java/res/layout/search_toolbar.xml b/chrome/android/java/res/layout/search_toolbar.xml index fdd6629..e15bf44 100644 --- a/chrome/android/java/res/layout/search_toolbar.xml +++ b/chrome/android/java/res/layout/search_toolbar.xml
@@ -24,7 +24,7 @@ android:imeOptions="flagNoExtractUi|actionSearch" android:inputType="text" android:singleLine="true" - android:textAppearance="@style/BlackTitle1" + android:textAppearance="@style/TextAppearance.BlackTitle1" android:textColorHint="@color/search_box_hint"/> <org.chromium.ui.widget.ChromeImageButton
diff --git a/chrome/android/java/res/layout/selectable_list_layout.xml b/chrome/android/java/res/layout/selectable_list_layout.xml index 66bc974e..1884854 100644 --- a/chrome/android/java/res/layout/selectable_list_layout.xml +++ b/chrome/android/java/res/layout/selectable_list_layout.xml
@@ -31,7 +31,7 @@ android:layout_height="wrap_content" android:layout_gravity="center" android:drawablePadding="3dp" - android:textAppearance="@style/BlackDisabledText1" + android:textAppearance="@style/TextAppearance.BlackDisabledText1" android:visibility="gone" /> <org.chromium.chrome.browser.widget.LoadingView
diff --git a/chrome/android/java/res/layout/signin_view.xml b/chrome/android/java/res/layout/signin_view.xml index aed47c1..5332856 100644 --- a/chrome/android/java/res/layout/signin_view.xml +++ b/chrome/android/java/res/layout/signin_view.xml
@@ -41,7 +41,7 @@ android:layout_marginStart="@dimen/signin_margin_start" android:layout_marginTop="15dp" android:layout_marginEnd="@dimen/signin_margin_end" - android:textAppearance="@style/BlackHeadline" + android:textAppearance="@style/TextAppearance.BlackHeadline" tools:text="@string/signin_title"/> <LinearLayout android:id="@+id/signin_account_picker" @@ -77,7 +77,7 @@ android:layout_height="wrap_content" android:gravity="center_vertical" android:minHeight="20dp" - android:textAppearance="@style/BlackBodyDefault" + android:textAppearance="@style/TextAppearance.BlackBodyDefault" tools:text="John Doe"/> <TextView android:id="@+id/account_text_secondary" @@ -85,7 +85,7 @@ android:layout_height="wrap_content" android:gravity="center_vertical" android:minHeight="20dp" - android:textAppearance="@style/BlackCaption" + android:textAppearance="@style/TextAppearance.BlackCaption" tools:text="john.doe@example.com"/> </LinearLayout> <!-- For forced sign-in & consent bump this ImageView shows checkmark icon. --> @@ -119,7 +119,7 @@ android:layout_marginTop="20dp" android:layout_marginEnd="@dimen/signin_margin_end" android:layout_toEndOf="@id/signin_sync_icon" - android:textAppearance="@style/BlackBody" + android:textAppearance="@style/TextAppearance.BlackBody" tools:text="@string/signin_sync_description"/> <ImageView android:id="@+id/signin_personalization_icon" @@ -142,7 +142,7 @@ android:layout_marginTop="24dp" android:layout_marginEnd="@dimen/signin_margin_end" android:layout_toEndOf="@id/signin_sync_icon" - android:textAppearance="@style/BlackBody" + android:textAppearance="@style/TextAppearance.BlackBody" tools:text="@string/signin_personalization_description"/> <ImageView android:id="@+id/signin_google_services_icon" @@ -164,7 +164,7 @@ android:layout_marginTop="24dp" android:layout_marginEnd="@dimen/signin_margin_end" android:layout_toEndOf="@id/signin_google_services_icon" - android:textAppearance="@style/BlackBody" + android:textAppearance="@style/TextAppearance.BlackBody" tools:text="@string/signin_google_services_description"/> <View android:id="@+id/signin_divider" @@ -192,7 +192,7 @@ android:layout_marginTop="20dp" android:layout_marginEnd="@dimen/signin_margin_end" android:layout_toEndOf="@id/signin_details_icon" - android:textAppearance="@style/BlackBody" + android:textAppearance="@style/TextAppearance.BlackBody" tools:text="@string/signin_details_description"/> </RelativeLayout> </org.chromium.chrome.browser.signin.SigninScrollView>
diff --git a/chrome/android/java/res/layout/snackbar.xml b/chrome/android/java/res/layout/snackbar.xml index f397a0a..4346c44 100644 --- a/chrome/android/java/res/layout/snackbar.xml +++ b/chrome/android/java/res/layout/snackbar.xml
@@ -68,7 +68,7 @@ android:layout_marginBottom="14dp" android:layout_weight="1" android:textAlignment="viewStart" - android:textAppearance="@style/WhiteBody" /> + android:textAppearance="@style/TextAppearance.WhiteBody" /> <org.chromium.ui.widget.ButtonCompat android:id="@+id/snackbar_button"
diff --git a/chrome/android/java/res/layout/sync_promo_view.xml b/chrome/android/java/res/layout/sync_promo_view.xml index 6de470b..1ab74b9 100644 --- a/chrome/android/java/res/layout/sync_promo_view.xml +++ b/chrome/android/java/res/layout/sync_promo_view.xml
@@ -22,14 +22,14 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="8dp" - android:textAppearance="@style/BlackTitle1" /> + android:textAppearance="@style/TextAppearance.BlackTitle1" /> <TextView android:id="@+id/description" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" - android:textAppearance="@style/BlackBody" + android:textAppearance="@style/TextAppearance.BlackBody" android:lineSpacingExtra="6sp" /> <LinearLayout
diff --git a/chrome/android/java/res/layout/textbubble_text.xml b/chrome/android/java/res/layout/textbubble_text.xml index 90f3edd..03a482a9 100644 --- a/chrome/android/java/res/layout/textbubble_text.xml +++ b/chrome/android/java/res/layout/textbubble_text.xml
@@ -8,4 +8,4 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="16dp" - android:textAppearance="@style/WhiteTitle2" /> + android:textAppearance="@style/TextAppearance.WhiteTitle2" />
diff --git a/chrome/android/java/res/layout/textbubble_text_with_image.xml b/chrome/android/java/res/layout/textbubble_text_with_image.xml index c99355e..130f508 100644 --- a/chrome/android/java/res/layout/textbubble_text_with_image.xml +++ b/chrome/android/java/res/layout/textbubble_text_with_image.xml
@@ -29,6 +29,6 @@ android:id="@+id/message" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textAppearance="@style/WhiteTitle2" /> + android:textAppearance="@style/TextAppearance.WhiteTitle2" /> </LinearLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/tile_view_modern.xml b/chrome/android/java/res/layout/tile_view_modern.xml index 361c123..4d5ccb7c 100644 --- a/chrome/android/java/res/layout/tile_view_modern.xml +++ b/chrome/android/java/res/layout/tile_view_modern.xml
@@ -58,6 +58,6 @@ android:gravity="center_horizontal" android:lines="2" android:lineSpacingMultiplier="1.17" - android:textAppearance="@style/BlackCaption" /> + android:textAppearance="@style/TextAppearance.BlackCaption" /> </merge>
diff --git a/chrome/android/java/res/layout/tile_view_modern_condensed.xml b/chrome/android/java/res/layout/tile_view_modern_condensed.xml index 9cbe68e..b212111 100644 --- a/chrome/android/java/res/layout/tile_view_modern_condensed.xml +++ b/chrome/android/java/res/layout/tile_view_modern_condensed.xml
@@ -58,6 +58,6 @@ android:gravity="center_horizontal" android:lines="2" android:lineSpacingMultiplier="1.17" - android:textAppearance="@style/BlackCaption" /> + android:textAppearance="@style/TextAppearance.BlackCaption" /> </merge>
diff --git a/chrome/android/java/res/layout/update_menu_item.xml b/chrome/android/java/res/layout/update_menu_item.xml index 98b05087..2f9274ef 100644 --- a/chrome/android/java/res/layout/update_menu_item.xml +++ b/chrome/android/java/res/layout/update_menu_item.xml
@@ -30,7 +30,7 @@ android:id="@+id/menu_item_summary" android:layout_width="wrap_content" android:layout_height="match_parent" - android:textAppearance="@style/BlackCaption" /> + android:textAppearance="@style/TextAppearance.BlackCaption" /> </LinearLayout>
diff --git a/chrome/android/java/res/values-v17/styles.xml b/chrome/android/java/res/values-v17/styles.xml index 1e93ba6..12df8d7 100644 --- a/chrome/android/java/res/values-v17/styles.xml +++ b/chrome/android/java/res/values-v17/styles.xml
@@ -119,7 +119,7 @@ </style> <style name="AlertDialogTitleStyle" parent="RtlOverlay.DialogWindowTitle.AppCompat"> - <item name="android:textAppearance">@style/BlackHeadline</item> + <item name="android:textAppearance">@style/TextAppearance.BlackHeadline</item> </style> <!-- The dim amount should match the alpha of modal_dialog_scrim_color. --> @@ -139,10 +139,10 @@ <style name="PreferencesTheme" parent="ThemeWithActionBar"> <item name="android:textColorLink">@color/pref_accent_color</item> <item name="android:textAppearanceMedium">@style/TextAppearance.PreferenceMediumText</item> - <item name="android:textAppearanceSmall">@style/BlackBody</item> + <item name="android:textAppearanceSmall">@style/TextAppearance.BlackBody</item> <item name="android:preferenceCategoryStyle">@style/PreferenceCategory</item> <item name="android:spinnerItemStyle">@style/PreferenceSpinnerItem</item> - <item name="floatLabelTextAppearance">@style/BlackCaption</item> + <item name="floatLabelTextAppearance">@style/TextAppearance.BlackCaption</item> <item name="floatLabelPaddingLeft">@dimen/pref_autofill_field_horizontal_padding</item> <item name="floatLabelPaddingRight">@dimen/pref_autofill_field_horizontal_padding</item> <item name="floatLabelPaddingTop">@dimen/pref_autofill_field_top_margin</item> @@ -152,7 +152,7 @@ <item name="android:contextPopupMenuStyle" tools:targetApi="24">@style/PopupMenuStyle</item> </style> <style name="PreferenceActionBarModern" parent="@style/Widget.AppCompat.Light.ActionBar.Solid"> - <item name="titleTextStyle">@style/BlackHeadline</item> + <item name="titleTextStyle">@style/TextAppearance.BlackHeadline</item> </style> <style name="TextAppearance.PreferenceMediumText"> <item name="android:textSize">18sp</item> @@ -169,7 +169,7 @@ <item name="android:paddingTop">16dp</item> <item name="android:layout_marginBottom">16dp</item> </style> - <style name="TextAppearance.PreferenceCategoryText" parent="RobotoMediumStyle"> + <style name="TextAppearance.PreferenceCategoryText" parent="TextAppearance.RobotoMediumStyle"> <item name="android:textColor">@color/pref_accent_color</item> <item name="android:textSize">12sp</item> </style> @@ -179,7 +179,7 @@ <item name="android:textAppearance">?android:attr/textAppearanceMedium</item> </style> <style name="PreferenceSummary"> - <item name="android:textAppearance">@style/BlackBody</item> + <item name="android:textAppearance">@style/TextAppearance.BlackBody</item> </style> <style name="PreferenceScreenLayout"> <item name="android:paddingTop">16dp</item> @@ -235,7 +235,7 @@ <item name="actionBarStyle">@style/ManageSpaceActionBarModern</item> </style> <style name="ManageSpaceActionBarModern" parent="PreferenceActionBarModern"> - <item name="titleTextStyle">@style/WhiteHeadline</item> + <item name="titleTextStyle">@style/TextAppearance.WhiteHeadline</item> </style> <style name="ManageSpaceActivityButton"> <item name="android:layout_width">wrap_content</item> @@ -279,7 +279,7 @@ <item name="android:popupBackground">@null</item> <item name="android:listDivider">@null</item> <item name="android:listPreferredItemHeightSmall">48dp</item> - <item name="android:textAppearance">@style/BlackTitle1</item> + <item name="android:textAppearance">@style/TextAppearance.BlackTitle1</item> <item name="colorControlHighlight">@color/control_highlight_color</item> </style> <style name="OverflowMenuButton"> @@ -377,7 +377,7 @@ <item name="android:windowIsTranslucent">true</item> <item name="android:windowNoTitle">true</item> </style> - <style name="PromoDialogNormalText" parent="@style/BlackBody"> + <style name="PromoDialogNormalText" parent="@style/TextAppearance.BlackBody"> <item name="android:lineSpacingMultiplier">1.3</item> </style> @@ -397,7 +397,7 @@ <item name="android:layout_height">wrap_content</item> <item name="android:gravity">center</item> <item name="android:lineSpacingMultiplier">1.4</item> - <item name="android:textAppearance">@style/BlackHeadline</item> + <item name="android:textAppearance">@style/TextAppearance.BlackHeadline</item> </style> <!-- Web Notifications --> @@ -465,7 +465,7 @@ explicitly specified. --> <style name="DialogWhenLargeBase" parent="Theme.AppCompat.Light.DialogWhenLarge" > <item name="android:windowBackground">@drawable/bg_white_dialog</item> - <item name="android:textAppearance">@style/BlackBodyDefault</item> + <item name="android:textAppearance">@style/TextAppearance.BlackBodyDefault</item> <item name="android:textColorLink">@color/default_text_color_link</item> <item name="colorPrimaryDark">@android:color/black</item> <item name="colorAccent">@color/light_active_color</item> @@ -487,7 +487,7 @@ </style> <style name="SigninDialogButtonStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog"> - <item name="android:textAppearance">@style/BlueButtonText2</item> + <item name="android:textAppearance">@style/TextAppearance.BlueButtonText2</item> </style> <!-- Contextual Search styles --> @@ -501,7 +501,7 @@ <item name="android:paddingStart">53dp</item> <item name="android:paddingEnd">53dp</item> </style> - <style name="ContextualSearchTextView" parent="@style/BlackTitle1"> + <style name="ContextualSearchTextView" parent="@style/TextAppearance.BlackTitle1"> <item name="android:layout_height">match_parent</item> <item name="android:ellipsize">end</item> <item name="android:includeFontPadding">false</item> @@ -534,7 +534,7 @@ <item name="android:ellipsize">end</item> <item name="android:includeFontPadding">false</item> <item name="android:singleLine">true</item> - <item name="android:textAppearance">@style/BlackBody</item> + <item name="android:textAppearance">@style/TextAppearance.BlackBody</item> </style> <!-- Payments UI --> @@ -542,17 +542,17 @@ <item name="android:textColor">@color/error_text_color</item> <item name="android:textSize">@dimen/text_size_medium</item> </style> - <style name="TextAppearance.PaymentsUiSectionDescriptiveTextEndAligned" parent="BlackBody"> + <style name="TextAppearance.PaymentsUiSectionDescriptiveTextEndAligned" parent="TextAppearance.BlackBody"> <item name="android:textAlignment">viewEnd</item> </style> <style name="TextAppearance.PaymentsUiSectionPendingTextEndAligned" parent="TextAppearance.PaymentsUiSectionDescriptiveTextEndAligned"> <item name="android:textColor">@color/explanation_text_color</item> </style> - <style name="TextAppearance.EditorDialogSectionAddButton" parent="BlueLink2"> + <style name="TextAppearance.EditorDialogSectionAddButton" parent="TextAppearance.BlueLink2"> <item name="android:textAllCaps">true</item> </style> - <style name="TextAppearance.PaymentRequestHeaderTitle" parent="BlackTitle1"> + <style name="TextAppearance.PaymentRequestHeaderTitle" parent="TextAppearance.BlackTitle1"> <item name="android:textStyle">bold</item> </style> <style name="TextAppearance.PaymentRequestErrorText"> @@ -587,7 +587,7 @@ <item name="tint">@color/dark_mode_tint</item> </style> <style name="ModernToolbar" parent="Widget.AppCompat.Toolbar"> - <item name="titleTextAppearance">@style/BlackHeadline</item> + <item name="titleTextAppearance">@style/TextAppearance.BlackHeadline</item> <item name="windowActionBarOverlay">true</item> <item name="android:background">@color/modern_primary_color</item> </style> @@ -621,16 +621,39 @@ <item name="android:textSize">@dimen/text_size_large</item> </style> <style name="SadTabBodyText"> - <item name="android:textAppearance">@style/BlackBody</item> + <item name="android:textAppearance">@style/TextAppearance.BlackBody</item> <item name="android:layout_gravity">start</item> </style> <style name="SigninButtonBorderlessRegular" parent="@style/TextButton"> <item name="android:paddingStart">0dp</item> <item name="android:paddingEnd">0dp</item> - <item name="android:textAppearance">@style/BlueLink2</item> + <item name="android:textAppearance">@style/TextAppearance.BlueLink2</item> </style> <style name="NavigationPopupDialog" parent="Widget.AppCompat.Light.ListPopupWindow" /> + <!-- Misc text appearance styles --> + <style name="TextAppearance.AddToHomeScreenEditText"> + <item name="android:textSize">18sp</item> + </style> + <style name="TextAppearance.AddToHomeScreenWebAppName" parent="TextAppearance.BlackTitle1"> + <item name="android:textSize">20sp</item> + </style> + <style name="TextAppearance.ConnectionInfoHeadline" parent="TextAppearance.RobotoMediumStyle"> + <item name="android:textColor">@color/connection_info_popup_text</item> + </style> + <style name="TextAppearance.ConnectionInfoDescription"> + <item name="android:textColor">@color/connection_info_popup_text</item> + </style> + <style name="TextAppearance.PageInfoPermissionSubtitle" parent="TextAppearance.BlackBody"> + <item name="android:textColor">@color/secondary_text_default_material_light</item> + </style> + <style name="TextAppearance.PhotoPickerSpecialTile" parent="TextAppearance.BlackTitle2"> + <item name="android:textColor">@color/photo_picker_special_tile_color</item> + </style> + <style name="TextAppearance.SearchEngineRecentTitle" parent="TextAppearance.RobotoMediumStyle"> + <item name="android:textColor">@color/default_text_color_link</item> + </style> + <!-- New Tab Page --> <style name="NewTabPageRecyclerView"> <item name="android:colorEdgeEffect" tools:targetApi="21">@color/modern_grey_300</item> @@ -676,10 +699,6 @@ </style> <!-- Download Home --> - <style name="TextAppearance.DownloadHomeChip"> - <item name="android:textColor">@color/chip_text_color</item> - <item name="android:textSize">@dimen/text_size_medium</item> - </style> <style name="DateView"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">wrap_content</item> @@ -687,11 +706,11 @@ <item name="android:layout_marginBottom">10dp</item> <item name="android:layout_marginStart">@dimen/list_item_default_margin</item> <item name="android:layout_marginEnd">@dimen/list_item_default_margin</item> - <item name="android:textAppearance">@style/BlackBody</item> + <item name="android:textAppearance">@style/TextAppearance.BlackBody</item> </style> <!-- Data Reduction --> - <style name="TextAppearance.DataUsageBreakdownColumnLabel" parent="@style/BlackButtonText"> + <style name="TextAppearance.DataUsageBreakdownColumnLabel" parent="@style/TextAppearance.BlackButtonText"> <item name="android:textAllCaps">false</item> </style> <style name="DataUsageBreakdownColumnLabel"> @@ -702,7 +721,7 @@ <item name="android:textAppearance"> @style/TextAppearance.DataUsageBreakdownColumnLabel</item> </style> - <style name="TextAppearance.DataUsageBreakdownSavedColumnLabel" parent="@style/BlueButtonText2"> + <style name="TextAppearance.DataUsageBreakdownSavedColumnLabel" parent="@style/TextAppearance.BlueButtonText2"> <item name="android:textAllCaps">false</item> </style> <style name="DataUsageBreakdownSavedColumnLabel" parent="DataUsageBreakdownColumnLabel"> @@ -714,26 +733,26 @@ <item name="android:paddingBottom">10dp</item> <item name="android:paddingTop">10dp</item> <item name="android:singleLine">true</item> - <item name="android:textAppearance">@style/BlackCaption</item> + <item name="android:textAppearance">@style/TextAppearance.BlackCaption</item> </style> <style name="DataUsageBreakdownSavedColumnItem" parent="DataUsageBreakdownColumnItem"> - <item name="android:textAppearance">@style/BlueLink3</item> + <item name="android:textAppearance">@style/TextAppearance.BlueLink3</item> </style> - <style name="TextAppearance.DataReductionHeadline" parent="BlackHeadline"> + <style name="TextAppearance.DataReductionHeadline" parent="TextAppearance.BlackHeadline"> <item name="android:textColor">@color/default_text_color_link</item> </style> <!-- Incognito New Tab Page --> <style name="IncognitoNewTabMessage"> <item name="android:maxWidth">660dp</item> - <item name="android:textAppearance">@style/WhiteBodyIncognito</item> + <item name="android:textAppearance">@style/TextAppearance.WhiteBodyIncognito</item> <item name="android:lineSpacingMultiplier">1.2</item> </style> <style name="IncognitoNewTabLearnMoreLink"> <item name="android:background">?attr/listChoiceBackgroundIndicator</item> <item name="android:clickable">true</item> <item name="android:focusable">true</item> - <item name="android:textAppearance">@style/BlueButtonText1</item> + <item name="android:textAppearance">@style/TextAppearance.BlueButtonText1</item> <item name="android:padding">16dp</item> </style> <style name="TextAppearance.IncognitoNewTabLearnMoreLinkModern"> @@ -755,14 +774,14 @@ </style> <!-- TODO(twellington): Use standard line height for SuggestionsCard*. Updating the leading for these requires updating the NTP article suggestions thumbnail size as well. --> - <style name="SuggestionCardTitleModern" parent="BlackTitle1"> + <style name="SuggestionCardTitleModern" parent="TextAppearance.BlackTitle1"> <item name="android:ellipsize">end</item> <item name="leading">20sp</item> </style> <style name="ContextualSuggestionCardTitleModern" parent="SuggestionCardTitleModern"> <item name="leading">@dimen/text_size_large_leading</item> </style> - <style name="SuggestionCardBodyModern" parent="BlackBody"> + <style name="SuggestionCardBodyModern" parent="TextAppearance.BlackBody"> <item name="android:layout_marginTop">8dp</item> <item name="android:ellipsize">end</item> <item name="leading">16sp</item> @@ -780,7 +799,7 @@ <item name="android:layout_width">match_parent</item> <item name="android:layout_height">wrap_content</item> </style> - <style name="TextAppearance.PasswordEntryName" parent="BlueButtonText2"> + <style name="TextAppearance.PasswordEntryName" parent="TextAppearance.BlueButtonText2"> <item name="android:textAllCaps">false</item> </style>
diff --git a/chrome/android/java/res/values-v21/styles.xml b/chrome/android/java/res/values-v21/styles.xml index fa2daff..a7f6ce3 100644 --- a/chrome/android/java/res/values-v21/styles.xml +++ b/chrome/android/java/res/values-v21/styles.xml
@@ -14,7 +14,7 @@ <item name="android:alertDialogTheme">@style/PreferencesDialogTheme</item> <item name="android:divider">@null</item> <item name="android:spinnerItemStyle">@style/PreferenceSpinnerItem</item> - <item name="floatLabelTextAppearance">@style/BlackCaption</item> + <item name="floatLabelTextAppearance">@style/TextAppearance.BlackCaption</item> <item name="floatLabelPaddingLeft">@dimen/pref_autofill_field_horizontal_padding</item> <item name="floatLabelPaddingRight">@dimen/pref_autofill_field_horizontal_padding</item> <item name="floatLabelPaddingTop">@dimen/pref_autofill_field_top_margin</item> @@ -27,7 +27,7 @@ <item name="android:paddingStart">?android:attr/listPreferredItemPaddingStart</item> <item name="android:paddingEnd">4dp</item> </style> - <style name="TextAppearance.PreferenceCategoryText" parent="RobotoMediumStyle"> + <style name="TextAppearance.PreferenceCategoryText" parent="TextAppearance.RobotoMediumStyle"> <item name="android:textColor">@color/pref_accent_color</item> <item name="android:textSize">12sp</item> </style> @@ -37,7 +37,7 @@ <item name="android:textAppearance">?android:attr/textAppearanceListItem</item> </style> <style name="PreferenceSummary"> - <item name="android:textAppearance">@style/BlackBody</item> + <item name="android:textAppearance">@style/TextAppearance.BlackBody</item> </style> <style name="PreferenceLayoutBase"> <item name="android:background">?android:attr/activatedBackgroundIndicator</item>
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index d015eecf..3c2ebdc 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -553,12 +553,8 @@ <item type="dimen" name="dialog_fixed_height_minor">100%</item> <!-- Chip list --> - <dimen name="chip_no_icon_padding">16dp</dimen> - <dimen name="chip_icon_padding">8dp</dimen> <dimen name="chip_list_inter_chip_padding">2.5dp</dimen> <dimen name="chip_list_side_padding">16dp</dimen> - <item name="chip_background_selected_focused_alpha" format="float" type="dimen">0.12</item> - <item name="chip_background_selected_alpha" format="float" type="dimen">0.06</item> <!-- Download manager dimensions --> <dimen name="download_manager_ideal_image_width">150dp</dimen>
diff --git a/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_chip_assistive.xml b/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_chip_assistive.xml index 62309a2..7dd29dd 100644 --- a/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_chip_assistive.xml +++ b/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_chip_assistive.xml
@@ -8,7 +8,7 @@ android:layout_height="wrap_content" android:paddingStart="16dp" android:paddingEnd="16dp" - android:textAppearance="@style/BlackTitle2" + android:textAppearance="@style/TextAppearance.BlackTitle2" android:gravity="center_vertical|center_horizontal" android:minHeight="32dp" android:singleLine="true"
diff --git a/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_details.xml b/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_details.xml index 2ad1b18..c7be29f 100644 --- a/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_details.xml +++ b/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_details.xml
@@ -60,7 +60,7 @@ android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" - android:textAppearance="@style/BlackCaption" + android:textAppearance="@style/TextAppearance.BlackCaption" android:singleLine="true" android:requiresFadingEdge="horizontal" android:fadingEdgeLength="20dp" @@ -72,8 +72,8 @@ android:id="@+id/purchase_summary" android:layout_width="wrap_content" android:layout_height="match_parent" - android:textAppearance="@style/BlackCaption" + android:textAppearance="@style/TextAppearance.BlackCaption" android:singleLine="true"/> </LinearLayout> </LinearLayout> -</LinearLayout> \ No newline at end of file +</LinearLayout>
diff --git a/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_sheet.xml b/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_sheet.xml index bdccf7a9..36c767a 100644 --- a/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_sheet.xml +++ b/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_sheet.xml
@@ -67,7 +67,7 @@ android:gravity="center_vertical" android:paddingStart="24dp" android:paddingEnd="24dp" - android:textAppearance="@style/BlackTitle2" + android:textAppearance="@style/TextAppearance.BlackTitle2" android:layout_weight="1.0" android:maxLines="2" android:ellipsize="end"/>
diff --git a/chrome/android/java/res_autofill_assistant/layout/init_screen.xml b/chrome/android/java/res_autofill_assistant/layout/init_screen.xml index 01944d5..56319ee6 100644 --- a/chrome/android/java/res_autofill_assistant/layout/init_screen.xml +++ b/chrome/android/java/res_autofill_assistant/layout/init_screen.xml
@@ -69,7 +69,7 @@ <TextView android:layout_height="wrap_content" android:layout_width="wrap_content" - android:textAppearance="@style/BlackTitle2" + android:textAppearance="@style/TextAppearance.BlackTitle2" android:gravity="center_horizontal" android:text="@string/autofill_assistant_onboarding_title" /> @@ -78,7 +78,7 @@ <TextView android:layout_height="wrap_content" android:layout_width="wrap_content" - android:textAppearance="@style/BlackBody" + android:textAppearance="@style/TextAppearance.BlackBody" android:paddingStart="35dp" android:paddingEnd="35dp" android:gravity="center_horizontal" @@ -115,7 +115,7 @@ android:layout_height="wrap_content" android:layout_margin="0dp" android:layout_gravity="center" - android:textAppearance="@style/BlackCaption" + android:textAppearance="@style/TextAppearance.BlackCaption" android:text="@string/autofill_assistant_google_terms_description" /> </LinearLayout>
diff --git a/chrome/android/java/res_autofill_assistant/values-v17/styles.xml b/chrome/android/java/res_autofill_assistant/values-v17/styles.xml index 9357f5a..6044d68a 100644 --- a/chrome/android/java/res_autofill_assistant/values-v17/styles.xml +++ b/chrome/android/java/res_autofill_assistant/values-v17/styles.xml
@@ -5,7 +5,7 @@ <resources> <!-- TODO(crbuc.com/806868): Use a Chrome approved text appearance and remove this. --> - <style name="TextAppearance.DetailsTitle" parent="BlackCaptionDefault"> + <style name="TextAppearance.DetailsTitle" parent="TextAppearance.BlackCaptionDefault"> <item name="android:textStyle">bold</item> </style> -</resources> \ No newline at end of file +</resources>
diff --git a/chrome/android/java/res_download/layout/confirm_oma_download.xml b/chrome/android/java/res_download/layout/confirm_oma_download.xml index d8275b8..355c2504 100644 --- a/chrome/android/java/res_download/layout/confirm_oma_download.xml +++ b/chrome/android/java/res_download/layout/confirm_oma_download.xml
@@ -16,12 +16,12 @@ android:text="@string/oma_download_name_label" android:gravity="start" android:padding="3dp" - android:textAppearance="@style/BlackBodyDefault" /> + android:textAppearance="@style/TextAppearance.BlackBodyDefault" /> <TextView android:id="@+id/oma_download_name" android:gravity="start" android:padding="3dp" - android:textAppearance="@style/BlackBodyDefault" /> + android:textAppearance="@style/TextAppearance.BlackBodyDefault" /> </TableRow> <TableRow> @@ -29,12 +29,12 @@ android:text="@string/oma_download_vendor_label" android:gravity="start" android:padding="3dp" - android:textAppearance="@style/BlackBodyDefault" /> + android:textAppearance="@style/TextAppearance.BlackBodyDefault" /> <TextView android:id="@+id/oma_download_vendor" android:gravity="start" android:padding="3dp" - android:textAppearance="@style/BlackBodyDefault" /> + android:textAppearance="@style/TextAppearance.BlackBodyDefault" /> </TableRow> <TableRow> @@ -42,12 +42,12 @@ android:text="@string/oma_download_size_label" android:gravity="start" android:padding="3dp" - android:textAppearance="@style/BlackBodyDefault" /> + android:textAppearance="@style/TextAppearance.BlackBodyDefault" /> <TextView android:id="@+id/oma_download_size" android:gravity="start" android:padding="3dp" - android:textAppearance="@style/BlackBodyDefault" /> + android:textAppearance="@style/TextAppearance.BlackBodyDefault" /> </TableRow> @@ -56,12 +56,12 @@ android:text="@string/oma_download_type_label" android:gravity="start" android:padding="3dp" - android:textAppearance="@style/BlackBodyDefault" /> + android:textAppearance="@style/TextAppearance.BlackBodyDefault" /> <TextView android:id="@+id/oma_download_type" android:gravity="start" android:padding="3dp" - android:textAppearance="@style/BlackBodyDefault" /> + android:textAppearance="@style/TextAppearance.BlackBodyDefault" /> </TableRow> <TableRow> @@ -69,11 +69,11 @@ android:text="@string/oma_download_description_label" android:gravity="start" android:padding="3dip" - android:textAppearance="@style/BlackBodyDefault" /> + android:textAppearance="@style/TextAppearance.BlackBodyDefault" /> <TextView android:id="@+id/oma_download_description" android:gravity="start" android:padding="3dip" - android:textAppearance="@style/BlackBodyDefault" /> + android:textAppearance="@style/TextAppearance.BlackBodyDefault" /> </TableRow> </TableLayout> \ No newline at end of file
diff --git a/chrome/android/java/res_download/layout/download_home_tabs.xml b/chrome/android/java/res_download/layout/download_home_tabs.xml index 619c4e7..65be890 100644 --- a/chrome/android/java/res_download/layout/download_home_tabs.xml +++ b/chrome/android/java/res_download/layout/download_home_tabs.xml
@@ -19,7 +19,7 @@ app:tabMaxWidth="2000dp" app:tabMode="fixed" app:tabGravity="center" - app:tabTextAppearance="@style/BlackLink" + app:tabTextAppearance="@style/TextAppearance.BlackLink" app:tabIndicatorColor="@color/light_active_color" android:background="@drawable/download_home_tabs_bg">
diff --git a/chrome/android/java/res_download/layout/download_home_toolbar.xml b/chrome/android/java/res_download/layout/download_home_toolbar.xml index 18f3e73c..c116212 100644 --- a/chrome/android/java/res_download/layout/download_home_toolbar.xml +++ b/chrome/android/java/res_download/layout/download_home_toolbar.xml
@@ -17,7 +17,7 @@ android:id="@+id/title_bar" android:layout_width="wrap_content" android:layout_height="wrap_content" - style="@style/BlackHeadline" + style="@style/TextAppearance.BlackHeadline" android:text="@string/menu_downloads"/> </org.chromium.chrome.browser.download.home.toolbar.DownloadHomeToolbar>
diff --git a/chrome/android/java/res_download/layout/download_item_view.xml b/chrome/android/java/res_download/layout/download_item_view.xml index 6e933d6..db32108a 100644 --- a/chrome/android/java/res_download/layout/download_item_view.xml +++ b/chrome/android/java/res_download/layout/download_item_view.xml
@@ -57,7 +57,7 @@ android:layout_toStartOf="@+id/pause_button" android:minHeight="18dp" android:singleLine="true" - android:textAppearance="@style/BlackTitle1" /> + android:textAppearance="@style/TextAppearance.BlackTitle1" /> <org.chromium.chrome.browser.widget.MaterialProgressBar android:id="@+id/download_progress_view"
diff --git a/chrome/android/java/res_download/layout/download_location_dialog.xml b/chrome/android/java/res_download/layout/download_location_dialog.xml index 0a71bfa4..e0a6a9e 100644 --- a/chrome/android/java/res_download/layout/download_location_dialog.xml +++ b/chrome/android/java/res_download/layout/download_location_dialog.xml
@@ -19,7 +19,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/subtitle" - android:textAppearance="@style/BlackBody" + android:textAppearance="@style/TextAppearance.BlackBody" android:visibility="gone" android:layout_marginBottom="16dp" /> @@ -39,7 +39,7 @@ android:id="@+id/file_name" android:layout_width="match_parent" android:layout_height="wrap_content" - android:textAppearance="@style/BlackTitle1" + android:textAppearance="@style/TextAppearance.BlackTitle1" android:singleLine="true" /> </LinearLayout> @@ -65,7 +65,7 @@ </LinearLayout> <CheckBox - style="@style/BlackDisabledText3" + style="@style/TextAppearance.BlackDisabledText3" android:id="@+id/show_again_checkbox" android:layout_width="match_parent" android:layout_height="wrap_content"
diff --git a/chrome/android/java/res_download/layout/download_location_preference_item.xml b/chrome/android/java/res_download/layout/download_location_preference_item.xml index b2a67ad9e..37588cb 100644 --- a/chrome/android/java/res_download/layout/download_location_preference_item.xml +++ b/chrome/android/java/res_download/layout/download_location_preference_item.xml
@@ -32,7 +32,7 @@ android:layout_marginStart="6dp" android:maxLines="1" android:ellipsize="end" - android:textAppearance="@style/BlackTitle1" /> + android:textAppearance="@style/TextAppearance.BlackTitle1" /> <TextView android:id="@+id/description" android:layout_width="match_parent" @@ -40,7 +40,7 @@ android:layout_marginStart="6dp" android:maxLines="1" android:ellipsize="end" - android:textAppearance="@style/BlackBody" /> + android:textAppearance="@style/TextAppearance.BlackBody" /> </LinearLayout> </LinearLayout>
diff --git a/chrome/android/java/res_download/layout/download_location_spinner_item.xml b/chrome/android/java/res_download/layout/download_location_spinner_item.xml index 7d7e536..a0543c9 100644 --- a/chrome/android/java/res_download/layout/download_location_spinner_item.xml +++ b/chrome/android/java/res_download/layout/download_location_spinner_item.xml
@@ -8,4 +8,4 @@ android:layout_height="match_parent" android:id="@+id/text" android:singleLine="true" - android:textAppearance="@style/BlackTitle1" /> \ No newline at end of file + android:textAppearance="@style/TextAppearance.BlackTitle1" /> \ No newline at end of file
diff --git a/chrome/android/java/res_download/layout/download_manager_generic_item.xml b/chrome/android/java/res_download/layout/download_manager_generic_item.xml index bcf4888e..8b024d54 100644 --- a/chrome/android/java/res_download/layout/download_manager_generic_item.xml +++ b/chrome/android/java/res_download/layout/download_manager_generic_item.xml
@@ -43,7 +43,7 @@ android:id="@+id/title" style="@style/DownloadItemText" android:layout_marginTop="11dp" - android:textAppearance="@style/BlackTitle1" + android:textAppearance="@style/TextAppearance.BlackTitle1" app:layout_column="1" app:layout_row="0" app:layout_gravity="fill_horizontal" /> @@ -51,7 +51,7 @@ <TextView android:id="@+id/caption" style="@style/DownloadItemText" - android:textAppearance="@style/BlackHint2" + android:textAppearance="@style/TextAppearance.BlackHint2" app:layout_column="1" app:layout_row="1" app:layout_gravity="fill_horizontal" />
diff --git a/chrome/android/java/res_download/layout/download_manager_in_progress_image_item.xml b/chrome/android/java/res_download/layout/download_manager_in_progress_image_item.xml index 910b7a2..4f806f9 100644 --- a/chrome/android/java/res_download/layout/download_manager_in_progress_image_item.xml +++ b/chrome/android/java/res_download/layout/download_manager_in_progress_image_item.xml
@@ -41,7 +41,7 @@ <TextView android:id="@+id/caption" style="@style/DownloadItemText" - android:textAppearance="@style/BlackHint2" + android:textAppearance="@style/TextAppearance.BlackHint2" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1"
diff --git a/chrome/android/java/res_download/layout/download_manager_in_progress_item.xml b/chrome/android/java/res_download/layout/download_manager_in_progress_item.xml index c5e5a01..7e00b7f6 100644 --- a/chrome/android/java/res_download/layout/download_manager_in_progress_item.xml +++ b/chrome/android/java/res_download/layout/download_manager_in_progress_item.xml
@@ -29,7 +29,7 @@ android:id="@+id/title" style="@style/DownloadItemText" android:layout_marginTop="11dp" - android:textAppearance="@style/BlackTitle1" + android:textAppearance="@style/TextAppearance.BlackTitle1" app:layout_column="1" app:layout_row="0" app:layout_gravity="fill_horizontal" /> @@ -37,7 +37,7 @@ <TextView android:id="@+id/caption" style="@style/DownloadItemText" - android:textAppearance="@style/BlackHint2" + android:textAppearance="@style/TextAppearance.BlackHint2" app:layout_column="1" app:layout_row="1" app:layout_gravity="fill_horizontal" />
diff --git a/chrome/android/java/res_download/layout/download_manager_in_progress_video_item.xml b/chrome/android/java/res_download/layout/download_manager_in_progress_video_item.xml index 0e26ee7..2543ea86 100644 --- a/chrome/android/java/res_download/layout/download_manager_in_progress_video_item.xml +++ b/chrome/android/java/res_download/layout/download_manager_in_progress_video_item.xml
@@ -58,14 +58,14 @@ style="@style/DownloadItemText" android:layout_width="match_parent" android:layout_marginTop="11dp" - android:textAppearance="@style/BlackTitle1" /> + android:textAppearance="@style/TextAppearance.BlackTitle1" /> <TextView android:id="@+id/caption" style="@style/DownloadItemText" android:layout_width="match_parent" android:layout_marginBottom="11dp" - android:textAppearance="@style/BlackHint2" /> + android:textAppearance="@style/TextAppearance.BlackHint2" /> </LinearLayout>
diff --git a/chrome/android/java/res_download/layout/download_manager_prefetch_item.xml b/chrome/android/java/res_download/layout/download_manager_prefetch_item.xml index c53666d7..ffcfc7c 100644 --- a/chrome/android/java/res_download/layout/download_manager_prefetch_item.xml +++ b/chrome/android/java/res_download/layout/download_manager_prefetch_item.xml
@@ -54,7 +54,7 @@ android:minHeight="40dp" android:maxLines="2" android:ellipsize="end" - android:textAppearance="@style/BlackBodyDefault" + android:textAppearance="@style/TextAppearance.BlackBodyDefault" android:textAlignment="viewStart" app:layout_column="1" app:layout_row="0" @@ -69,7 +69,7 @@ android:layout_marginBottom="8dp" android:maxLines="1" android:ellipsize="end" - android:textAppearance="@style/BlackCaption" + android:textAppearance="@style/TextAppearance.BlackCaption" android:textAlignment="viewStart" app:layout_column="1" app:layout_row="1" @@ -82,7 +82,7 @@ android:layout_height="wrap_content" android:maxLines="1" android:ellipsize="end" - android:textAppearance="@style/BlackCaption" + android:textAppearance="@style/TextAppearance.BlackCaption" android:textAlignment="viewStart" app:layout_column="1" app:layout_row="2"
diff --git a/chrome/android/java/res_download/layout/download_manager_section_header.xml b/chrome/android/java/res_download/layout/download_manager_section_header.xml index 87b1e341..9ab6962 100644 --- a/chrome/android/java/res_download/layout/download_manager_section_header.xml +++ b/chrome/android/java/res_download/layout/download_manager_section_header.xml
@@ -26,7 +26,7 @@ android:layout_below="@+id/top_space" android:paddingStart="@dimen/list_item_default_margin" android:maxLines="1" - android:textAppearance="@style/BlackTitle1"/> + android:textAppearance="@style/TextAppearance.BlackTitle1"/> <TextView android:id="@+id/title" @@ -34,7 +34,7 @@ android:layout_height="wrap_content" android:layout_below="@+id/date" android:paddingStart="@dimen/list_item_default_margin" - android:textAppearance="@style/BlackHint2" + android:textAppearance="@style/TextAppearance.BlackHint2" android:maxLines="1" /> <Space
diff --git a/chrome/android/java/res_download/layout/download_manager_spinner.xml b/chrome/android/java/res_download/layout/download_manager_spinner.xml index 7888971..3ed71893 100644 --- a/chrome/android/java/res_download/layout/download_manager_spinner.xml +++ b/chrome/android/java/res_download/layout/download_manager_spinner.xml
@@ -6,4 +6,4 @@ <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textAppearance="@style/BlackHeadline" /> \ No newline at end of file + android:textAppearance="@style/TextAppearance.BlackHeadline" /> \ No newline at end of file
diff --git a/chrome/android/java/res_download/layout/download_manager_spinner_drop_down.xml b/chrome/android/java/res_download/layout/download_manager_spinner_drop_down.xml index 4980abb7..78656c49 100644 --- a/chrome/android/java/res_download/layout/download_manager_spinner_drop_down.xml +++ b/chrome/android/java/res_download/layout/download_manager_spinner_drop_down.xml
@@ -12,4 +12,4 @@ android:minWidth="176dp" android:minHeight="48dp" android:paddingStart="16dp" - android:textAppearance="@style/BlackTitle1" /> + android:textAppearance="@style/TextAppearance.BlackTitle1" />
diff --git a/chrome/android/java/res_download/layout/download_manager_ui_space_widget.xml b/chrome/android/java/res_download/layout/download_manager_ui_space_widget.xml index 29621bd..03534ec 100644 --- a/chrome/android/java/res_download/layout/download_manager_ui_space_widget.xml +++ b/chrome/android/java/res_download/layout/download_manager_ui_space_widget.xml
@@ -25,7 +25,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" - android:textAppearance="@style/BlueLink3" /> + android:textAppearance="@style/TextAppearance.BlueLink3" /> <!-- The progress bar uses 20dp of space, vertically, including spacing. --> <org.chromium.chrome.browser.widget.MaterialProgressBar @@ -43,7 +43,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" - android:textAppearance="@style/BlackDisabledText2" /> + android:textAppearance="@style/TextAppearance.BlackDisabledText2" /> </LinearLayout>
diff --git a/chrome/android/java/res_download/layout/download_manager_video_item.xml b/chrome/android/java/res_download/layout/download_manager_video_item.xml index 1a1801a..52f769a 100644 --- a/chrome/android/java/res_download/layout/download_manager_video_item.xml +++ b/chrome/android/java/res_download/layout/download_manager_video_item.xml
@@ -57,14 +57,14 @@ style="@style/DownloadItemText" android:layout_width="match_parent" android:layout_marginTop="11dp" - android:textAppearance="@style/BlackTitle1" /> + android:textAppearance="@style/TextAppearance.BlackTitle1" /> <TextView android:id="@+id/caption" style="@style/DownloadItemText" android:layout_width="match_parent" android:layout_marginBottom="11dp" - android:textAppearance="@style/BlackHint2" /> + android:textAppearance="@style/TextAppearance.BlackHint2" /> </LinearLayout> <include layout="@layout/list_menu_button"
diff --git a/chrome/android/java/res_download/layout/download_storage_summary.xml b/chrome/android/java/res_download/layout/download_storage_summary.xml index f41c382..73d0cf7 100644 --- a/chrome/android/java/res_download/layout/download_storage_summary.xml +++ b/chrome/android/java/res_download/layout/download_storage_summary.xml
@@ -11,7 +11,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" - android:textAppearance="@style/BlackDisabledText2" + android:textAppearance="@style/TextAppearance.BlackDisabledText2" android:maxLines="1" android:paddingTop="8dp" android:paddingBottom="8dp" /> \ No newline at end of file
diff --git a/chrome/android/java/res_download/layout/downloads_empty_view.xml b/chrome/android/java/res_download/layout/downloads_empty_view.xml index cd07b76..bfbb309 100644 --- a/chrome/android/java/res_download/layout/downloads_empty_view.xml +++ b/chrome/android/java/res_download/layout/downloads_empty_view.xml
@@ -14,7 +14,7 @@ android:layout_height="wrap_content" android:layout_gravity="center" android:drawablePadding="3dp" - android:textAppearance="@style/BlackDisabledText1"/> + android:textAppearance="@style/TextAppearance.BlackDisabledText1"/> <org.chromium.chrome.browser.widget.LoadingView android:id="@+id/loading"
diff --git a/chrome/android/java/res_download/values-v17/styles.xml b/chrome/android/java/res_download/values-v17/styles.xml index 57cf3ad..a1bccb57 100644 --- a/chrome/android/java/res_download/values-v17/styles.xml +++ b/chrome/android/java/res_download/values-v17/styles.xml
@@ -11,7 +11,7 @@ <item name="android:layout_height">wrap_content</item> <item name="android:layout_marginTop">0dp</item> <item name="android:minHeight">18dp</item> - <item name="android:textAppearance">@style/BlackBody</item> + <item name="android:textAppearance">@style/TextAppearance.BlackBody</item> <item name="android:ellipsize">start</item> <item name="android:singleLine">true</item> </style> @@ -22,7 +22,7 @@ <item name="android:layout_alignParentStart">true</item> <item name="android:paddingEnd">16dp</item> <item name="android:singleLine">true</item> - <item name="android:textAppearance">@style/BlackTitle1</item> + <item name="android:textAppearance">@style/TextAppearance.BlackTitle1</item> </style> <style name="DownloadDescriptionStyle"> <item name="android:layout_width">wrap_content</item> @@ -34,7 +34,7 @@ <item name="android:textAlignment">viewStart</item> <item name="android:ellipsize">start</item> <item name="android:singleLine">true</item> - <item name="android:textAppearance">@style/BlackBody</item> + <item name="android:textAppearance">@style/TextAppearance.BlackBody</item> </style> <style name="DownloadIconView" parent="@style/ListItemStartIcon"> <item name="android:background">@color/light_active_color</item>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ApplicationInitialization.java b/chrome/android/java/src/org/chromium/chrome/browser/ApplicationInitialization.java deleted file mode 100644 index 08b16853..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/ApplicationInitialization.java +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser; - -import android.content.res.Resources; -import android.util.TypedValue; - -import org.chromium.base.CommandLine; -import org.chromium.chrome.R; -import org.chromium.content_public.common.ContentSwitches; - -/** - * Utility class for application level initialization calls. - */ -public final class ApplicationInitialization { - // Prevent instantiation. - private ApplicationInitialization() { - } - - /** - * Enable fullscreen related startup flags. - * @param resources Resources to use while calculating initialization constants. - */ - public static void enableFullscreenFlags(Resources resources) { - CommandLine commandLine = CommandLine.getInstance(); - if (commandLine.hasSwitch(ChromeSwitches.DISABLE_FULLSCREEN)) return; - - TypedValue threshold = new TypedValue(); - resources.getValue(R.dimen.top_controls_show_threshold, threshold, true); - commandLine.appendSwitchWithValue( - ContentSwitches.TOP_CONTROLS_SHOW_THRESHOLD, threshold.coerceToString().toString()); - resources.getValue(R.dimen.top_controls_hide_threshold, threshold, true); - commandLine.appendSwitchWithValue( - ContentSwitches.TOP_CONTROLS_HIDE_THRESHOLD, threshold.coerceToString().toString()); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index b560932..06fe4b1a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -25,6 +25,7 @@ import android.support.annotation.Nullable; import android.util.DisplayMetrics; import android.util.Pair; +import android.util.TypedValue; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -343,7 +344,17 @@ // not go through ChromeLauncherActivity that would have normally triggered this. mPartnerBrowserRefreshNeeded = !PartnerBrowserCustomizations.isInitialized(); - ApplicationInitialization.enableFullscreenFlags(getResources()); + CommandLine commandLine = CommandLine.getInstance(); + if (!commandLine.hasSwitch(ChromeSwitches.DISABLE_FULLSCREEN)) { + TypedValue threshold = new TypedValue(); + getResources().getValue(R.dimen.top_controls_show_threshold, threshold, true); + commandLine.appendSwitchWithValue(ContentSwitches.TOP_CONTROLS_SHOW_THRESHOLD, + threshold.coerceToString().toString()); + getResources().getValue(R.dimen.top_controls_hide_threshold, threshold, true); + commandLine.appendSwitchWithValue(ContentSwitches.TOP_CONTROLS_HIDE_THRESHOLD, + threshold.coerceToString().toString()); + } + getWindow().setBackgroundDrawable(getBackgroundDrawable()); mFullscreenManager = createFullscreenManager();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillUiUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillUiUtils.java index f26e390..2367e1b6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillUiUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillUiUtils.java
@@ -40,7 +40,7 @@ TextView textView = new TextView(context); textView.setText(text); textView.setWidth(width); - TextViewCompat.setTextAppearance(textView, R.style.WhiteBody); + TextViewCompat.setTextAppearance(textView, R.style.TextAppearance_WhiteBody); Resources resources = context.getResources(); int hPadding = resources.getDimensionPixelSize( R.dimen.autofill_card_unmask_tooltip_horizontal_padding);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java index 0b0e792..869f191 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java
@@ -621,9 +621,11 @@ mActivity.getString(R.string.continue_button), ChipStyle.BUTTON_FILLED); continueChip.setOnClickListener(unusedView -> { // Reset UI changes. - ApiCompatibilityUtils.setTextAppearance(mDetailsTitle, R.style.BlackCaptionDefault); + ApiCompatibilityUtils.setTextAppearance( + mDetailsTitle, R.style.TextAppearance_BlackCaptionDefault); mDetailsTitle.setTypeface(mDetailsTitle.getTypeface(), Typeface.BOLD); - ApiCompatibilityUtils.setTextAppearance(mDetailsText, R.style.BlackCaption); + ApiCompatibilityUtils.setTextAppearance( + mDetailsText, R.style.TextAppearance_BlackCaption); clearCarousel(); showStatusMessage(oldMessage); disableProgressBarPulsing();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerToolbar.java index 5c2992df..1bcdfcb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerToolbar.java
@@ -31,8 +31,8 @@ TextView up = (TextView) mNumberRollView.findViewById(R.id.up); TextView down = (TextView) mNumberRollView.findViewById(R.id.down); - ApiCompatibilityUtils.setTextAppearance(up, R.style.BlackHeadline); - ApiCompatibilityUtils.setTextAppearance(down, R.style.BlackHeadline); + ApiCompatibilityUtils.setTextAppearance(up, R.style.TextAppearance_BlackHeadline); + ApiCompatibilityUtils.setTextAppearance(down, R.style.TextAppearance_BlackHeadline); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/filter/chips/Chip.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/filter/chips/Chip.java index e312438..661c962b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/filter/chips/Chip.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/filter/chips/Chip.java
@@ -7,13 +7,15 @@ import android.support.annotation.DrawableRes; import android.support.annotation.StringRes; +import org.chromium.ui.widget.ChipView; + /** * A generic visual representation of a Chip. Most of the visuals are immutable, but the selection * and enable states are not. */ public class Chip { /** An id to use for {@link #icon} when there is no icon on the chip. */ - public static final int INVALID_ICON_ID = -1; + public static final int INVALID_ICON_ID = ChipView.INVALID_ICON_ID; /** An id used to identify this chip. */ public final int id;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/filter/chips/ChipsViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/filter/chips/ChipsViewHolder.java index 56a1019a..91fddda 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/filter/chips/ChipsViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/filter/chips/ChipsViewHolder.java
@@ -3,39 +3,25 @@ // found in the LICENSE file. package org.chromium.chrome.browser.download.home.filter.chips; -import android.content.res.ColorStateList; -import android.support.v4.view.ViewCompat; import android.support.v7.widget.RecyclerView.ViewHolder; -import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; -import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.chrome.R; +import org.chromium.ui.widget.ChipView; /** The {@link ViewHolder} responsible for reflecting a {@link Chip} to a {@link View}. */ public class ChipsViewHolder extends ViewHolder { - private final int mTextStartPaddingWithIconPx; - private final int mTextStartPaddingWithNoIconPx; - - private final TextView mText; - private final ImageView mImage; - /** Builds a ChipsViewHolder around a specific {@link View}. */ private ChipsViewHolder(View itemView) { super(itemView); + } - mText = itemView.findViewById(org.chromium.chrome.R.id.text); - mImage = itemView.findViewById(org.chromium.chrome.R.id.icon); - - ColorStateList textColors = mText.getTextColors(); - if (textColors != null) ApiCompatibilityUtils.setImageTintList(mImage, textColors); - - mTextStartPaddingWithIconPx = mText.getResources().getDimensionPixelSize( - org.chromium.chrome.R.dimen.chip_icon_padding); - mTextStartPaddingWithNoIconPx = mText.getResources().getDimensionPixelSize( - org.chromium.chrome.R.dimen.chip_no_icon_padding); + private ChipView getChipView() { + assert itemView + instanceof ChipView : "ChipViewHolder doesn't hold ChipView but " + + itemView.getClass(); + return (ChipView) itemView; } /** @@ -45,8 +31,8 @@ */ public static ChipsViewHolder create(ViewGroup parent, int viewType) { assert viewType == 0; - return new ChipsViewHolder(LayoutInflater.from(parent.getContext()) - .inflate(org.chromium.chrome.R.layout.chip, null)); + return new ChipsViewHolder( + new ChipView(parent.getContext(), R.style.SuggestionChipThemeOverlay)); } /** @@ -56,26 +42,12 @@ * @see org.chromium.chrome.browser.modelutil.SimpleRecyclerViewMcp.ViewBinder#onBindViewHolder */ public void bind(Chip chip) { - itemView.setEnabled(chip.enabled); - mText.setEnabled(chip.enabled); - mImage.setEnabled(chip.enabled); - - itemView.setSelected(chip.selected); - itemView.setOnClickListener(v -> chip.chipSelectedListener.run()); - mText.setContentDescription(mText.getContext().getText(chip.contentDescription)); - mText.setText(chip.text); - - final int textStartPadding; - if (chip.icon == Chip.INVALID_ICON_ID) { - mImage.setVisibility(ViewGroup.GONE); - textStartPadding = mTextStartPaddingWithNoIconPx; - } else { - textStartPadding = mTextStartPaddingWithIconPx; - mImage.setVisibility(ViewGroup.VISIBLE); - mImage.setImageResource(chip.icon); - } - - ViewCompat.setPaddingRelative(mText, textStartPadding, mText.getPaddingTop(), - ViewCompat.getPaddingEnd(mText), mText.getPaddingBottom()); + getChipView().setEnabled(chip.enabled); + getChipView().setSelected(chip.selected); + getChipView().setOnClickListener(v -> chip.chipSelectedListener.run()); + getChipView().getInnerTextView().setContentDescription( + getChipView().getResources().getString(chip.contentDescription)); + getChipView().getInnerTextView().setText(chip.text); + getChipView().setIcon(chip.icon); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarCompactLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarCompactLayout.java index 5f6877a74..9abf8ba 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarCompactLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarCompactLayout.java
@@ -164,7 +164,8 @@ if (mLink != null) builder.append(" ").append(mLink); TextView prompt = new InfoBarMessageView(mLayout.getContext()); - ApiCompatibilityUtils.setTextAppearance(prompt, R.style.BlackBodyDefault); + ApiCompatibilityUtils.setTextAppearance( + prompt, R.style.TextAppearance_BlackBodyDefault); prompt.setText(builder); prompt.setGravity(Gravity.CENTER_VERTICAL); prompt.setPadding(0, messagePadding, 0, messagePadding);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InstallableAmbientBadgeInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InstallableAmbientBadgeInfoBar.java index c2b696b..39a5e782 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InstallableAmbientBadgeInfoBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InstallableAmbientBadgeInfoBar.java
@@ -50,7 +50,7 @@ Resources res = layout.getResources(); prompt.setText(mMessageText); - ApiCompatibilityUtils.setTextAppearance(prompt, R.style.BlueLink1); + ApiCompatibilityUtils.setTextAppearance(prompt, R.style.TextAppearance_BlueLink1); prompt.setGravity(Gravity.CENTER_VERTICAL); prompt.setOnClickListener(this);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/SurveyInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/SurveyInfoBar.java index 81c6226..1f86c94 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/SurveyInfoBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/SurveyInfoBar.java
@@ -118,7 +118,7 @@ prompt.setText(infoBarText); prompt.setMovementMethod(LinkMovementMethod.getInstance()); prompt.setGravity(Gravity.CENTER_VERTICAL); - ApiCompatibilityUtils.setTextAppearance(prompt, R.style.BlackTitle1); + ApiCompatibilityUtils.setTextAppearance(prompt, R.style.TextAppearance_BlackTitle1); addAccessibilityClickListener(prompt, tab); layout.addContent(prompt, 1f); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/indicator/OfflineIndicatorController.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/indicator/OfflineIndicatorController.java index 3d0f0f4..f0b117da 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/indicator/OfflineIndicatorController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/indicator/OfflineIndicatorController.java
@@ -247,7 +247,7 @@ .setSingleLine(true) .setProfileImage(icon) .setBackgroundColor(Color.BLACK) - .setTextAppearance(R.style.WhiteBody) + .setTextAppearance(R.style.TextAppearance_WhiteBody) .setDuration(SNACKBAR_DURATION_MS) .setAction(chromeActivity.getString( R.string.offline_indicator_view_offline_content),
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/page_info/ConnectionInfoPopup.java b/chrome/android/java/src/org/chromium/chrome/browser/page_info/ConnectionInfoPopup.java index f028822d..1bababd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/page_info/ConnectionInfoPopup.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/page_info/ConnectionInfoPopup.java
@@ -144,7 +144,8 @@ assert mCertificateViewerTextView == null; mCertificateViewerTextView = new TextView(mContext); mCertificateViewerTextView.setText(label); - ApiCompatibilityUtils.setTextAppearance(mCertificateViewerTextView, R.style.BlueLink3); + ApiCompatibilityUtils.setTextAppearance( + mCertificateViewerTextView, R.style.TextAppearance_BlueLink3); mCertificateViewerTextView.setOnClickListener(this); mCertificateViewerTextView.setPadding(0, mPaddingThin, 0, 0); mCertificateLayout.addView(mCertificateViewerTextView); @@ -180,7 +181,7 @@ mMoreInfoLink = new TextView(mContext); mLinkUrl = HELP_URL; mMoreInfoLink.setText(linkText); - ApiCompatibilityUtils.setTextAppearance(mMoreInfoLink, R.style.BlueLink3); + ApiCompatibilityUtils.setTextAppearance(mMoreInfoLink, R.style.TextAppearance_BlueLink3); mMoreInfoLink.setPadding(0, mPaddingThin, 0, 0); mMoreInfoLink.setOnClickListener(this); mDescriptionLayout.addView(mMoreInfoLink);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoController.java b/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoController.java index 6ddaf8c..4214905 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoController.java
@@ -218,8 +218,8 @@ mTab.getProfile(), displayUrlBuilder.toString()); if (emphasizeResponse.schemeLength > 0) { displayUrlBuilder.setSpan( - new TextAppearanceSpan(mContext, R.style.RobotoMediumStyle), 0, - emphasizeResponse.schemeLength, Spannable.SPAN_EXCLUSIVE_INCLUSIVE); + new TextAppearanceSpan(mContext, R.style.TextAppearance_RobotoMediumStyle), + 0, emphasizeResponse.schemeLength, Spannable.SPAN_EXCLUSIVE_INCLUSIVE); } } viewParams.url = displayUrlBuilder;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java index cdef723..b9613d8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java
@@ -342,17 +342,19 @@ // The title is always displayed for the row at the top of the main section. mTitleView = new TextView(getContext()); mTitleView.setText(sectionName); - ApiCompatibilityUtils.setTextAppearance(mTitleView, R.style.BlueLink2); + ApiCompatibilityUtils.setTextAppearance(mTitleView, R.style.TextAppearance_BlueLink2); mainSectionLayout.addView( mTitleView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); // Create the two TextViews for showing the summary text. mSummaryLeftTextView = new TextView(getContext()); mSummaryLeftTextView.setId(R.id.payments_left_summary_label); - ApiCompatibilityUtils.setTextAppearance(mSummaryLeftTextView, R.style.BlackTitle1); + ApiCompatibilityUtils.setTextAppearance( + mSummaryLeftTextView, R.style.TextAppearance_BlackTitle1); mSummaryRightTextView = new TextView(getContext()); - ApiCompatibilityUtils.setTextAppearance(mSummaryRightTextView, R.style.BlackTitle1); + ApiCompatibilityUtils.setTextAppearance( + mSummaryRightTextView, R.style.TextAppearance_BlackTitle1); ApiCompatibilityUtils.setTextAlignment(mSummaryRightTextView, TEXT_ALIGNMENT_TEXT_END); // The main TextView sucks up all the available space. @@ -575,7 +577,8 @@ // Create the view and set the text appearance and layout parameters. mUpdatedView = new TextView(context); - ApiCompatibilityUtils.setTextAppearance(mUpdatedView, R.style.BlackTitle1); + ApiCompatibilityUtils.setTextAppearance( + mUpdatedView, R.style.TextAppearance_BlackTitle1); LinearLayout.LayoutParams updatedLayoutParams = new LinearLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); ApiCompatibilityUtils.setTextAlignment(mUpdatedView, TEXT_ALIGNMENT_TEXT_END); @@ -950,7 +953,8 @@ columnStart = 0; columnSpan = 4; - ApiCompatibilityUtils.setTextAppearance(labelView, R.style.BlackBody); + ApiCompatibilityUtils.setTextAppearance( + labelView, R.style.TextAppearance_BlackBody); } else if (mRowType == OPTION_ROW_TYPE_WARNING) { // Warnings use three columns. columnSpan = 3; @@ -1289,17 +1293,17 @@ // Section summary should be displayed as descriptive text style. if (!mSummaryInDescriptiveText) { ApiCompatibilityUtils.setTextAppearance( - getSummaryLeftTextView(), R.style.BlackBody); + getSummaryLeftTextView(), R.style.TextAppearance_BlackBody); mSummaryInDescriptiveText = true; } SectionUiUtils.showSectionSummaryInTextViewInSingeLine( getContext(), mSectionInformation, getSummaryLeftTextView()); } else { setLogoDrawable(selectedItem.getDrawableIcon()); - // Selected item summary should be displayed as R.style.BlackTitle1. + // Selected item summary should be displayed as R.style.TextAppearance_BlackTitle1. if (mSummaryInDescriptiveText) { ApiCompatibilityUtils.setTextAppearance( - getSummaryLeftTextView(), R.style.BlackTitle1); + getSummaryLeftTextView(), R.style.TextAppearance_BlackTitle1); mSummaryInDescriptiveText = false; } // Split summary in DISPLAY_MODE_NORMAL if caller specified. The first part is
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java index d9477992..4b9a22f8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java
@@ -1029,7 +1029,7 @@ TextView view = new TextViewWithClickableSpans(mContext); view.setText(spannableMessage); view.setMovementMethod(LinkMovementMethod.getInstance()); - ApiCompatibilityUtils.setTextAppearance(view, R.style.BlackBody); + ApiCompatibilityUtils.setTextAppearance(view, R.style.TextAppearance_BlackBody); // Add paddings instead of margin to let getMeasuredHeight return correct value for section // resize animation.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerToolbar.java index 9cb1815..5e294cb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerToolbar.java
@@ -32,8 +32,8 @@ TextView up = (TextView) mNumberRollView.findViewById(R.id.up); TextView down = (TextView) mNumberRollView.findViewById(R.id.down); - ApiCompatibilityUtils.setTextAppearance(up, R.style.BlackHeadline); - ApiCompatibilityUtils.setTextAppearance(down, R.style.BlackHeadline); + ApiCompatibilityUtils.setTextAppearance(up, R.style.TextAppearance_BlackHeadline); + ApiCompatibilityUtils.setTextAppearance(down, R.style.TextAppearance_BlackHeadline); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarView.java b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarView.java index 8d8bbd5..ad54ebf2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarView.java
@@ -249,7 +249,7 @@ int textAppearanceResId = snackbar.getTextAppearance(); if (textAppearanceResId == 0) { - textAppearanceResId = R.style.BlackBodyDefault; + textAppearanceResId = R.style.TextAppearance_BlackBodyDefault; } ApiCompatibilityUtils.setTextAppearance(mMessageView, textAppearanceResId);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/smartlockautosignin/AutoSigninSnackbarController.java b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/smartlockautosignin/AutoSigninSnackbarController.java index 3a65508..ee9eb1c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/smartlockautosignin/AutoSigninSnackbarController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/smartlockautosignin/AutoSigninSnackbarController.java
@@ -48,7 +48,7 @@ snackbar.setSingleLine(false) .setBackgroundColor(backgroundColor) .setProfileImage(icon) - .setTextAppearance(R.style.WhiteBody); + .setTextAppearance(R.style.TextAppearance_WhiteBody); snackbarManager.showSnackbar(snackbar); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BrowsingModeBottomToolbarMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BrowsingModeBottomToolbarMediator.java index 490c9b5..c531357 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BrowsingModeBottomToolbarMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BrowsingModeBottomToolbarMediator.java
@@ -144,9 +144,9 @@ FeatureHighlightProvider.getInstance().buildForView(activity, anchor, R.string.iph_duet_title, FeatureHighlightProvider.TextAlignment.CENTER, - R.style.WhiteTitle1, R.string.iph_duet_description, - FeatureHighlightProvider.TextAlignment.CENTER, R.style.WhiteBody, finalColor, - DUET_IPH_BUBBLE_SHOW_DURATION_MS); + R.style.TextAppearance_WhiteTitle1, R.string.iph_duet_description, + FeatureHighlightProvider.TextAlignment.CENTER, R.style.TextAppearance_WhiteBody, + finalColor, DUET_IPH_BUBBLE_SHOW_DURATION_MS); anchor.postDelayed(() -> tracker.dismissed(FeatureConstants.CHROME_DUET_FEATURE), DUET_IPH_BUBBLE_SHOW_DURATION_MS);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTPhone.java index f48ec777..5da40aa 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTPhone.java
@@ -43,11 +43,11 @@ private IncognitoStateProvider mIncognitoStateProvider; private @Nullable IncognitoToggleTabLayout mIncognitoToggleTabLayout; - private @Nullable ToggleTabStackButton mToggleTabStackButton; - // The following two buttons are not used when Duet is enabled. + // The following three buttons are not used when Duet is enabled. private @Nullable NewTabButton mNewTabButton; private @Nullable MenuButton mMenuButton; + private @Nullable ToggleTabStackButton mToggleTabStackButton; private int mPrimaryColor; private boolean mUseLightIcons; @@ -74,7 +74,16 @@ if (isBottomToolbarEnabled) { UiUtils.removeViewFromParent(mNewTabButton); + mNewTabButton.destroy(); + mNewTabButton = null; + UiUtils.removeViewFromParent(mMenuButton); + mMenuButton.destroy(); + mMenuButton = null; + + UiUtils.removeViewFromParent(mToggleTabStackButton); + mToggleTabStackButton.destroy(); + mToggleTabStackButton = null; } else { // TODO(twellington): Try to make NewTabButton responsible for handling its own clicks. // TabSwitcherBottomToolbarCoordinator also uses NewTabButton and @@ -86,9 +95,7 @@ if (usingHorizontalTabSwitcher() && PrefServiceBridge.getInstance().isIncognitoModeEnabled()) { - inflateIncognitoToggle(); - } else if (isBottomToolbarEnabled) { - removeToggleTabStackButton(); + updateTabSwitchingElements(true); } } @@ -246,11 +253,9 @@ void onAccessibilityStatusChanged(boolean enabled) { if (mNewTabButton != null) mNewTabButton.onAccessibilityStatusChanged(); - if (mIncognitoToggleTabLayout != null) { - mIncognitoToggleTabLayout.setVisibility(enabled ? View.GONE : View.VISIBLE); - } else if (usingHorizontalTabSwitcher() + if (ChromeFeatureList.isEnabled(ChromeFeatureList.HORIZONTAL_TAB_SWITCHER_ANDROID) && PrefServiceBridge.getInstance().isIncognitoModeEnabled()) { - inflateIncognitoToggle(); + updateTabSwitchingElements(!enabled); } updatePrimaryColorAndTint(); @@ -316,15 +321,23 @@ if (mTabModelSelector != null) { mIncognitoToggleTabLayout.setTabModelSelector(mTabModelSelector); } - - removeToggleTabStackButton(); } - private void removeToggleTabStackButton() { - if (mToggleTabStackButton == null) return; + private void setIncognitoToggleVisibility(boolean showIncognitoToggle) { + if (mIncognitoToggleTabLayout == null) { + if (showIncognitoToggle) inflateIncognitoToggle(); + } else { + mIncognitoToggleTabLayout.setVisibility(showIncognitoToggle ? View.VISIBLE : View.GONE); + } + } - UiUtils.removeViewFromParent(mToggleTabStackButton); - mToggleTabStackButton.destroy(); - mToggleTabStackButton = null; + private void setToggleTabStackButtonVisibility(boolean showToggleTabStackButton) { + if (mToggleTabStackButton == null) return; + mToggleTabStackButton.setVisibility(showToggleTabStackButton ? View.VISIBLE : View.GONE); + } + + private void updateTabSwitchingElements(boolean showIncognitoToggle) { + setIncognitoToggleVisibility(showIncognitoToggle); + setToggleTabStackButtonVisibility(!showIncognitoToggle); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/DualControlLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/DualControlLayout.java index 8024a6cf..d6d946a3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/DualControlLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/DualControlLayout.java
@@ -76,7 +76,8 @@ secondaryButton.setId(R.id.button_secondary); secondaryButton.setOnClickListener(listener); secondaryButton.setText(text); - ApiCompatibilityUtils.setTextAppearance(secondaryButton, R.style.BlueButtonText2); + ApiCompatibilityUtils.setTextAppearance( + secondaryButton, R.style.TextAppearance_BlueButtonText2); return secondaryButton; } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/accessibility/AccessibilityTabModelListItem.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/accessibility/AccessibilityTabModelListItem.java index f68d6d3..5d19dc0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/accessibility/AccessibilityTabModelListItem.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/accessibility/AccessibilityTabModelListItem.java
@@ -309,14 +309,16 @@ if (mTab.isIncognito()) { setBackgroundResource(R.color.incognito_modern_primary_color); mFaviconView.getBackground().setLevel(mIncognitoLevel); - ApiCompatibilityUtils.setTextAppearance(mTitleView, R.style.WhiteTitle1); - ApiCompatibilityUtils.setTextAppearance(mDescriptionView, R.style.WhiteBody); + ApiCompatibilityUtils.setTextAppearance(mTitleView, R.style.TextAppearance_WhiteTitle1); + ApiCompatibilityUtils.setTextAppearance( + mDescriptionView, R.style.TextAppearance_WhiteBody); ApiCompatibilityUtils.setImageTintList(mCloseButton, mLightCloseIconColor); } else { setBackgroundResource(R.color.modern_primary_color); mFaviconView.getBackground().setLevel(mDefaultLevel); - ApiCompatibilityUtils.setTextAppearance(mTitleView, R.style.BlackTitle1); - ApiCompatibilityUtils.setTextAppearance(mDescriptionView, R.style.BlackBody); + ApiCompatibilityUtils.setTextAppearance(mTitleView, R.style.TextAppearance_BlackTitle1); + ApiCompatibilityUtils.setTextAppearance( + mDescriptionView, R.style.TextAppearance_BlackBody); ApiCompatibilityUtils.setImageTintList(mCloseButton, mDarkCloseIconColor); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/EditorDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/EditorDialog.java index 3efd1b02..8ff6d94 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/EditorDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/EditorDialog.java
@@ -189,7 +189,7 @@ EditorDialogToolbar toolbar = (EditorDialogToolbar) mLayout.findViewById(R.id.action_bar); toolbar.setBackgroundColor(ApiCompatibilityUtils.getColor( toolbar.getResources(), R.color.modern_primary_color)); - toolbar.setTitleTextAppearance(toolbar.getContext(), R.style.BlackHeadline); + toolbar.setTitleTextAppearance(toolbar.getContext(), R.style.TextAppearance_BlackHeadline); toolbar.setTitle(mEditorModel.getTitle()); toolbar.setShowDeleteMenuItem(mDeleteRunnable != null);
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 52c084bc..530b0ad2 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -18,7 +18,6 @@ "java/src/org/chromium/chrome/browser/AppHooks.java", "java/src/org/chromium/chrome/browser/AppHooksModule.java", "java/src/org/chromium/chrome/browser/AppIndexingUtil.java", - "java/src/org/chromium/chrome/browser/ApplicationInitialization.java", "java/src/org/chromium/chrome/browser/ApplicationLifetime.java", "java/src/org/chromium/chrome/browser/AssistStatusHandler.java", "java/src/org/chromium/chrome/browser/BackgroundSyncLauncher.java",
diff --git a/chrome/browser/apps/platform_apps/api/webstore_widget_private/app_installer.cc b/chrome/browser/apps/platform_apps/api/webstore_widget_private/app_installer.cc index 5d51766..ec12fab 100644 --- a/chrome/browser/apps/platform_apps/api/webstore_widget_private/app_installer.cc +++ b/chrome/browser/apps/platform_apps/api/webstore_widget_private/app_installer.cc
@@ -36,10 +36,11 @@ const std::string& item_id, Profile* profile, bool silent_installation, - const Callback& callback) - : extensions::WebstoreStandaloneInstaller(item_id, profile, callback), + Callback callback) + : extensions::WebstoreStandaloneInstaller(item_id, + profile, + std::move(callback)), silent_installation_(silent_installation), - callback_(callback), web_contents_(web_contents), web_contents_observer_(new WebContentsObserver(web_contents, this)) { DCHECK(web_contents_); @@ -79,8 +80,8 @@ } void AppInstaller::OnWebContentsDestroyed(content::WebContents* web_contents) { - callback_.Run(false, kWebContentsDestroyedError, - extensions::webstore_install::OTHER_ERROR); + RunCallback(false, kWebContentsDestroyedError, + extensions::webstore_install::OTHER_ERROR); AbortInstall(); }
diff --git a/chrome/browser/apps/platform_apps/api/webstore_widget_private/app_installer.h b/chrome/browser/apps/platform_apps/api/webstore_widget_private/app_installer.h index a2d6188..71f2fc3 100644 --- a/chrome/browser/apps/platform_apps/api/webstore_widget_private/app_installer.h +++ b/chrome/browser/apps/platform_apps/api/webstore_widget_private/app_installer.h
@@ -26,7 +26,7 @@ const std::string& item_id, Profile* profile, bool silent_installation, - const Callback& callback); + Callback callback); protected: friend class base::RefCountedThreadSafe<AppInstaller>; @@ -47,7 +47,6 @@ class WebContentsObserver; bool silent_installation_; - Callback callback_; content::WebContents* web_contents_; std::unique_ptr<WebContentsObserver> web_contents_observer_;
diff --git a/chrome/browser/apps/platform_apps/api/webstore_widget_private/webstore_widget_private_api.cc b/chrome/browser/apps/platform_apps/api/webstore_widget_private/webstore_widget_private_api.cc index da79b489..d59020fe 100644 --- a/chrome/browser/apps/platform_apps/api/webstore_widget_private/webstore_widget_private_api.cc +++ b/chrome/browser/apps/platform_apps/api/webstore_widget_private/webstore_widget_private_api.cc
@@ -7,6 +7,7 @@ #include <memory> #include <utility> +#include "base/bind.h" #include "chrome/browser/apps/platform_apps/api/webstore_widget_private/app_installer.h" #include "chrome/browser/chromeos/file_manager/app_id.h" #include "chrome/browser/profiles/profile.h" @@ -44,20 +45,19 @@ if (params->silent_installation && !allow_silent_install) return RespondNow(Error("Silent installation not allowed.")); - const extensions::WebstoreStandaloneInstaller::Callback callback = base::Bind( - &WebstoreWidgetPrivateInstallWebstoreItemFunction::OnInstallComplete, - this); - content::WebContents* web_contents = GetSenderWebContents(); if (!web_contents) { return RespondNow( Error(extensions::function_constants::kCouldNotFindSenderWebContents)); } - scoped_refptr<webstore_widget::AppInstaller> installer( - new webstore_widget::AppInstaller( - web_contents, params->item_id, - Profile::FromBrowserContext(browser_context()), - params->silent_installation, callback)); + + auto installer = base::MakeRefCounted<webstore_widget::AppInstaller>( + web_contents, params->item_id, + Profile::FromBrowserContext(browser_context()), + params->silent_installation, + base::BindOnce( + &WebstoreWidgetPrivateInstallWebstoreItemFunction::OnInstallComplete, + this)); // installer will be AddRef()'d in BeginInstall(). installer->BeginInstall();
diff --git a/chrome/browser/background_fetch/background_fetch_browsertest.cc b/chrome/browser/background_fetch/background_fetch_browsertest.cc index 635d792..f04fcef 100644 --- a/chrome/browser/background_fetch/background_fetch_browsertest.cc +++ b/chrome/browser/background_fetch/background_fetch_browsertest.cc
@@ -707,6 +707,9 @@ FetchesRunToCompletionAndUpdateTitle_Fetched) { ASSERT_NO_FATAL_FAILURE(RunScriptAndCheckResultingMessage( "RunFetchTillCompletion()", "backgroundfetchsuccess")); + EXPECT_EQ(offline_content_provider_observer_->latest_item().state, + offline_items_collection::OfflineItemState::COMPLETE); + base::RunLoop().RunUntilIdle(); // Give `updateUI` a chance to propagate. EXPECT_TRUE( base::StartsWith(offline_content_provider_observer_->latest_item().title, @@ -720,6 +723,9 @@ FetchesRunToCompletionAndUpdateTitle_Failed) { ASSERT_NO_FATAL_FAILURE(RunScriptAndCheckResultingMessage( "RunFetchTillCompletionWithMissingResource()", "backgroundfetchfail")); + EXPECT_EQ(offline_content_provider_observer_->latest_item().state, + offline_items_collection::OfflineItemState::COMPLETE); + base::RunLoop().RunUntilIdle(); // Give `updateUI` a chance to propagate. EXPECT_TRUE( base::StartsWith(offline_content_provider_observer_->latest_item().title,
diff --git a/chrome/browser/background_fetch/background_fetch_delegate_impl.cc b/chrome/browser/background_fetch/background_fetch_delegate_impl.cc index 6bc6ece..159212b 100644 --- a/chrome/browser/background_fetch/background_fetch_delegate_impl.cc +++ b/chrome/browser/background_fetch/background_fetch_delegate_impl.cc
@@ -108,6 +108,13 @@ job_state = State::kStartedButPaused; } +void BackgroundFetchDelegateImpl::JobDetails::UpdateJobOnDownloadComplete() { + fetch_description->completed_parts++; + in_progress_parts_size = 0u; + if (fetch_description->completed_parts == fetch_description->total_parts) + job_state = State::kDownloadsComplete; +} + void BackgroundFetchDelegateImpl::JobDetails::UpdateOfflineItem() { DCHECK_GT(fetch_description->total_parts, 0); @@ -116,10 +123,9 @@ // If we have completed all downloads, update progress max to // completed_parts_size in case total_parts_size was set too high. This // avoid unnecessary jumping in the progress bar. - offline_item.progress.max = - (fetch_description->completed_parts == fetch_description->total_parts) - ? fetch_description->completed_parts_size - : fetch_description->total_parts_size; + offline_item.progress.max = job_state == State::kDownloadsComplete + ? fetch_description->completed_parts_size + : fetch_description->total_parts_size; } else { offline_item.progress.value = fetch_description->completed_parts; offline_item.progress.max = fetch_description->total_parts; @@ -134,19 +140,22 @@ offline_item.is_resumable = true; using OfflineItemState = offline_items_collection::OfflineItemState; - if (job_state == State::kCancelled) { - offline_item.state = OfflineItemState::CANCELLED; - } else if (fetch_description->completed_parts == - fetch_description->total_parts) { - // This includes cases when the download failed, or completed but the - // response was an HTTP error, e.g. 404. - offline_item.state = OfflineItemState::COMPLETE; - offline_item.is_openable = true; - } else if (job_state == State::kPendingWillStartPaused || - job_state == State::kStartedButPaused) { - offline_item.state = OfflineItemState::PAUSED; - } else { - offline_item.state = OfflineItemState::IN_PROGRESS; + switch (job_state) { + case State::kCancelled: + offline_item.state = OfflineItemState::CANCELLED; + break; + case State::kDownloadsComplete: + // This includes cases when the download failed, or completed but the + // response was an HTTP error, e.g. 404. + offline_item.state = OfflineItemState::COMPLETE; + offline_item.is_openable = true; + break; + case State::kPendingWillStartPaused: + case State::kStartedButPaused: + offline_item.state = OfflineItemState::PAUSED; + break; + default: + offline_item.state = OfflineItemState::IN_PROGRESS; } } @@ -361,6 +370,17 @@ job_details.offline_item.refresh_visuals = true; } + bool should_update_visuals = job_details.offline_item.refresh_visuals; +#if !defined(OS_ANDROID) + should_update_visuals = false; +#endif + + if (!should_update_visuals) { + // Notify the client that the UI updates have been handed over. + if (job_details.client) + job_details.client->OnUIUpdated(job_unique_id); + } + UpdateOfflineItemAndUpdateObservers(&job_details); } @@ -438,9 +458,8 @@ const std::string& job_unique_id = download_job_unique_id_iter->second; JobDetails& job_details = job_details_map_.find(job_unique_id)->second; - ++job_details.fetch_description->completed_parts; - job_details.in_progress_parts_size = 0u; + job_details.UpdateJobOnDownloadComplete(); UpdateOfflineItemAndUpdateObservers(&job_details); // The client cancelled or aborted the download so no need to notify it. @@ -472,8 +491,7 @@ const std::string& job_unique_id = download_job_unique_id_iter->second; JobDetails& job_details = job_details_map_.find(job_unique_id)->second; - ++job_details.fetch_description->completed_parts; - job_details.in_progress_parts_size = 0u; + job_details.UpdateJobOnDownloadComplete(); job_details.fetch_description->completed_parts_size += profile_->IsOffTheRecord() ? result->blob_handle->size() @@ -633,9 +651,14 @@ std::make_unique<offline_items_collection::OfflineItemVisuals>(); auto it = job_details_map_.find(id.id); if (it != job_details_map_.end()) { + auto& job_details = it->second; visuals->icon = - gfx::Image::CreateFrom1xBitmap(it->second.fetch_description->icon); - it->second.offline_item.refresh_visuals = false; + gfx::Image::CreateFrom1xBitmap(job_details.fetch_description->icon); + job_details.offline_item.refresh_visuals = false; + if (job_details.client && + job_details.job_state == JobDetails::State::kDownloadsComplete) { + job_details.client->OnUIUpdated(id.id); + } } base::ThreadTaskRunnerHandle::Get()->PostTask(
diff --git a/chrome/browser/background_fetch/background_fetch_delegate_impl.h b/chrome/browser/background_fetch/background_fetch_delegate_impl.h index e541d80..af12951 100644 --- a/chrome/browser/background_fetch/background_fetch_delegate_impl.h +++ b/chrome/browser/background_fetch/background_fetch_delegate_impl.h
@@ -142,7 +142,10 @@ kPendingWillStartDownloading, kStartedButPaused, kStartedAndDownloading, + // The job was aborted. kCancelled, + // All requests were processed (either succeeded or failed). + kDownloadsComplete, }; JobDetails(JobDetails&&); @@ -155,6 +158,7 @@ void UpdateOfflineItem(); void MarkJobAsStarted(); + void UpdateJobOnDownloadComplete(); // Returns how many bytes have been processed by the Download Service so // far.
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 06f6a71..cb670fd 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -247,6 +247,8 @@ <include name="IDR_APP_MANAGEMENT_ITEM_JS" file="resources\app_management\item.js" type="BINDATA" /> <include name="IDR_APP_MANAGEMENT_MAIN_VIEW_HTML" file="resources\app_management\main_view.html" type="BINDATA" /> <include name="IDR_APP_MANAGEMENT_MAIN_VIEW_JS" file="resources\app_management\main_view.js" type="BINDATA" /> + <include name="IDR_APP_MANAGEMENT_PERMISSION_VIEW_HEADER_HTML" file="resources\app_management\permission_view_header.html" type="BINDATA"/> + <include name="IDR_APP_MANAGEMENT_PERMISSION_VIEW_HEADER_JS" file="resources\app_management\permission_view_header.js" type="BINDATA"/> <include name="IDR_APP_MANAGEMENT_METADATA_VIEW_HTML" file="resources\app_management\metadata_view.html" type="BINDATA" /> <include name="IDR_APP_MANAGEMENT_METADATA_VIEW_JS" file="resources\app_management\metadata_view.js" type="BINDATA" /> <include name="IDR_APP_MANAGEMENT_PERMISSION_ITEM_HTML" file="resources\app_management\permission_item.html" type="BINDATA"/>
diff --git a/chrome/browser/chromeos/crostini/crostini_manager.cc b/chrome/browser/chromeos/crostini/crostini_manager.cc index 2c59762e..4c45ccd85 100644 --- a/chrome/browser/chromeos/crostini/crostini_manager.cc +++ b/chrome/browser/chromeos/crostini/crostini_manager.cc
@@ -89,13 +89,11 @@ base::WeakPtr<CrostiniManager> crostini_manager, std::string vm_name, std::string container_name, - std::string container_username, CrostiniManager::RestartCrostiniCallback callback) : profile_(profile), crostini_manager_(crostini_manager), vm_name_(std::move(vm_name)), container_name_(std::move(container_name)), - container_username_(std::move(container_username)), callback_(std::move(callback)), restart_id_(next_restart_id_++) {} @@ -303,7 +301,7 @@ return; } crostini_manager_->SetUpLxdContainerUser( - vm_name_, container_name_, container_username_, + vm_name_, container_name_, DefaultContainerUserNameForProfile(profile_), base::BindOnce(&CrostiniRestarter::SetUpLxdContainerUserFinished, this)); } @@ -324,18 +322,21 @@ // If default termina/penguin, then do sshfs mount and reshare folders, // else we are finished. + auto info = crostini_manager_->GetContainerInfo(vm_name_, container_name_); if (vm_name_ == kCrostiniDefaultVmName && - container_name_ == kCrostiniDefaultContainerName) { + container_name_ == kCrostiniDefaultContainerName && info && + !info->sshfs_mounted) { crostini_manager_->GetContainerSshKeys( vm_name_, container_name_, - base::BindOnce(&CrostiniRestarter::GetContainerSshKeysFinished, - this)); + base::BindOnce(&CrostiniRestarter::GetContainerSshKeysFinished, this, + info->username)); } else { FinishRestart(result); } } - void GetContainerSshKeysFinished(crostini::CrostiniResult result, + void GetContainerSshKeysFinished(const std::string& container_username, + crostini::CrostiniResult result, const std::string& container_public_key, const std::string& host_private_key, const std::string& hostname) { @@ -358,7 +359,7 @@ // Call to sshfs to mount. source_path_ = base::StringPrintf( - "sshfs://%s@%s:", container_username_.c_str(), hostname.c_str()); + "sshfs://%s@%s:", container_username.c_str(), hostname.c_str()); dmgr->MountPath(source_path_, "", file_manager::util::GetCrostiniMountPointName(profile_), file_manager::util::GetCrostiniMountOptions( @@ -388,6 +389,8 @@ << ", mount_type=" << mount_info.mount_type << ", mount_condition=" << mount_info.mount_condition; } else { + crostini_manager_->SetContainerSshfsMounted(vm_name_, container_name_); + // Register filesystem and add volume to VolumeManager. base::FilePath mount_path = base::FilePath(mount_info.mount_path); storage::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem( @@ -415,7 +418,6 @@ std::string vm_name_; std::string container_name_; - std::string container_username_; std::string source_path_; CrostiniManager::RestartCrostiniCallback callback_; base::ObserverList<CrostiniManager::RestartObserver>::Unchecked @@ -437,7 +439,7 @@ void CrostiniManager::SetVmState(std::string vm_name, VmState vm_state) { auto vm_info = running_vms_.find(std::move(vm_name)); if (vm_info != running_vms_.end()) { - vm_info->second.first = vm_state; + vm_info->second.state = vm_state; return; } // This can happen normally when StopVm is called right after start up. @@ -447,43 +449,62 @@ bool CrostiniManager::IsVmRunning(std::string vm_name) { auto vm_info = running_vms_.find(std::move(vm_name)); if (vm_info != running_vms_.end()) { - return vm_info->second.first == VmState::STARTED; + return vm_info->second.state == VmState::STARTED; } return false; } -base::Optional<vm_tools::concierge::VmInfo> CrostiniManager::GetVmInfo( - std::string vm_name) { +base::Optional<VmInfo> CrostiniManager::GetVmInfo(std::string vm_name) { auto it = running_vms_.find(std::move(vm_name)); if (it != running_vms_.end()) - return it->second.second; + return it->second; return base::nullopt; } -void CrostiniManager::AddRunningVmForTesting( - std::string vm_name, - vm_tools::concierge::VmInfo vm_info) { - running_vms_[std::move(vm_name)] = - std::make_pair(VmState::STARTED, std::move(vm_info)); +void CrostiniManager::AddRunningVmForTesting(std::string vm_name) { + running_vms_[std::move(vm_name)] = VmInfo{VmState::STARTED}; } LinuxPackageInfo::LinuxPackageInfo() = default; LinuxPackageInfo::~LinuxPackageInfo() = default; -bool CrostiniManager::IsContainerRunning(std::string vm_name, - std::string container_name) { - if (!IsVmRunning(vm_name)) { - return false; - } - // TODO(jopra): Ensure the container not marked running if the vm is not - // running. +ContainerInfo::ContainerInfo(std::string container_name, + std::string container_username, + std::string container_homedir) + : name(container_name), + username(container_username), + homedir(container_homedir) {} +ContainerInfo::~ContainerInfo() = default; +ContainerInfo::ContainerInfo(const ContainerInfo&) = default; + +void CrostiniManager::SetContainerSshfsMounted(std::string vm_name, + std::string container_name) { auto range = running_containers_.equal_range(std::move(vm_name)); for (auto it = range.first; it != range.second; ++it) { - if (it->second == container_name) { - return true; + if (it->second.name == container_name) { + it->second.sshfs_mounted = true; } } - return false; +} + +base::Optional<ContainerInfo> CrostiniManager::GetContainerInfo( + std::string vm_name, + std::string container_name) { + if (!IsVmRunning(vm_name)) { + return base::nullopt; + } + auto range = running_containers_.equal_range(std::move(vm_name)); + for (auto it = range.first; it != range.second; ++it) { + if (it->second.name == container_name) { + return it->second; + } + } + return base::nullopt; +} + +void CrostiniManager::AddRunningContainerForTesting(std::string vm_name, + ContainerInfo info) { + running_containers_.emplace(std::move(vm_name), info); } void CrostiniManager::UpdateLaunchMetricsForEnterpriseReporting() { @@ -1146,8 +1167,7 @@ auto restarter = base::MakeRefCounted<CrostiniRestarter>( profile_, weak_ptr_factory_.GetWeakPtr(), std::move(vm_name), - std::move(container_name), ContainerUserNameForProfile(profile_), - std::move(callback)); + std::move(container_name), std::move(callback)); if (observer) restarter->AddObserver(observer); auto key = std::make_pair(restarter->vm_name(), restarter->container_name()); @@ -1316,7 +1336,7 @@ // If the vm is already marked "running" run the callback. if (response.status() == vm_tools::concierge::VM_STATUS_RUNNING) { running_vms_[vm_name] = - std::make_pair(VmState::STARTED, std::move(response.vm_info())); + VmInfo{VmState::STARTED, std::move(response.vm_info())}; std::move(callback).Run(CrostiniResult::SUCCESS); return; } @@ -1327,7 +1347,7 @@ VLOG(1) << "Awaiting TremplinStartedSignal for " << owner_id_ << ", " << vm_name; running_vms_[vm_name] = - std::make_pair(VmState::STARTING, std::move(response.vm_info())); + VmInfo{VmState::STARTING, std::move(response.vm_info())}; // If we thought a container was running for this VM, we're wrong. This can // happen if the vm was formerly running, then stopped via crosh. running_containers_.erase(vm_name); @@ -1391,6 +1411,10 @@ const vm_tools::cicerone::ContainerStartedSignal& signal) { if (signal.owner_id() != owner_id_) return; + running_containers_.emplace( + signal.vm_name(), + ContainerInfo(signal.container_name(), signal.container_username(), + signal.container_homedir())); // Find the callbacks to call, then erase them from the map. auto range = start_container_callbacks_.equal_range( std::make_tuple(signal.vm_name(), signal.container_name())); @@ -1398,7 +1422,6 @@ std::move(it->second).Run(CrostiniResult::SUCCESS); } start_container_callbacks_.erase(range.first, range.second); - running_containers_.emplace(signal.vm_name(), signal.container_name()); } void CrostiniManager::OnContainerStartupFailed( @@ -1419,12 +1442,22 @@ if (signal.owner_id() != owner_id_) return; // Find the callbacks to call, then erase them from the map. - auto range = shutdown_container_callbacks_.equal_range( + auto range_callbacks = shutdown_container_callbacks_.equal_range( std::make_tuple(signal.vm_name(), signal.container_name())); - for (auto it = range.first; it != range.second; ++it) { + for (auto it = range_callbacks.first; it != range_callbacks.second; ++it) { std::move(it->second).Run(); } - shutdown_container_callbacks_.erase(range.first, range.second); + shutdown_container_callbacks_.erase(range_callbacks.first, + range_callbacks.second); + + // Remove from running containers multimap. + auto range_containers = running_containers_.equal_range(signal.vm_name()); + for (auto it = range_containers.first; it != range_containers.second; ++it) { + if (it->second.name == signal.container_name()) { + running_containers_.erase(it); + break; + } + } } void CrostiniManager::OnInstallLinuxPackageProgress( @@ -1604,7 +1637,7 @@ return; } - if (!IsContainerRunning(vm_name, container_name)) { + if (!GetContainerInfo(vm_name, container_name)) { start_container_callbacks_.emplace(std::make_tuple(vm_name, container_name), std::move(callback)); return;
diff --git a/chrome/browser/chromeos/crostini/crostini_manager.h b/chrome/browser/chromeos/crostini/crostini_manager.h index dbba332..6bc25f7 100644 --- a/chrome/browser/chromeos/crostini/crostini_manager.h +++ b/chrome/browser/chromeos/crostini/crostini_manager.h
@@ -74,6 +74,22 @@ UNINSTALLING, // In progress }; +struct VmInfo { + VmState state; + vm_tools::concierge::VmInfo info; +}; + +struct ContainerInfo { + ContainerInfo(std::string name, std::string username, std::string homedir); + ~ContainerInfo(); + ContainerInfo(const ContainerInfo&); + + std::string name; + std::string username; + base::FilePath homedir; + bool sshfs_mounted = false; +}; + // Return type when getting app icons from within a container. struct Icon { std::string desktop_file_id; @@ -429,12 +445,16 @@ void SetVmState(std::string vm_name, VmState vm_state); bool IsVmRunning(std::string vm_name); - // Returns null if VM is not running. - base::Optional<vm_tools::concierge::VmInfo> GetVmInfo(std::string vm_name); - void AddRunningVmForTesting(std::string vm_name, - vm_tools::concierge::VmInfo vm_info); - bool IsContainerRunning(std::string vm_name, std::string container_name); + base::Optional<VmInfo> GetVmInfo(std::string vm_name); + void AddRunningVmForTesting(std::string vm_name); + + void SetContainerSshfsMounted(std::string vm_name, + std::string container_name); + // Returns null if VM or container is not running. + base::Optional<ContainerInfo> GetContainerInfo(std::string vm_name, + std::string container_name); + void AddRunningContainerForTesting(std::string vm_name, ContainerInfo info); // If the Crostini reporting policy is set, save the last app launch // time window and the Termina version in prefs for asynchronous reporting. @@ -612,11 +632,10 @@ // start. std::multimap<std::string, base::OnceClosure> tremplin_started_callbacks_; - std::map<std::string, std::pair<VmState, vm_tools::concierge::VmInfo>> - running_vms_; + std::map<std::string, VmInfo> running_vms_; // Running containers as keyed by vm name. - std::multimap<std::string, std::string> running_containers_; + std::multimap<std::string, ContainerInfo> running_containers_; std::vector<RemoveCrostiniCallback> remove_crostini_callbacks_;
diff --git a/chrome/browser/chromeos/crostini/crostini_manager_unittest.cc b/chrome/browser/chromeos/crostini/crostini_manager_unittest.cc index abb6520..d491a28 100644 --- a/chrome/browser/chromeos/crostini/crostini_manager_unittest.cc +++ b/chrome/browser/chromeos/crostini/crostini_manager_unittest.cc
@@ -715,6 +715,10 @@ EXPECT_TRUE(fake_concierge_client_->create_disk_image_called()); EXPECT_TRUE(fake_concierge_client_->start_termina_vm_called()); EXPECT_TRUE(fake_concierge_client_->get_container_ssh_keys_called()); + EXPECT_TRUE(crostini_manager() + ->GetContainerInfo(kCrostiniDefaultVmName, + kCrostiniDefaultContainerName) + ->sshfs_mounted); EXPECT_EQ(1, restart_crostini_callback_count_); base::FilePath path; EXPECT_TRUE( @@ -741,7 +745,7 @@ EXPECT_EQ(1, restart_crostini_callback_count_); EXPECT_TRUE(crostini_manager()->IsVmRunning(kVmName)); - EXPECT_TRUE(crostini_manager()->IsContainerRunning(kVmName, kContainerName)); + EXPECT_TRUE(crostini_manager()->GetContainerInfo(kVmName, kContainerName)); // Now call StartTerminaVm again. The default response state is "STARTING", // so no container should be considered running. @@ -754,7 +758,7 @@ base::Unretained(this), run_loop2.QuitClosure())); run_loop2.Run(); EXPECT_TRUE(crostini_manager()->IsVmRunning(kVmName)); - EXPECT_FALSE(crostini_manager()->IsContainerRunning(kVmName, kContainerName)); + EXPECT_FALSE(crostini_manager()->GetContainerInfo(kVmName, kContainerName)); } } // namespace crostini
diff --git a/chrome/browser/chromeos/crostini/crostini_share_path.cc b/chrome/browser/chromeos/crostini/crostini_share_path.cc index 985557c2..7823272 100644 --- a/chrome/browser/chromeos/crostini/crostini_share_path.cc +++ b/chrome/browser/chromeos/crostini/crostini_share_path.cc
@@ -48,13 +48,13 @@ vm_tools::seneschal::SharePathRequest request, crostini::CrostiniResult result) { auto* crostini_manager = crostini::CrostiniManager::GetForProfile(profile); - base::Optional<vm_tools::concierge::VmInfo> vm_info = + base::Optional<crostini::VmInfo> vm_info = crostini_manager->GetVmInfo(std::move(vm_name)); - if (!vm_info) { + if (!vm_info || vm_info->state != crostini::VmState::STARTED) { std::move(callback).Run(false, "VM could not be started"); return; } - request.set_handle(vm_info->seneschal_server_handle()); + request.set_handle(vm_info->info.seneschal_server_handle()); chromeos::DBusThreadManager::Get()->GetSeneschalClient()->SharePath( request, base::BindOnce(&OnSeneschalSharePathResponse, std::move(callback))); @@ -240,9 +240,9 @@ // Restart VM if not currently running. auto* crostini_manager = crostini::CrostiniManager::GetForProfile(profile_); - base::Optional<vm_tools::concierge::VmInfo> vm_info = + base::Optional<crostini::VmInfo> vm_info = crostini_manager->GetVmInfo(vm_name); - if (!vm_info) { + if (!vm_info || vm_info->state != crostini::VmState::STARTED) { crostini_manager->RestartCrostini( vm_name, crostini::kCrostiniDefaultContainerName, base::BindOnce(&OnVmRestartedForSeneschal, profile_, std::move(vm_name), @@ -251,7 +251,7 @@ return; } - request.set_handle(vm_info->seneschal_server_handle()); + request.set_handle(vm_info->info.seneschal_server_handle()); chromeos::DBusThreadManager::Get()->GetSeneschalClient()->SharePath( request, base::BindOnce(&OnSeneschalSharePathResponse, std::move(callback))); @@ -263,9 +263,9 @@ base::OnceCallback<void(bool, std::string)> callback) { // Return success if VM is not currently running. auto* crostini_manager = crostini::CrostiniManager::GetForProfile(profile_); - base::Optional<vm_tools::concierge::VmInfo> vm_info = - crostini_manager->GetVmInfo(vm_name); - if (!vm_info) { + base::Optional<crostini::VmInfo> vm_info = + crostini_manager->GetVmInfo(std::move(vm_name)); + if (!vm_info || vm_info->state != crostini::VmState::STARTED) { std::move(callback).Run(true, "VM not running"); return; } @@ -292,7 +292,7 @@ } vm_tools::seneschal::UnsharePathRequest request; - request.set_handle(vm_info->seneschal_server_handle()); + request.set_handle(vm_info->info.seneschal_server_handle()); request.set_path(unshare_path.value()); chromeos::DBusThreadManager::Get()->GetSeneschalClient()->UnsharePath( request,
diff --git a/chrome/browser/chromeos/crostini/crostini_share_path_unittest.cc b/chrome/browser/chromeos/crostini/crostini_share_path_unittest.cc index 5fbe07d..4e246dc 100644 --- a/chrome/browser/chromeos/crostini/crostini_share_path_unittest.cc +++ b/chrome/browser/chromeos/crostini/crostini_share_path_unittest.cc
@@ -208,9 +208,8 @@ volume_downloads_ = file_manager::Volume::CreateForDownloads(downloads_); // Create 'vm-running' VM instance which is running. - vm_tools::concierge::VmInfo vm_info; CrostiniManager::GetForProfile(profile())->AddRunningVmForTesting( - "vm-running", vm_info); + "vm-running"); } void TearDown() override { @@ -499,9 +498,8 @@ features_.InitAndEnableFeature(chromeos::features::kCrostiniFiles); base::FilePath share_path2_ = downloads_.AppendASCII("path-to-share-2"); ASSERT_TRUE(base::CreateDirectory(share_path2_)); - vm_tools::concierge::VmInfo vm_info; CrostiniManager::GetForProfile(profile())->AddRunningVmForTesting( - kCrostiniDefaultVmName, vm_info); + kCrostiniDefaultVmName); base::ListValue shared_paths = base::ListValue(); shared_paths.GetList().push_back(base::Value(share_path_.value())); shared_paths.GetList().push_back(base::Value(share_path2_.value())); @@ -695,9 +693,8 @@ TEST_F(CrostiniSharePathTest, ShareOnMountSuccessParentMount) { features_.InitAndEnableFeature(chromeos::features::kCrostiniFiles); - vm_tools::concierge::VmInfo vm_info; CrostiniManager::GetForProfile(profile())->AddRunningVmForTesting( - kCrostiniDefaultVmName, vm_info); + kCrostiniDefaultVmName); crostini_share_path_->SetMountEventSeneschalCallbackForTesting( base::BindRepeating(&CrostiniSharePathTest::MountEventSharePathCallback, base::Unretained(this), "share-on-mount", @@ -711,9 +708,8 @@ TEST_F(CrostiniSharePathTest, ShareOnMountSuccessSelfMount) { features_.InitAndEnableFeature(chromeos::features::kCrostiniFiles); - vm_tools::concierge::VmInfo vm_info; CrostiniManager::GetForProfile(profile())->AddRunningVmForTesting( - kCrostiniDefaultVmName, vm_info); + kCrostiniDefaultVmName); auto volume_shared_path = file_manager::Volume::CreateForDownloads(shared_path_); crostini_share_path_->SetMountEventSeneschalCallbackForTesting( @@ -729,9 +725,8 @@ TEST_F(CrostiniSharePathTest, ShareOnMountFeatureNotEnabled) { features_.InitAndDisableFeature(chromeos::features::kCrostiniFiles); - vm_tools::concierge::VmInfo vm_info; CrostiniManager::GetForProfile(profile())->AddRunningVmForTesting( - kCrostiniDefaultVmName, vm_info); + kCrostiniDefaultVmName); // Test mount. crostini_share_path_->OnVolumeMounted(chromeos::MountError::MOUNT_ERROR_NONE, @@ -746,9 +741,8 @@ TEST_F(CrostiniSharePathTest, ShareOnMountMountError) { features_.InitAndDisableFeature(chromeos::features::kCrostiniFiles); - vm_tools::concierge::VmInfo vm_info; CrostiniManager::GetForProfile(profile())->AddRunningVmForTesting( - kCrostiniDefaultVmName, vm_info); + kCrostiniDefaultVmName); // Test mount. crostini_share_path_->OnVolumeMounted( @@ -793,9 +787,8 @@ TEST_F(CrostiniSharePathTest, UnshareOnUnmountSuccessParentMount) { features_.InitAndEnableFeature(chromeos::features::kCrostiniFiles); - vm_tools::concierge::VmInfo vm_info; CrostiniManager::GetForProfile(profile())->AddRunningVmForTesting( - kCrostiniDefaultVmName, vm_info); + kCrostiniDefaultVmName); crostini_share_path_->SetMountEventSeneschalCallbackForTesting( base::BindRepeating( &CrostiniSharePathTest::MountEventUnsharePathCallback, @@ -809,9 +802,8 @@ TEST_F(CrostiniSharePathTest, UnshareOnUnmountSuccessSelfMount) { features_.InitAndEnableFeature(chromeos::features::kCrostiniFiles); - vm_tools::concierge::VmInfo vm_info; CrostiniManager::GetForProfile(profile())->AddRunningVmForTesting( - kCrostiniDefaultVmName, vm_info); + kCrostiniDefaultVmName); auto volume_shared_path = file_manager::Volume::CreateForDownloads(shared_path_); crostini_share_path_->SetMountEventSeneschalCallbackForTesting(
diff --git a/chrome/browser/chromeos/crostini/crostini_util.cc b/chrome/browser/chromeos/crostini/crostini_util.cc index 3cf1600..03a1671 100644 --- a/chrome/browser/chromeos/crostini/crostini_util.cc +++ b/chrome/browser/chromeos/crostini/crostini_util.cc
@@ -384,7 +384,7 @@ return id.empty() ? "test" : id; } -std::string ContainerUserNameForProfile(Profile* profile) { +std::string DefaultContainerUserNameForProfile(Profile* profile) { // Get rid of the @domain.name in the profile user name (an email address). std::string container_username = profile->GetProfileUserName(); if (container_username.find('@') != std::string::npos) { @@ -396,10 +396,6 @@ return container_username; } -base::FilePath ContainerHomeDirectoryForProfile(Profile* profile) { - return base::FilePath("/home/" + ContainerUserNameForProfile(profile)); -} - base::FilePath ContainerChromeOSBaseDirectory() { return base::FilePath("/mnt/chromeos"); }
diff --git a/chrome/browser/chromeos/crostini/crostini_util.h b/chrome/browser/chromeos/crostini/crostini_util.h index e1a6fae..45bcfc34 100644 --- a/chrome/browser/chromeos/crostini/crostini_util.h +++ b/chrome/browser/chromeos/crostini/crostini_util.h
@@ -78,10 +78,7 @@ // Retrieves username from profile. This is the text until '@' in // profile->GetProfileUserName() email address. -std::string ContainerUserNameForProfile(Profile* profile); - -// Returns the home directory within the container for a given profile. -base::FilePath ContainerHomeDirectoryForProfile(Profile* profile); +std::string DefaultContainerUserNameForProfile(Profile* profile); // Returns the mount directory within the container where paths from the Chrome // OS host such as within Downloads are shared with the container. @@ -126,7 +123,7 @@ // Generated using crx_file::id_util::GenerateId("LinuxAppsFolder") constexpr char kCrostiniFolderId[] = "ddolnhmblagmcagkedkbfejapapdimlk"; constexpr char kCrostiniDefaultImageServerUrl[] = - "https://storage.googleapis.com/cros-containers"; + "https://storage.googleapis.com/cros-containers/%d"; constexpr char kCrostiniDefaultImageAlias[] = "debian/stretch"; // Whether running Crostini is allowed for unaffiliated users per enterprise
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc b/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc index 8877013..d2e1b3f 100644 --- a/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc +++ b/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc
@@ -551,9 +551,11 @@ crostini::CrostiniManager* crostini_manager = crostini::CrostiniManager::GetForProfile(browser()->profile()); crostini_manager->set_skip_restart_for_testing(); - vm_tools::concierge::VmInfo vm_info; - crostini_manager->AddRunningVmForTesting(crostini::kCrostiniDefaultVmName, - std::move(vm_info)); + crostini_manager->AddRunningVmForTesting(crostini::kCrostiniDefaultVmName); + crostini_manager->AddRunningContainerForTesting( + crostini::kCrostiniDefaultVmName, + crostini::ContainerInfo(crostini::kCrostiniDefaultContainerName, + "testuser", "/home/testuser")); ExpectCrostiniMount(); @@ -585,8 +587,17 @@ IN_PROC_BROWSER_TEST_F(FileManagerPrivateApiTest, CrostiniIncognito) { base::test::ScopedFeatureList scoped_feature_list; EnableCrostiniForProfile(&scoped_feature_list); - crostini::CrostiniManager::GetForProfile(browser()->profile()) - ->set_skip_restart_for_testing(); + + // Setup CrostiniManager for testing. + crostini::CrostiniManager* crostini_manager = + crostini::CrostiniManager::GetForProfile(browser()->profile()); + crostini_manager->set_skip_restart_for_testing(); + crostini_manager->AddRunningVmForTesting(crostini::kCrostiniDefaultVmName); + crostini_manager->AddRunningContainerForTesting( + crostini::kCrostiniDefaultVmName, + crostini::ContainerInfo(crostini::kCrostiniDefaultContainerName, + "testuser", "/home/testuser")); + ExpectCrostiniMount(); scoped_refptr<extensions::FileManagerPrivateMountCrostiniFunction> function(
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 d55c6ef..b553969 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
@@ -1252,13 +1252,21 @@ drive_volume_ = drive_volumes_[profile()->GetOriginalProfile()].get(); test_util::WaitUntilDriveMountPointIsAdded(profile()); - // Init crostini. Set prefs to enable crostini and register - // CustomMountPointCallback. TODO(joelhockey): It would be better if the - // crostini interface allowed for testing without such tight coupling. + // Init crostini. Set prefs to enable crostini, set VM and container + // running for testing, and register CustomMountPointCallback. + // TODO(joelhockey): It would be better if the crostini interface allowed + // for testing without such tight coupling. crostini_volume_ = std::make_unique<CrostiniTestVolume>(); profile()->GetPrefs()->SetBoolean(crostini::prefs::kCrostiniEnabled, true); - crostini::CrostiniManager::GetForProfile(profile()->GetOriginalProfile()) - ->set_skip_restart_for_testing(); + crostini::CrostiniManager* crostini_manager = + crostini::CrostiniManager::GetForProfile( + profile()->GetOriginalProfile()); + crostini_manager->set_skip_restart_for_testing(); + crostini_manager->AddRunningVmForTesting(crostini::kCrostiniDefaultVmName); + crostini_manager->AddRunningContainerForTesting( + crostini::kCrostiniDefaultVmName, + crostini::ContainerInfo(crostini::kCrostiniDefaultContainerName, + "testuser", "/home/testuser")); chromeos::DBusThreadManager* dbus_thread_manager = chromeos::DBusThreadManager::Get(); static_cast<chromeos::FakeCrosDisksClient*>( @@ -1733,13 +1741,7 @@ if (source_url.scheme() != "sshfs") { return {}; } - // Mount crostini volume, and set VM now running for CrostiniManager. CHECK(crostini_volume_->Mount(profile())); - crostini::CrostiniManager* crostini_manager = - crostini::CrostiniManager::GetForProfile(profile()->GetOriginalProfile()); - vm_tools::concierge::VmInfo vm_info; - crostini_manager->AddRunningVmForTesting(crostini::kCrostiniDefaultVmName, - std::move(vm_info)); return crostini_volume_->mount_path(); }
diff --git a/chrome/browser/chromeos/file_manager/path_util.cc b/chrome/browser/chromeos/file_manager/path_util.cc index 4edba79..e87c2d5 100644 --- a/chrome/browser/chromeos/file_manager/path_util.cc +++ b/chrome/browser/chromeos/file_manager/path_util.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h" #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_map.h" #include "chrome/browser/chromeos/arc/fileapi/chrome_content_provider_url_util.h" +#include "chrome/browser/chromeos/crostini/crostini_manager.h" #include "chrome/browser/chromeos/crostini/crostini_util.h" #include "chrome/browser/chromeos/drive/drive_integration_service.h" #include "chrome/browser/chromeos/fileapi/external_file_url_util.h" @@ -270,7 +271,14 @@ base::FilePath base_to_exclude(id); if (id == GetCrostiniMountPointName(profile)) { // Crostini. - *inside = crostini::ContainerHomeDirectoryForProfile(profile); + base::Optional<crostini::ContainerInfo> container_info = + crostini::CrostiniManager::GetForProfile(profile)->GetContainerInfo( + crostini::kCrostiniDefaultVmName, + crostini::kCrostiniDefaultContainerName); + if (!container_info) { + return false; + } + *inside = container_info->homedir; } else if (id == GetDownloadsMountPointName(profile)) { // MyFiles or Downloads. if (base::FeatureList::IsEnabled(chromeos::features::kMyFilesVolume)) {
diff --git a/chrome/browser/chromeos/file_manager/path_util_unittest.cc b/chrome/browser/chromeos/file_manager/path_util_unittest.cc index 46c0e488..3d0974b 100644 --- a/chrome/browser/chromeos/file_manager/path_util_unittest.cc +++ b/chrome/browser/chromeos/file_manager/path_util_unittest.cc
@@ -14,6 +14,8 @@ #include "base/test/scoped_feature_list.h" #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.h" #include "chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.h" +#include "chrome/browser/chromeos/crostini/crostini_manager.h" +#include "chrome/browser/chromeos/crostini/crostini_util.h" #include "chrome/browser/chromeos/drive/drive_integration_service.h" #include "chrome/browser/chromeos/drive/file_system_util.h" #include "chrome/browser/chromeos/file_manager/fake_disk_mount_manager.h" @@ -26,6 +28,7 @@ #include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" #include "chromeos/constants/chromeos_features.h" +#include "chromeos/dbus/dbus_thread_manager.h" #include "components/account_id/account_id.h" #include "components/arc/arc_bridge_service.h" #include "components/arc/arc_service_manager.h" @@ -327,6 +330,15 @@ AccountId::FromUserEmailGaiaId(profile.GetProfileUserName(), "12345")); profile.GetPrefs()->SetString(drive::prefs::kDriveFsProfileSalt, "a"); + // Initialize DBUS and running container. + chromeos::DBusThreadManager::Initialize(); + crostini::CrostiniManager* crostini_manager = + crostini::CrostiniManager::GetForProfile(&profile); + crostini_manager->AddRunningVmForTesting(crostini::kCrostiniDefaultVmName); + crostini_manager->AddRunningContainerForTesting( + crostini::kCrostiniDefaultVmName, + crostini::ContainerInfo(crostini::kCrostiniDefaultContainerName, + "testuser", "/home/testuser")); { base::test::ScopedFeatureList features; features.InitAndEnableFeature(chromeos::features::kDriveFs); @@ -362,7 +374,7 @@ GURL(), "crostini_0123456789abcdef_termina_penguin", base::FilePath("path/in/crostini")), &inside)); - EXPECT_EQ("/home/testing_profile/path/in/crostini", inside.value()); + EXPECT_EQ("/home/testuser/path/in/crostini", inside.value()); EXPECT_TRUE(ConvertFileSystemURLToPathInsideCrostini( &profile,
diff --git a/chrome/browser/chromeos/power/ml/adaptive_screen_brightness_manager_unittest.cc b/chrome/browser/chromeos/power/ml/adaptive_screen_brightness_manager_unittest.cc index 02f655ac..50f72dd 100644 --- a/chrome/browser/chromeos/power/ml/adaptive_screen_brightness_manager_unittest.cc +++ b/chrome/browser/chromeos/power/ml/adaptive_screen_brightness_manager_unittest.cc
@@ -82,21 +82,24 @@ : public ChromeRenderViewHostTestHarness { public: AdaptiveScreenBrightnessManagerTest() - : task_runner_(base::MakeRefCounted<base::TestMockTimeTaskRunner>()) { + : ChromeRenderViewHostTestHarness( + base::test::ScopedTaskEnvironment::MainThreadType::UI_MOCK_TIME, + base::test::ScopedTaskEnvironment::ExecutionMode::QUEUED, + content::TestBrowserThreadBundle::Options::DEFAULT) { auto logger = std::make_unique<TestingAdaptiveScreenBrightnessUkmLogger>(); ukm_logger_ = logger.get(); fake_power_manager_client_.Init(nullptr); viz::mojom::VideoDetectorObserverPtr observer; auto periodic_timer = std::make_unique<base::RepeatingTimer>(); - periodic_timer->SetTaskRunner(task_runner_); + periodic_timer->SetTaskRunner(thread_bundle()->GetMainThreadTaskRunner()); screen_brightness_manager_ = std::make_unique<AdaptiveScreenBrightnessManager>( std::move(logger), &user_activity_detector_, &fake_power_manager_client_, nullptr, nullptr, mojo::MakeRequest(&observer), std::move(periodic_timer), - task_runner_->GetMockClock(), - std::make_unique<FakeBootClock>(task_runner_, + const_cast<base::Clock*>(thread_bundle()->GetMockClock()), + std::make_unique<FakeBootClock>(thread_bundle(), base::TimeDelta::FromSeconds(10))); } @@ -150,7 +153,7 @@ } void FastForwardTimeBySecs(const int seconds) { - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(seconds)); + thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(seconds)); } // Creates a test browser window and sets its visibility, activity and @@ -217,9 +220,6 @@ const GURL kUrl3 = GURL("https://example3.com/"); private: - // TODO(crbug.com/917580): Remove this; thread_bundle() should be used - // instead. - const scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; chromeos::FakeChromeUserManager fake_user_manager_; ui::UserActivityDetector user_activity_detector_;
diff --git a/chrome/browser/chromeos/power/ml/fake_boot_clock.cc b/chrome/browser/chromeos/power/ml/fake_boot_clock.cc index ac61ed6..9afca73d 100644 --- a/chrome/browser/chromeos/power/ml/fake_boot_clock.cc +++ b/chrome/browser/chromeos/power/ml/fake_boot_clock.cc
@@ -8,16 +8,6 @@ namespace power { namespace ml { -FakeBootClock::FakeBootClock( - scoped_refptr<const base::TestMockTimeTaskRunner> task_runner, - base::TimeDelta initial_time_since_boot) - : task_runner_(task_runner), - env_(nullptr), - initial_time_since_boot_(initial_time_since_boot) { - DCHECK_GE(initial_time_since_boot, base::TimeDelta()); - initial_time_ticks_ = task_runner_->NowTicks(); -} - FakeBootClock::FakeBootClock(base::test::ScopedTaskEnvironment* env, base::TimeDelta initial_time_since_boot) : env_(env), initial_time_since_boot_(initial_time_since_boot) { @@ -28,12 +18,7 @@ FakeBootClock::~FakeBootClock() = default; base::TimeDelta FakeBootClock::GetTimeSinceBoot() { - base::TimeTicks now; - if (env_) { - now = env_->NowTicks(); - } else { - now = task_runner_->NowTicks(); - } + base::TimeTicks now = env_->NowTicks(); return (now - initial_time_ticks_) + initial_time_since_boot_; }
diff --git a/chrome/browser/chromeos/power/ml/fake_boot_clock.h b/chrome/browser/chromeos/power/ml/fake_boot_clock.h index 070b3dd8..e5cb0bc4 100644 --- a/chrome/browser/chromeos/power/ml/fake_boot_clock.h +++ b/chrome/browser/chromeos/power/ml/fake_boot_clock.h
@@ -18,8 +18,6 @@ class FakeBootClock : public BootClock { public: - FakeBootClock(scoped_refptr<const base::TestMockTimeTaskRunner> task_runner, - base::TimeDelta initial_time_since_boot); FakeBootClock(base::test::ScopedTaskEnvironment* env, base::TimeDelta initial_time_since_boot); ~FakeBootClock() override; @@ -28,9 +26,6 @@ base::TimeDelta GetTimeSinceBoot() override; private: - // TODO(crbug.com/917580): This is no longer needed and should be removed. - // |env_| should give sufficient access to fake clock values. - scoped_refptr<const base::TestMockTimeTaskRunner> task_runner_; base::test::ScopedTaskEnvironment* env_; base::TimeDelta initial_time_since_boot_; base::TimeTicks initial_time_ticks_;
diff --git a/chrome/browser/chromeos/power/ml/idle_event_notifier_unittest.cc b/chrome/browser/chromeos/power/ml/idle_event_notifier_unittest.cc index 00b2f284..1049255 100644 --- a/chrome/browser/chromeos/power/ml/idle_event_notifier_unittest.cc +++ b/chrome/browser/chromeos/power/ml/idle_event_notifier_unittest.cc
@@ -79,15 +79,16 @@ class IdleEventNotifierTest : public testing::Test { public: IdleEventNotifierTest() - : task_runner_(base::MakeRefCounted<base::TestMockTimeTaskRunner>( - base::TestMockTimeTaskRunner::Type::kBoundToThread)), - scoped_context_(task_runner_.get()) { + : scoped_task_env_( + base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME, + base::test::ScopedTaskEnvironment::ExecutionMode::QUEUED) { viz::mojom::VideoDetectorObserverPtr observer; idle_event_notifier_ = std::make_unique<IdleEventNotifier>( &power_client_, &user_activity_detector_, mojo::MakeRequest(&observer)); idle_event_notifier_->SetClockForTesting( - task_runner_, task_runner_->GetMockClock(), - std::make_unique<FakeBootClock>(task_runner_, + scoped_task_env_.GetMainThreadTaskRunner(), + const_cast<base::Clock*>(scoped_task_env_.GetMockClock()), + std::make_unique<FakeBootClock>(&scoped_task_env_, base::TimeDelta::FromSeconds(10))); idle_event_notifier_->AddObserver(&test_observer_); ac_power_.set_external_power( @@ -111,8 +112,7 @@ EXPECT_TRUE(expected_activity_data == test_observer_.activity_data()); } - const scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; - const base::TestMockTimeTaskRunner::ScopedContext scoped_context_; + base::test::ScopedTaskEnvironment scoped_task_env_; TestObserver test_observer_; std::unique_ptr<IdleEventNotifier> idle_event_notifier_; @@ -132,7 +132,7 @@ // Lid is opened, followed by an idle event. TEST_F(IdleEventNotifierTest, LidOpenEventReceived) { - base::Time now = task_runner_->Now(); + base::Time now = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->LidEventReceived( chromeos::PowerManagerClient::LidState::OPEN, base::TimeTicks::UnixEpoch()); @@ -148,7 +148,7 @@ // PowerChanged signal is received but source isn't changed, so it won't change // ActivityData that gets reported when an idle event is received. TEST_F(IdleEventNotifierTest, PowerSourceNotChanged) { - base::Time now = task_runner_->Now(); + base::Time now = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->PowerChanged(ac_power_); IdleEventNotifier::ActivityData data; data.last_activity_day = GetDayOfWeek(now); @@ -158,7 +158,7 @@ data.recent_time_active = base::TimeDelta(); ReportIdleEventAndCheckResults(1, data); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(10)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(10)); idle_event_notifier_->PowerChanged(ac_power_); ReportIdleEventAndCheckResults(2, data); } @@ -166,7 +166,7 @@ // PowerChanged signal is received and source is changed, so a different // ActivityData gets reported when the 2nd idle event is received. TEST_F(IdleEventNotifierTest, PowerSourceChanged) { - base::Time now_1 = task_runner_->Now(); + base::Time now_1 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->PowerChanged(ac_power_); IdleEventNotifier::ActivityData data_1; data_1.last_activity_day = GetDayOfWeek(now_1); @@ -176,8 +176,8 @@ data_1.recent_time_active = base::TimeDelta(); ReportIdleEventAndCheckResults(1, data_1); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(100)); - base::Time now_2 = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(100)); + base::Time now_2 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->PowerChanged(disconnected_power_); IdleEventNotifier::ActivityData data_2; data_2.last_activity_day = GetDayOfWeek(now_2); @@ -190,15 +190,15 @@ // Short sleep duration does not break up recent time active. TEST_F(IdleEventNotifierTest, ShortSuspendDone) { - base::Time now_1 = task_runner_->Now(); + base::Time now_1 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->PowerChanged(ac_power_); - task_runner_->FastForwardBy(IdleEventNotifier::kIdleDelay / 2); + scoped_task_env_.FastForwardBy(IdleEventNotifier::kIdleDelay / 2); idle_event_notifier_->SuspendDone(IdleEventNotifier::kIdleDelay / 2); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(5)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(5)); idle_event_notifier_->PowerChanged(disconnected_power_); - base::Time now_2 = task_runner_->Now(); + base::Time now_2 = scoped_task_env_.GetMockClock()->Now(); IdleEventNotifier::ActivityData data; data.last_activity_day = GetDayOfWeek(now_2); @@ -213,14 +213,14 @@ TEST_F(IdleEventNotifierTest, LongSuspendDone) { idle_event_notifier_->PowerChanged(ac_power_); - task_runner_->FastForwardBy(IdleEventNotifier::kIdleDelay + - base::TimeDelta::FromSeconds(10)); - base::Time now_1 = task_runner_->Now(); + scoped_task_env_.FastForwardBy(IdleEventNotifier::kIdleDelay + + base::TimeDelta::FromSeconds(10)); + base::Time now_1 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->SuspendDone(IdleEventNotifier::kIdleDelay + base::TimeDelta::FromSeconds(10)); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(10)); - base::Time now_2 = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(10)); + base::Time now_2 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->PowerChanged(disconnected_power_); IdleEventNotifier::ActivityData data; @@ -233,7 +233,7 @@ } TEST_F(IdleEventNotifierTest, UserActivityKey) { - base::Time now = task_runner_->Now(); + base::Time now = scoped_task_env_.GetMockClock()->Now(); ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE); idle_event_notifier_->OnUserActivity(&key_event); IdleEventNotifier::ActivityData data; @@ -244,12 +244,12 @@ data.recent_time_active = base::TimeDelta(); data.time_since_last_key = base::TimeDelta::FromSeconds(10); data.key_events_in_last_hour = 1; - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(10)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(10)); ReportIdleEventAndCheckResults(1, data); } TEST_F(IdleEventNotifierTest, UserActivityMouse) { - base::Time now = task_runner_->Now(); + base::Time now = scoped_task_env_.GetMockClock()->Now(); ui::MouseEvent mouse_event(ui::ET_MOUSE_EXITED, gfx::Point(0, 0), gfx::Point(0, 0), base::TimeTicks(), 0, 0); @@ -262,12 +262,12 @@ data.recent_time_active = base::TimeDelta(); data.time_since_last_mouse = base::TimeDelta::FromSeconds(10); data.mouse_events_in_last_hour = 1; - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(10)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(10)); ReportIdleEventAndCheckResults(1, data); } TEST_F(IdleEventNotifierTest, UserActivityOther) { - base::Time now = task_runner_->Now(); + base::Time now = scoped_task_env_.GetMockClock()->Now(); ui::GestureEvent gesture_event(0, 0, 0, base::TimeTicks(), ui::GestureEventDetails(ui::ET_GESTURE_TAP)); @@ -278,20 +278,20 @@ data.last_activity_time_of_day = time_of_day; data.last_user_activity_time_of_day = time_of_day; data.recent_time_active = base::TimeDelta(); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(10)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(10)); ReportIdleEventAndCheckResults(1, data); } // Two consecutive activities separated by 2sec only. Only 1 idle event with // different timestamps for the two activities. TEST_F(IdleEventNotifierTest, TwoQuickUserActivities) { - base::Time now_1 = task_runner_->Now(); + base::Time now_1 = scoped_task_env_.GetMockClock()->Now(); ui::MouseEvent mouse_event(ui::ET_MOUSE_EXITED, gfx::Point(0, 0), gfx::Point(0, 0), base::TimeTicks(), 0, 0); idle_event_notifier_->OnUserActivity(&mouse_event); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(2)); - base::Time now_2 = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(2)); + base::Time now_2 = scoped_task_env_.GetMockClock()->Now(); ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE); idle_event_notifier_->OnUserActivity(&key_event); @@ -306,22 +306,22 @@ base::TimeDelta::FromSeconds(10) + (now_2 - now_1); data.key_events_in_last_hour = 1; data.mouse_events_in_last_hour = 1; - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(10)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(10)); ReportIdleEventAndCheckResults(1, data); } TEST_F(IdleEventNotifierTest, ActivityAfterVideoStarts) { ui::MouseEvent mouse_event(ui::ET_MOUSE_EXITED, gfx::Point(0, 0), gfx::Point(0, 0), base::TimeTicks(), 0, 0); - base::Time now_1 = task_runner_->Now(); + base::Time now_1 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnVideoActivityStarted(); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1)); - base::Time now_2 = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(1)); + base::Time now_2 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnUserActivity(&mouse_event); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(2)); - base::Time now_3 = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(2)); + base::Time now_3 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnVideoActivityEnded(); IdleEventNotifier::ActivityData data; @@ -333,17 +333,17 @@ data.video_playing_time = now_3 - now_1; data.time_since_video_ended = base::TimeDelta::FromSeconds(10); data.mouse_events_in_last_hour = 1; - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(10)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(10)); ReportIdleEventAndCheckResults(1, data); } TEST_F(IdleEventNotifierTest, IdleEventFieldReset) { - base::Time now_1 = task_runner_->Now(); + base::Time now_1 = scoped_task_env_.GetMockClock()->Now(); ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE); idle_event_notifier_->OnUserActivity(&key_event); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(10)); - base::Time now_2 = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(10)); + base::Time now_2 = scoped_task_env_.GetMockClock()->Now(); ui::MouseEvent mouse_event(ui::ET_MOUSE_EXITED, gfx::Point(0, 0), gfx::Point(0, 0), base::TimeTicks(), 0, 0); idle_event_notifier_->OnUserActivity(&mouse_event); @@ -358,11 +358,11 @@ data_1.time_since_last_mouse = base::TimeDelta::FromSeconds(10); data_1.key_events_in_last_hour = 1; data_1.mouse_events_in_last_hour = 1; - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(10)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(10)); ReportIdleEventAndCheckResults(1, data_1); idle_event_notifier_->PowerChanged(ac_power_); - base::Time now_3 = task_runner_->Now(); + base::Time now_3 = scoped_task_env_.GetMockClock()->Now(); IdleEventNotifier::ActivityData data_2; data_2.last_activity_day = GetDayOfWeek(now_3); @@ -375,28 +375,28 @@ base::TimeDelta::FromSeconds(20) + now_3 - now_2; data_2.key_events_in_last_hour = 1; data_2.mouse_events_in_last_hour = 1; - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(20)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(20)); ReportIdleEventAndCheckResults(2, data_2); } TEST_F(IdleEventNotifierTest, TwoConsecutiveVideoPlaying) { // Two video playing sessions with a gap shorter than kIdleDelay. They are // merged into one playing session. - base::Time now_1 = task_runner_->Now(); + base::Time now_1 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnVideoActivityStarted(); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(2)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(2)); idle_event_notifier_->OnVideoActivityEnded(); - task_runner_->FastForwardBy(IdleEventNotifier::kIdleDelay / 2); + scoped_task_env_.FastForwardBy(IdleEventNotifier::kIdleDelay / 2); idle_event_notifier_->OnVideoActivityStarted(); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(20)); - base::Time now_2 = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(20)); + base::Time now_2 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnVideoActivityEnded(); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(10)); - base::Time now_3 = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(10)); + base::Time now_3 = scoped_task_env_.GetMockClock()->Now(); ui::MouseEvent mouse_event(ui::ET_MOUSE_EXITED, gfx::Point(0, 0), gfx::Point(0, 0), base::TimeTicks(), 0, 0); idle_event_notifier_->OnUserActivity(&mouse_event); @@ -411,30 +411,30 @@ data.video_playing_time = now_2 - now_1; data.time_since_video_ended = base::TimeDelta::FromSeconds(25) + now_3 - now_2; - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(25)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(25)); ReportIdleEventAndCheckResults(1, data); } TEST_F(IdleEventNotifierTest, TwoVideoPlayingFarApartOneIdleEvent) { // Two video playing sessions with a gap larger than kIdleDelay. - base::Time now_1 = task_runner_->Now(); + base::Time now_1 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnVideoActivityStarted(); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(2)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(2)); idle_event_notifier_->OnVideoActivityEnded(); ui::MouseEvent mouse_event(ui::ET_MOUSE_EXITED, gfx::Point(0, 0), gfx::Point(0, 0), base::TimeTicks(), 0, 0); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(20)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(20)); idle_event_notifier_->OnUserActivity(&mouse_event); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(20)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(20)); idle_event_notifier_->OnUserActivity(&mouse_event); - base::Time now_2 = task_runner_->Now(); + base::Time now_2 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnVideoActivityStarted(); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(20)); - base::Time now_3 = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(20)); + base::Time now_3 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnVideoActivityEnded(); IdleEventNotifier::ActivityData data; @@ -446,18 +446,18 @@ data.mouse_events_in_last_hour = 2; data.video_playing_time = now_3 - now_2; data.time_since_video_ended = base::TimeDelta::FromSeconds(25); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(25)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(25)); ReportIdleEventAndCheckResults(1, data); } TEST_F(IdleEventNotifierTest, TwoVideoPlayingFarApartTwoIdleEvents) { // Two video playing sessions with a gap equal to kIdleDelay. An idle event // is generated in between, both video sessions are reported. - base::Time now_1 = task_runner_->Now(); + base::Time now_1 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnVideoActivityStarted(); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(2)); - base::Time now_2 = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(2)); + base::Time now_2 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnVideoActivityEnded(); IdleEventNotifier::ActivityData data_1; @@ -467,14 +467,14 @@ data_1.video_playing_time = now_2 - now_1; data_1.time_since_video_ended = IdleEventNotifier::kIdleDelay + base::TimeDelta::FromSeconds(10); - task_runner_->FastForwardBy(IdleEventNotifier::kIdleDelay + - base::TimeDelta::FromSeconds(10)); + scoped_task_env_.FastForwardBy(IdleEventNotifier::kIdleDelay + + base::TimeDelta::FromSeconds(10)); ReportIdleEventAndCheckResults(1, data_1); - base::Time now_3 = task_runner_->Now(); + base::Time now_3 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnVideoActivityStarted(); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(20)); - base::Time now_4 = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(20)); + base::Time now_4 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnVideoActivityEnded(); IdleEventNotifier::ActivityData data_2; @@ -489,11 +489,11 @@ TEST_F(IdleEventNotifierTest, TwoVideoPlayingSeparatedByAnIdleEvent) { // Two video playing sessions with gap shorter than kIdleDelay but separated // by an idle event. They are considered as two video sessions. - const base::Time kNow1 = task_runner_->Now(); + const base::Time kNow1 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnVideoActivityStarted(); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(2)); - const base::Time kNow2 = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(2)); + const base::Time kNow2 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnVideoActivityEnded(); IdleEventNotifier::ActivityData data_1; @@ -502,13 +502,13 @@ data_1.recent_time_active = kNow2 - kNow1; data_1.video_playing_time = kNow2 - kNow1; data_1.time_since_video_ended = base::TimeDelta::FromSeconds(1); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(1)); ReportIdleEventAndCheckResults(1, data_1); - const base::Time kNow3 = task_runner_->Now(); + const base::Time kNow3 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnVideoActivityStarted(); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(20)); - const base::Time kNow4 = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(20)); + const base::Time kNow4 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnVideoActivityEnded(); IdleEventNotifier::ActivityData data_2; @@ -521,15 +521,15 @@ } TEST_F(IdleEventNotifierTest, VideoPlayingPausedByShortSuspend) { - base::Time now_1 = task_runner_->Now(); + base::Time now_1 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnVideoActivityStarted(); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(100)); - base::Time now_2 = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(100)); + base::Time now_2 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->SuspendDone(IdleEventNotifier::kIdleDelay / 2); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(20)); - base::Time now_3 = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(20)); + base::Time now_3 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnVideoActivityEnded(); IdleEventNotifier::ActivityData data; @@ -545,12 +545,12 @@ TEST_F(IdleEventNotifierTest, VideoPlayingPausedByLongSuspend) { idle_event_notifier_->OnVideoActivityStarted(); - task_runner_->FastForwardBy(2 * IdleEventNotifier::kIdleDelay); - base::Time now_1 = task_runner_->Now(); + scoped_task_env_.FastForwardBy(2 * IdleEventNotifier::kIdleDelay); + base::Time now_1 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->SuspendDone(2 * IdleEventNotifier::kIdleDelay); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(20)); - base::Time now_2 = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(20)); + base::Time now_2 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnVideoActivityEnded(); IdleEventNotifier::ActivityData data; @@ -571,37 +571,37 @@ ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), base::TimeTicks::UnixEpoch(), ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0)); - base::Time first_activity_time = task_runner_->Now(); + base::Time first_activity_time = scoped_task_env_.GetMockClock()->Now(); // This key event will be too old to be counted. idle_event_notifier_->OnUserActivity(&key_event); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(10)); - base::Time video_start_time = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(10)); + base::Time video_start_time = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnVideoActivityStarted(); - task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(11)); - base::Time last_key_time = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromMinutes(11)); + base::Time last_key_time = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnUserActivity(&key_event); - task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(11)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromMinutes(11)); idle_event_notifier_->OnUserActivity(&mouse_event); - task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(11)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromMinutes(11)); idle_event_notifier_->OnUserActivity(&touch_event); - task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(11)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromMinutes(11)); idle_event_notifier_->OnUserActivity(&touch_event); - task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(11)); - base::Time last_touch_time = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromMinutes(11)); + base::Time last_touch_time = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnUserActivity(&touch_event); - task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(11)); - base::Time last_mouse_time = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromMinutes(11)); + base::Time last_mouse_time = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnUserActivity(&mouse_event); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(10)); - base::Time video_end_time = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(10)); + base::Time video_end_time = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnVideoActivityEnded(); IdleEventNotifier::ActivityData data; @@ -622,7 +622,7 @@ data.mouse_events_in_last_hour = 2; data.touch_events_in_last_hour = 3; - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(30)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(30)); ReportIdleEventAndCheckResults(1, data); } @@ -634,7 +634,7 @@ ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), base::TimeTicks::UnixEpoch(), ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0)); - base::Time now_1 = task_runner_->Now(); + base::Time now_1 = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnUserActivity(&key_event); IdleEventNotifier::ActivityData data_1; @@ -644,37 +644,37 @@ data_1.recent_time_active = base::TimeDelta(); data_1.time_since_last_key = base::TimeDelta::FromSeconds(30); data_1.key_events_in_last_hour = 1; - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(30)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(30)); ReportIdleEventAndCheckResults(1, data_1); - task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(11)); - base::Time last_key_time = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromMinutes(11)); + base::Time last_key_time = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnUserActivity(&key_event); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(10)); - base::Time video_start_time = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(10)); + base::Time video_start_time = scoped_task_env_.GetMockClock()->Now(); // Keep playing video so we won't run into an idle event. idle_event_notifier_->OnVideoActivityStarted(); - task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(11)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromMinutes(11)); idle_event_notifier_->OnUserActivity(&mouse_event); - task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(11)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromMinutes(11)); idle_event_notifier_->OnUserActivity(&touch_event); - task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(11)); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromMinutes(11)); idle_event_notifier_->OnUserActivity(&touch_event); - task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(11)); - base::Time last_touch_time = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromMinutes(11)); + base::Time last_touch_time = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnUserActivity(&touch_event); - task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(11)); - base::Time last_mouse_time = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromMinutes(11)); + base::Time last_mouse_time = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnUserActivity(&mouse_event); - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(10)); - base::Time video_end_time = task_runner_->Now(); + scoped_task_env_.FastForwardBy(base::TimeDelta::FromSeconds(10)); + base::Time video_end_time = scoped_task_env_.GetMockClock()->Now(); idle_event_notifier_->OnVideoActivityEnded(); IdleEventNotifier::ActivityData data_2;
diff --git a/chrome/browser/chromeos/power/ml/user_activity_manager.cc b/chrome/browser/chromeos/power/ml/user_activity_manager.cc index 567b1d3..f721496 100644 --- a/chrome/browser/chromeos/power/ml/user_activity_manager.cc +++ b/chrome/browser/chromeos/power/ml/user_activity_manager.cc
@@ -51,6 +51,14 @@ UMA_HISTOGRAM_ENUMERATION("PowerML.ModelNoDim.Result", result); } +void LogPowerMLSmartDimModelRequestCancel(base::TimeDelta time) { + UMA_HISTOGRAM_TIMES("PowerML.SmartDimModel.RequestCanceledDuration", time); +} + +void LogPowerMLSmartDimModelRequestComplete(base::TimeDelta time) { + UMA_HISTOGRAM_TIMES("PowerML.SmartDimModel.RequestCompleteDuration", time); +} + void LogMetricsToUMA(const UserActivityEvent& event) { const FinalResult result = event.event().type() == UserActivityEvent::Event::REACTIVATE @@ -262,6 +270,7 @@ base::FeatureList::IsEnabled(features::kUserActivityPrediction) && smart_dim_model_) { waiting_for_model_decision_ = true; + time_dim_decision_requested_ = base::TimeTicks::Now(); smart_dim_model_->RequestDimDecision( features_, base::Bind(&UserActivityManager::ApplyDimDecision, weak_ptr_factory_.GetWeakPtr())); @@ -273,6 +282,10 @@ UserActivityEvent::ModelPrediction prediction) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); waiting_for_model_decision_ = false; + const base::TimeDelta wait_time = + base::TimeTicks::Now() - time_dim_decision_requested_; + LogPowerMLSmartDimModelRequestComplete(wait_time); + time_dim_decision_requested_ = base::TimeTicks(); // Only defer the dim if the model predicts so and also if the dim was not // previously deferred. if (prediction.response() == UserActivityEvent::ModelPrediction::NO_DIM && @@ -594,13 +607,15 @@ } void UserActivityManager::CancelDimDecisionRequest() { - // TODO(crbug.com/893425): Log the time after which a dim decision request - // was cancelled, in UMA. // TODO(crbug.com/893425): Add a unit-test to verify UMA logging of // cancellation time. LOG(WARNING) << "Cancelling pending Smart Dim decision request."; smart_dim_model_->CancelPreviousRequest(); waiting_for_model_decision_ = false; + const base::TimeDelta wait_time = + base::TimeTicks::Now() - time_dim_decision_requested_; + LogPowerMLSmartDimModelRequestCancel(wait_time); + time_dim_decision_requested_ = base::TimeTicks(); } } // namespace ml
diff --git a/chrome/browser/chromeos/power/ml/user_activity_manager.h b/chrome/browser/chromeos/power/ml/user_activity_manager.h index 5ccb0390..43a1e2e 100644 --- a/chrome/browser/chromeos/power/ml/user_activity_manager.h +++ b/chrome/browser/chromeos/power/ml/user_activity_manager.h
@@ -242,6 +242,10 @@ // regarding whether to proceed with a dim or not. It is only set // to true in OnIdleEventObserved() when we request a dim decision. bool waiting_for_model_decision_ = false; + // Represents the time when a dim decision request was made. It is used to + // calculate time deltas while logging ML service dim decision request + // results. + base::TimeTicks time_dim_decision_requested_; // Model prediction for the current ScreenDimImminent event. Unset if // model prediction is disabled by an experiment.
diff --git a/chrome/browser/chromeos/power/ml/user_activity_manager_unittest.cc b/chrome/browser/chromeos/power/ml/user_activity_manager_unittest.cc index 8aabb263..c91457b2 100644 --- a/chrome/browser/chromeos/power/ml/user_activity_manager_unittest.cc +++ b/chrome/browser/chromeos/power/ml/user_activity_manager_unittest.cc
@@ -11,6 +11,7 @@ #include "base/cancelable_callback.h" #include "base/sequenced_task_runner.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" #include "base/time/clock.h" @@ -892,6 +893,7 @@ } TEST_F(UserActivityManagerTest, ScreenDimDeferredWithFinalEvent) { + base::HistogramTester histogram_tester; const std::map<std::string, std::string> params = { {"dim_threshold", "0.651"}}; base::test::ScopedFeatureList scoped_feature_list; @@ -907,6 +909,9 @@ ReportUserActivity(nullptr); EXPECT_EQ(1, GetNumberOfDeferredDims()); + std::string histogram("PowerML.SmartDimModel.RequestCompleteDuration"); + histogram_tester.ExpectTotalCount(histogram, 1); + const std::vector<UserActivityEvent>& events = delegate_.events(); ASSERT_EQ(1U, events.size()); @@ -928,6 +933,7 @@ } TEST_F(UserActivityManagerTest, ScreenDimDeferredWithoutFinalEvent) { + base::HistogramTester histogram_tester; const std::map<std::string, std::string> params = { {"dim_threshold", "0.651"}}; base::test::ScopedFeatureList scoped_feature_list; @@ -942,11 +948,15 @@ thread_bundle()->RunUntilIdle(); EXPECT_EQ(1, GetNumberOfDeferredDims()); + std::string histogram("PowerML.SmartDimModel.RequestCompleteDuration"); + histogram_tester.ExpectTotalCount(histogram, 1); + const std::vector<UserActivityEvent>& events = delegate_.events(); EXPECT_TRUE(events.empty()); } TEST_F(UserActivityManagerTest, ScreenDimNotDeferred) { + base::HistogramTester histogram_tester; const std::map<std::string, std::string> params = { {"dim_threshold", base::NumberToString(0.5)}}; base::test::ScopedFeatureList scoped_feature_list; @@ -962,6 +972,9 @@ ReportUserActivity(nullptr); EXPECT_EQ(0, GetNumberOfDeferredDims()); + std::string histogram("PowerML.SmartDimModel.RequestCompleteDuration"); + histogram_tester.ExpectTotalCount(histogram, 1); + const std::vector<UserActivityEvent>& events = delegate_.events(); ASSERT_EQ(1U, events.size()); @@ -975,6 +988,7 @@ } TEST_F(UserActivityManagerTest, TwoScreenDimImminentWithEventInBetween) { + base::HistogramTester histogram_tester; const std::map<std::string, std::string> params = { {"dim_threshold", base::NumberToString(0.5)}}; base::test::ScopedFeatureList scoped_feature_list; @@ -998,8 +1012,12 @@ model_.set_inactivity_score(20); thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(10)); ReportIdleEvent(data); + thread_bundle()->RunUntilIdle(); EXPECT_EQ(1, GetNumberOfDeferredDims()); + std::string histogram("PowerML.SmartDimModel.RequestCompleteDuration"); + histogram_tester.ExpectTotalCount(histogram, 2); + // Log when a SuspendImminent is received thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(20)); ReportSuspend(power_manager::SuspendImminent_Reason_IDLE, @@ -1045,6 +1063,7 @@ } TEST_F(UserActivityManagerTest, TwoScreenDimImminentWithoutEventInBetween) { + base::HistogramTester histogram_tester; const std::map<std::string, std::string> params = { {"dim_threshold", base::NumberToString(0.5)}}; base::test::ScopedFeatureList scoped_feature_list; @@ -1066,6 +1085,9 @@ thread_bundle()->RunUntilIdle(); EXPECT_EQ(1, GetNumberOfDeferredDims()); + std::string histogram("PowerML.SmartDimModel.RequestCompleteDuration"); + histogram_tester.ExpectTotalCount(histogram, 2); + // Log when a SuspendImminent is received thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(20)); ReportSuspend(power_manager::SuspendImminent_Reason_IDLE, @@ -1106,6 +1128,7 @@ } TEST_F(UserActivityManagerTest, ModelError) { + base::HistogramTester histogram_tester; const std::map<std::string, std::string> params = { {"dim_threshold", "0.651"}}; base::test::ScopedFeatureList scoped_feature_list; @@ -1122,6 +1145,9 @@ ReportUserActivity(nullptr); EXPECT_EQ(0, GetNumberOfDeferredDims()); + std::string histogram("PowerML.SmartDimModel.RequestCompleteDuration"); + histogram_tester.ExpectTotalCount(histogram, 1); + const std::vector<UserActivityEvent>& events = delegate_.events(); ASSERT_EQ(1U, events.size());
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.cc b/chrome/browser/extensions/api/developer_private/developer_private_api.cc index b0f731cd..9c14f31 100644 --- a/chrome/browser/extensions/api/developer_private/developer_private_api.cc +++ b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
@@ -1889,10 +1889,10 @@ return RespondNow(Error(kCouldNotFindWebContentsError)); scoped_refptr<WebstoreReinstaller> reinstaller(new WebstoreReinstaller( - web_contents, - params->extension_id, - base::Bind(&DeveloperPrivateRepairExtensionFunction::OnReinstallComplete, - this))); + web_contents, params->extension_id, + base::BindOnce( + &DeveloperPrivateRepairExtensionFunction::OnReinstallComplete, + this))); reinstaller->BeginReinstall(); return RespondLater();
diff --git a/chrome/browser/extensions/webstore_install_with_prompt.cc b/chrome/browser/extensions/webstore_install_with_prompt.cc index 4e60cd55..3a901a6 100644 --- a/chrome/browser/extensions/webstore_install_with_prompt.cc +++ b/chrome/browser/extensions/webstore_install_with_prompt.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/extensions/webstore_install_with_prompt.h" +#include <utility> + #include "chrome/browser/extensions/webstore_installer.h" #include "chrome/browser/profiles/profile.h" #include "content/public/browser/web_contents.h" @@ -15,8 +17,10 @@ WebstoreInstallWithPrompt::WebstoreInstallWithPrompt( const std::string& webstore_item_id, Profile* profile, - const Callback& callback) - : WebstoreStandaloneInstaller(webstore_item_id, profile, callback), + Callback callback) + : WebstoreStandaloneInstaller(webstore_item_id, + profile, + std::move(callback)), show_post_install_ui_(true), dummy_web_contents_( WebContents::Create(WebContents::CreateParams(profile))), @@ -28,8 +32,10 @@ const std::string& webstore_item_id, Profile* profile, gfx::NativeWindow parent_window, - const Callback& callback) - : WebstoreStandaloneInstaller(webstore_item_id, profile, callback), + Callback callback) + : WebstoreStandaloneInstaller(webstore_item_id, + profile, + std::move(callback)), show_post_install_ui_(true), dummy_web_contents_( WebContents::Create(WebContents::CreateParams(profile))),
diff --git a/chrome/browser/extensions/webstore_install_with_prompt.h b/chrome/browser/extensions/webstore_install_with_prompt.h index 483ad49..3995e07 100644 --- a/chrome/browser/extensions/webstore_install_with_prompt.h +++ b/chrome/browser/extensions/webstore_install_with_prompt.h
@@ -35,14 +35,14 @@ // will be centered on the screen. WebstoreInstallWithPrompt(const std::string& webstore_item_id, Profile* profile, - const Callback& callback); + Callback callback); // If this constructor is used, the parent of the install dialog will be // |parent_window|. WebstoreInstallWithPrompt(const std::string& webstore_item_id, Profile* profile, gfx::NativeWindow parent_window, - const Callback& callback); + Callback callback); protected: friend class base::RefCountedThreadSafe<WebstoreInstallWithPrompt>;
diff --git a/chrome/browser/extensions/webstore_reinstaller.cc b/chrome/browser/extensions/webstore_reinstaller.cc index 61fcf8eb..282a84b 100644 --- a/chrome/browser/extensions/webstore_reinstaller.cc +++ b/chrome/browser/extensions/webstore_reinstaller.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/extensions/webstore_reinstaller.h" +#include <utility> + #include "base/memory/ref_counted.h" #include "chrome/browser/extensions/extension_install_prompt.h" #include "chrome/browser/extensions/extension_service.h" @@ -21,11 +23,11 @@ WebstoreReinstaller::WebstoreReinstaller( content::WebContents* web_contents, const std::string& extension_id, - const WebstoreStandaloneInstaller::Callback& callback) + WebstoreStandaloneInstaller::Callback callback) : WebstoreStandaloneInstaller( extension_id, Profile::FromBrowserContext(web_contents->GetBrowserContext()), - callback), + std::move(callback)), content::WebContentsObserver(web_contents) { DCHECK( ExtensionPrefs::Get(web_contents->GetBrowserContext())
diff --git a/chrome/browser/extensions/webstore_reinstaller.h b/chrome/browser/extensions/webstore_reinstaller.h index 24904a9b..7e1c0c5a 100644 --- a/chrome/browser/extensions/webstore_reinstaller.h +++ b/chrome/browser/extensions/webstore_reinstaller.h
@@ -19,7 +19,7 @@ public: WebstoreReinstaller(content::WebContents* web_contents, const std::string& extension_id, - const WebstoreStandaloneInstaller::Callback& callback); + WebstoreStandaloneInstaller::Callback callback); // Begin the reinstall process. |callback| (from the constructor) will be // called upon completion.
diff --git a/chrome/browser/extensions/webstore_reinstaller_browsertest.cc b/chrome/browser/extensions/webstore_reinstaller_browsertest.cc index 007713b..394aefb6 100644 --- a/chrome/browser/extensions/webstore_reinstaller_browsertest.cc +++ b/chrome/browser/extensions/webstore_reinstaller_browsertest.cc
@@ -89,13 +89,10 @@ // Create and run a WebstoreReinstaller. base::RunLoop run_loop; - scoped_refptr<WebstoreReinstaller> reinstaller( - new WebstoreReinstaller( - active_web_contents, - kTestExtensionId, - base::Bind(&WebstoreReinstallerBrowserTest::OnInstallCompletion, - base::Unretained(this), - run_loop.QuitClosure()))); + scoped_refptr<WebstoreReinstaller> reinstaller(new WebstoreReinstaller( + active_web_contents, kTestExtensionId, + base::BindOnce(&WebstoreReinstallerBrowserTest::OnInstallCompletion, + base::Unretained(this), run_loop.QuitClosure()))); reinstaller->BeginReinstall(); run_loop.Run(); @@ -108,13 +105,10 @@ // Now accept the repair prompt. AutoAcceptInstall(); base::RunLoop run_loop2; - reinstaller = - new WebstoreReinstaller( - active_web_contents, - kTestExtensionId, - base::Bind(&WebstoreReinstallerBrowserTest::OnInstallCompletion, - base::Unretained(this), - run_loop2.QuitClosure())); + reinstaller = new WebstoreReinstaller( + active_web_contents, kTestExtensionId, + base::BindOnce(&WebstoreReinstallerBrowserTest::OnInstallCompletion, + base::Unretained(this), run_loop2.QuitClosure())); reinstaller->BeginReinstall(); run_loop2.Run();
diff --git a/chrome/browser/extensions/webstore_standalone_installer.cc b/chrome/browser/extensions/webstore_standalone_installer.cc index 998f8a51a..713f26d9 100644 --- a/chrome/browser/extensions/webstore_standalone_installer.cc +++ b/chrome/browser/extensions/webstore_standalone_installer.cc
@@ -31,9 +31,9 @@ WebstoreStandaloneInstaller::WebstoreStandaloneInstaller( const std::string& webstore_item_id, Profile* profile, - const Callback& callback) + Callback callback) : id_(webstore_item_id), - callback_(callback), + callback_(std::move(callback)), profile_(profile), install_source_(WebstoreInstaller::INSTALL_SOURCE_INLINE), show_user_count_(true), @@ -80,7 +80,8 @@ void WebstoreStandaloneInstaller::RunCallback(bool success, const std::string& error, webstore_install::Result result) { - callback_.Run(success, error, result); + DCHECK(callback_); + std::move(callback_).Run(success, error, result); } void WebstoreStandaloneInstaller::AbortInstall() { @@ -117,7 +118,7 @@ const std::string& error) { scoped_active_install_.reset(); if (!callback_.is_null()) - callback_.Run(result == webstore_install::SUCCESS, error, result); + RunCallback(result == webstore_install::SUCCESS, error, result); Release(); // Matches the AddRef in BeginInstall. }
diff --git a/chrome/browser/extensions/webstore_standalone_installer.h b/chrome/browser/extensions/webstore_standalone_installer.h index c948c6e..fa586fa 100644 --- a/chrome/browser/extensions/webstore_standalone_installer.h +++ b/chrome/browser/extensions/webstore_standalone_installer.h
@@ -46,20 +46,21 @@ // A callback for when the install process completes, successfully or not. If // there was a failure, |success| will be false and |error| may contain a // developer-readable error message about why it failed. - typedef base::Callback<void(bool success, - const std::string& error, - webstore_install::Result result)> Callback; + using Callback = base::OnceCallback<void(bool success, + const std::string& error, + webstore_install::Result result)>; WebstoreStandaloneInstaller(const std::string& webstore_item_id, Profile* profile, - const Callback& callback); + Callback callback); void BeginInstall(); protected: ~WebstoreStandaloneInstaller() override; // Runs the callback; primarily used for running a callback before it is - // cleared in AbortInstall(). + // cleared in AbortInstall(). This should only be called once for the lifetime + // of the class. void RunCallback( bool success, const std::string& error, webstore_install::Result result);
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc index 2b061499..b17651a 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
@@ -548,6 +548,26 @@ EXPECT_FALSE(menu.IsItemPresent(IDC_CONTENT_CONTEXT_EMOJI)); } +// Only Chrome OS supports emoji panel callbacks. +#if defined(OS_CHROMEOS) +IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, + ContextMenuForEmojiPanel_NoCallback) { + // Reset the emoji callback. + ui::SetShowEmojiKeyboardCallback(base::RepeatingClosure()); + + content::ContextMenuParams params; + params.is_editable = true; + + TestRenderViewContextMenu menu( + browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(), + params); + menu.Init(); + + // If there's no callback, the emoji context menu should not be present. + EXPECT_FALSE(menu.IsItemPresent(IDC_CONTENT_CONTEXT_EMOJI)); +} +#endif // defined(OS_CHROMEOS) + IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, CopyLinkTextMouse) { std::unique_ptr<TestRenderViewContextMenu> menu = CreateContextMenu( GURL("http://www.google.com/"), GURL("http://www.google.com/"),
diff --git a/chrome/browser/resources/app_management/BUILD.gn b/chrome/browser/resources/app_management/BUILD.gn index 9de449a..639f0d1 100644 --- a/chrome/browser/resources/app_management/BUILD.gn +++ b/chrome/browser/resources/app_management/BUILD.gn
@@ -69,6 +69,8 @@ js_library("chrome_app_permission_view") { deps = [ ":fake_page_handler", + ":metadata_view", + ":permission_view_header", ] } @@ -107,6 +109,9 @@ ] } + js_library("permission_view_header") { + } + js_library("permission_item") { deps = [ ":constants", @@ -120,6 +125,7 @@ ":fake_page_handler", ":metadata_view", ":permission_item", + ":permission_view_header", ":store_client", ] }
diff --git a/chrome/browser/resources/app_management/actions.js b/chrome/browser/resources/app_management/actions.js index c0f3056..0427f84d 100644 --- a/chrome/browser/resources/app_management/actions.js +++ b/chrome/browser/resources/app_management/actions.js
@@ -9,12 +9,12 @@ cr.define('app_management.actions', function() { /** - * @param {Array<App>} apps + * @param {App} app */ - function addApps(apps) { + function addApp(app) { return { - name: 'add-apps', - apps: apps, + name: 'add-app', + app: app, }; } @@ -56,7 +56,7 @@ } return { - addApps: addApps, + addApp: addApp, changeApp: changeApp, removeApp: removeApp, changePage: changePage,
diff --git a/chrome/browser/resources/app_management/api_listener.js b/chrome/browser/resources/app_management/api_listener.js index b7b3b46f..f622de3 100644 --- a/chrome/browser/resources/app_management/api_listener.js +++ b/chrome/browser/resources/app_management/api_listener.js
@@ -4,37 +4,22 @@ cr.define('app_management.ApiListener', function() { let initialized = false; - let initialListenerId; - - function init() { + async function init() { assert(!initialized); - const callbackRouter = - app_management.BrowserProxy.getInstance().callbackRouter; - - initialListenerId = - callbackRouter.onAppsAdded.addListener(initialOnAppsAdded); - - app_management.BrowserProxy.getInstance().handler.getApps(); - - initialized = true; - } - - /** - * @param {!Array<App>} apps - */ - function initialOnAppsAdded(apps) { - const initialState = app_management.util.createInitialState(apps); + const {apps: initialApps} = + await app_management.BrowserProxy.getInstance().handler.getApps(); + const initialState = app_management.util.createInitialState(initialApps); app_management.Store.getInstance().init(initialState); const callbackRouter = app_management.BrowserProxy.getInstance().callbackRouter; - callbackRouter.onAppsAdded.addListener(onAppsAdded); + callbackRouter.onAppAdded.addListener(onAppAdded); callbackRouter.onAppChanged.addListener(onAppChanged); callbackRouter.onAppRemoved.addListener(onAppRemoved); - callbackRouter.removeListener(initialListenerId); + initialized = true; } /** @@ -45,10 +30,10 @@ } /** - * @param {Array<App>} apps + * @param {App} app */ - function onAppsAdded(apps) { - dispatch(app_management.actions.addApps(apps)); + function onAppAdded(app) { + dispatch(app_management.actions.addApp(app)); } /**
diff --git a/chrome/browser/resources/app_management/chrome_app_permission_view.html b/chrome/browser/resources/app_management/chrome_app_permission_view.html index 2c1803b..ea78140 100644 --- a/chrome/browser/resources/app_management/chrome_app_permission_view.html +++ b/chrome/browser/resources/app_management/chrome_app_permission_view.html
@@ -1,9 +1,7 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="shared_style.html"> -<link rel="import" href="browser_proxy.html"> <link rel="import" href="shared_style.html"> -<link rel="import" href="util.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <dom-module id="app-management-chrome-app-permission-view"> @@ -11,15 +9,8 @@ <style include="app-management-shared-css"> </style> - <div class="permission-view-header"> - <paper-icon-button-light class="icon-arrow-back"> - <button> - <paper-ripple class="circle"></paper-ripple> - </button> - </paper-icon-button-light> - <img class="permission-view-header-icon" src="[[iconUrlFromId_(app_)]]"> - <div class="app-title">[[app_.title]]</div> - </div> + <app-management-permission-view-header app="[[app_]]"> + </app-management-permission-view-header> <app-management-metadata-view app="[[app_]]"></app-management-metadata-view> </template> <script src="chrome_app_permission_view.js"></script>
diff --git a/chrome/browser/resources/app_management/chrome_app_permission_view.js b/chrome/browser/resources/app_management/chrome_app_permission_view.js index 6973667..896d1d7 100644 --- a/chrome/browser/resources/app_management/chrome_app_permission_view.js +++ b/chrome/browser/resources/app_management/chrome_app_permission_view.js
@@ -17,13 +17,4 @@ }, }, }, - - /** - * @param {appManagement.mojom.App} app - * @return {string} - * @private - */ - iconUrlFromId_: function(app) { - return app_management.util.getAppIcon(app); - }, });
diff --git a/chrome/browser/resources/app_management/fake_page_handler.js b/chrome/browser/resources/app_management/fake_page_handler.js index 15396ed..a86724c 100644 --- a/chrome/browser/resources/app_management/fake_page_handler.js +++ b/chrome/browser/resources/app_management/fake_page_handler.js
@@ -58,7 +58,7 @@ } getApps() { - this.page.onAppsAdded.dispatch_(this.apps_); + return Promise.resolve({apps: this.apps_}); } /**
diff --git a/chrome/browser/resources/app_management/permission_view_header.html b/chrome/browser/resources/app_management/permission_view_header.html new file mode 100644 index 0000000..f502bbf1 --- /dev/null +++ b/chrome/browser/resources/app_management/permission_view_header.html
@@ -0,0 +1,44 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="shared_style.html"> +<link rel="import" href="shared_vars.html"> +<link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> +<dom-module id="app-management-permission-view-header"> + <template> + <style include="app-management-shared-css paper-button-style"> + :host { + align-items: center; + border-top: var(--card-separator); + display: flex; + } + + #permission-view-header-icon { + height: 26px; + margin-inline-end: 8px; + margin-inline-start: 24px; + width: 26px; + } + + #app-title { + flex: 1; + font-size: 16px; + overflow: hidden; + text-overflow: ellipsis; + } + </style> + + <paper-icon-button-light class="icon-arrow-back"> + <button><paper-ripple class="circle"></paper-ripple></button> + </paper-icon-button-light> + <img id="permission-view-header-icon" src="[[iconUrlFromId_(app)]]"> + <div id="app-title">[[app.title]]</div> + <slot name="extra-right-buttons"></slot> + <paper-button> + $i18n{uninstall} + </paper-button> + </template> + <script src="permission_view_header.js"></script> +</dom-module>
diff --git a/chrome/browser/resources/app_management/permission_view_header.js b/chrome/browser/resources/app_management/permission_view_header.js new file mode 100644 index 0000000..b60b8f0d --- /dev/null +++ b/chrome/browser/resources/app_management/permission_view_header.js
@@ -0,0 +1,22 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +Polymer({ + is: 'app-management-permission-view-header', + + properties: { + /** @type {App} */ + app: { + type: Object, + }, + }, + + /** + * @param {App} app + * @return {string} + * @private + */ + iconUrlFromId_: function(app) { + return app_management.util.getAppIcon(app); + }, +});
diff --git a/chrome/browser/resources/app_management/pwa_permission_view.html b/chrome/browser/resources/app_management/pwa_permission_view.html index ca89396..e8370ae7 100644 --- a/chrome/browser/resources/app_management/pwa_permission_view.html +++ b/chrome/browser/resources/app_management/pwa_permission_view.html
@@ -6,6 +6,7 @@ <link rel="import" href="permission_item.html"> <link rel="import" href="shared_style.html"> <link rel="import" href="shared_vars.html"> +<link rel="import" href="permission_view_header.html"> <link rel="import" href="store_client.html"> <link rel="import" href="chrome://resources/cr_elements/cr_icons_css.html"> <link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html"> @@ -19,16 +20,6 @@ <dom-module id="app-management-pwa-permission-view"> <template> <style include="app-management-shared-css cr-icons paper-button-style"> - #site-settings-button { - color: var(--secondary-text-color); - font-size: 12px; - } - - #site-settings-icon { - display: flex; - margin-inline-end: 24px; - } - #permission-list { display: flex; flex-direction: column; @@ -40,26 +31,34 @@ margin: 0 24px; width: 1px; } + + #site-settings-button { + --paper-button-ink-color: none; + border: none; + color: var(--secondary-text-color); + display: flex; + font-size: 12px; + font-weight: var(--secondary-font-weight); + } + + #site-settings-icon { + display: flex; + margin-inline-end: 24px; + margin-inline-start: 0; + } + </style> - <div class="permission-view-header"> - <paper-icon-button-light class="icon-arrow-back"> - <button id="closeButton" on-click="onClickBackButton_" - aria-label="$i18n{back}"> - <paper-ripple class="circle"></paper-ripple> - </button> - </paper-icon-button-light> - <img class="permission-view-header-icon" src="[[iconUrlFromId_(app_)]]"> - <div class="app-title">[[app_.title]]</div> - <div id="site-settings-button">$i18n{openSiteSettings}</div> - <paper-icon-button-light id="site-settings-icon" class="icon-external"> - <button aria-label="$i18n{openSiteSettings}"></button> - </paper-icon-button-light> - <paper-button class="secondary-button" on-click="onClickUninstallButton_" - role="button" - tabindex="0" aria-disabled="false" elevation="0"> - $i18n{uninstall} - </paper-button> - </div> + <app-management-permission-view-header app="[[app_]]"> + <div slot="extra-right-buttons"> + <paper-button id="site-settings-button"> + $i18n{openSiteSettings} + <paper-icon-button-light id="site-settings-icon" + class="icon-external"> + <button></button> + </paper-icon-button-light> + </paper-button> + </div> + </app-management-permission-view-header> <div id="permission-list" class="card-container"> <app-management-permission-item app="[[app_]]"
diff --git a/chrome/browser/resources/app_management/reducers.js b/chrome/browser/resources/app_management/reducers.js index 794fa85..7cb8617 100644 --- a/chrome/browser/resources/app_management/reducers.js +++ b/chrome/browser/resources/app_management/reducers.js
@@ -17,12 +17,10 @@ * @param {Object} action * @return {AppMap} */ - AppState.addApps = function(apps, action) { - const newAppEntries = {}; - for (const app of action.apps) { - newAppEntries[app.id] = app; - } - return Object.assign({}, apps, newAppEntries); + AppState.addApp = function(apps, action) { + const newAppEntry = {}; + newAppEntry[action.app.id] = action.app; + return Object.assign({}, apps, newAppEntry); }; /** @@ -57,8 +55,8 @@ */ AppState.updateApps = function(apps, action) { switch (action.name) { - case 'add-apps': - return AppState.addApps(apps, action); + case 'add-app': + return AppState.addApp(apps, action); case 'change-app': return AppState.changeApp(apps, action); case 'remove-app':
diff --git a/chrome/browser/resources/app_management/shared_style.html b/chrome/browser/resources/app_management/shared_style.html index 02dd666..46b9493 100644 --- a/chrome/browser/resources/app_management/shared_style.html +++ b/chrome/browser/resources/app_management/shared_style.html
@@ -13,19 +13,6 @@ width: var(--card-width); } - .permission-view-header { - align-items: center; - border-top: var(--card-separator); - display: flex; - } - - .permission-view-header-icon { - height: 26px; - margin-inline-end: 8px; - margin-inline-start: 24px; - width: 26px; - } - .permission-row { align-items: center; border-top: var(--card-separator); @@ -45,26 +32,6 @@ font-weight: var(--secondary-font-weight); } - .app-title { - flex: 1; - font-size: 16px; - overflow: hidden; - text-overflow: ellipsis; - } - - .permission-row { - align-items: center; - border-top: var(--card-separator); - display: inline-flex; - height: 62px; - justify-content: space-between; - padding: 0 24px; - } - - .permission-row:first-child { - border-style: none; - } - .permission-row-controls { align-items: center; display: inline-flex;
diff --git a/chrome/browser/resources/chromeos/chromevox/chromevox/injected/event_watcher_test.unitjs b/chrome/browser/resources/chromeos/chromevox/chromevox/injected/event_watcher_test.unitjs index 05c23bf..94dc1f4 100644 --- a/chrome/browser/resources/chromeos/chromevox/chromevox/injected/event_watcher_test.unitjs +++ b/chrome/browser/resources/chromeos/chromevox/chromevox/injected/event_watcher_test.unitjs
@@ -503,7 +503,8 @@ * Test that no feedback is received for events that fire on elements * that are hidden (or the descendant of a hidden element). */ -TEST_F('ChromeVoxEventWatcherUnitTest', 'AriaHiddenFeedback', function() { +// Flaky on Chromium OS: https://crbug.com/919033. +TEST_F('ChromeVoxEventWatcherUnitTest', 'DISABLED_AriaHiddenFeedback', function() { this.loadHtml('<div>' + '<div>' + ' <button id="button1">Button 1</button>' +
diff --git a/chrome/browser/resources/md_downloads/item.html b/chrome/browser/resources/md_downloads/item.html index 07ae040..30031f3d 100644 --- a/chrome/browser/resources/md_downloads/item.html +++ b/chrome/browser/resources/md_downloads/item.html
@@ -1,5 +1,10 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://downloads/browser_proxy.html"> +<link rel="import" href="chrome://downloads/constants.html"> +<link rel="import" href="chrome://downloads/i18n_setup.html"> +<link rel="import" href="chrome://downloads/icon_loader.html"> +<link rel="import" href="chrome://downloads/icons.html"> <link rel="import" href="chrome://resources/cr_elements/cr_icons_css.html"> <link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> @@ -13,11 +18,6 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-progress/paper-progress.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> -<link rel="import" href="chrome://downloads/browser_proxy.html"> -<link rel="import" href="chrome://downloads/constants.html"> -<link rel="import" href="chrome://downloads/i18n_setup.html"> -<link rel="import" href="chrome://downloads/icon_loader.html"> -<link rel="import" href="chrome://downloads/icons.html"> <dom-module id="downloads-item"> <template> @@ -67,6 +67,11 @@ border: 1px var(--google-grey-300) solid; } + :host-context([dark]) #content:not(.is-active) { + background: none; /* override */ + border-color: rgba(var(--google-grey-800-rgb), .8); + } + #details { border-inline-start: 1px #d8d8d8 solid; display: flex; @@ -79,14 +84,26 @@ padding-top: 16px; } + :host-context([dark]) #details { + border-color: rgba(var(--google-grey-800-rgb), .8); + } + #content:not(.is-active) #details { color: rgba(27, 27, 27, .6); } + :host-context([dark]) #content:not(.is-active) #details { + color: rgba(var(--google-grey-500-rgb), .6); + } + #content:not(.is-active) #name { text-decoration: line-through; } + :host-context([dark]) #content:not(.is-active) #name { + color: var(--google-grey-500); + } + .icon-wrapper { align-self: center; flex: none; @@ -137,7 +154,8 @@ word-break: break-all; } - .is-active :-webkit-any(#name, #file-link, #show) { + :host-context(html:not([dark])) .is-active + :-webkit-any(#name, #file-link, #show) { color: var(--google-blue-600); } @@ -216,6 +234,10 @@ width: 32px; } + :host-context([dark]) #remove-wrapper > paper-icon-button-light { + color: var(--google-grey-500); + } + #incognito { bottom: 20px; content: -webkit-image-set(
diff --git a/chrome/browser/resources/md_downloads/manager.html b/chrome/browser/resources/md_downloads/manager.html index 6af77258..621f454f 100644 --- a/chrome/browser/resources/md_downloads/manager.html +++ b/chrome/browser/resources/md_downloads/manager.html
@@ -1,5 +1,11 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://downloads/browser_proxy.html"> +<link rel="import" href="chrome://downloads/constants.html"> +<link rel="import" href="chrome://downloads/i18n_setup.html"> +<link rel="import" href="chrome://downloads/item.html"> +<link rel="import" href="chrome://downloads/search_service.html"> +<link rel="import" href="chrome://downloads/toolbar.html"> <link rel="import" href="chrome://resources/cr_components/managed_footnote/managed_footnote.html"> <link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> @@ -9,12 +15,6 @@ <link rel="import" href="chrome://resources/html/util.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-a11y-announcer/iron-a11y-announcer.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html"> -<link rel="import" href="chrome://downloads/browser_proxy.html"> -<link rel="import" href="chrome://downloads/constants.html"> -<link rel="import" href="chrome://downloads/i18n_setup.html"> -<link rel="import" href="chrome://downloads/item.html"> -<link rel="import" href="chrome://downloads/search_service.html"> -<link rel="import" href="chrome://downloads/toolbar.html"> <dom-module id="downloads-manager"> <template> @@ -30,6 +30,10 @@ @apply --cr-page-host; } + :host-context([dark]) { + color: var(--cr-secondary-text-color); + } + #toolbar { z-index: 1; } @@ -75,6 +79,10 @@ min-height: min-content; } + :host-context([dark]) #no-downloads { + color: var(--cr-secondary-text-color); + } + #no-downloads .illustration { background: -webkit-image-set( url(chrome://downloads/1x/no_downloads.png) 1x,
diff --git a/chrome/browser/resources/md_downloads/toolbar.html b/chrome/browser/resources/md_downloads/toolbar.html index 279617e..9dae4cb 100644 --- a/chrome/browser/resources/md_downloads/toolbar.html +++ b/chrome/browser/resources/md_downloads/toolbar.html
@@ -2,16 +2,17 @@ <link rel="import" href="chrome://downloads/search_service.html"> <link rel="import" href="chrome://downloads/browser_proxy.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_toolbar/cr_toolbar.html"> <link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html"> +<link rel="import" href="chrome://resources/cr_elements/icons.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="chrome://resources/html/util.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_toolbar/cr_toolbar.html"> -<link rel="import" href="chrome://resources/cr_elements/icons.html"> <dom-module id="downloads-toolbar"> <template> @@ -28,6 +29,10 @@ flex: 1; } + :host-context([dark]) #toolbar { + color: var(--cr-primary-text-color); + } + #moreActionsContainer { --iron-icon-height: 20px; --iron-icon-width: 20px;
diff --git a/chrome/browser/resources/print_preview/cloud_print_interface.js b/chrome/browser/resources/print_preview/cloud_print_interface.js index 2cd934d..0f6f1d1 100644 --- a/chrome/browser/resources/print_preview/cloud_print_interface.js +++ b/chrome/browser/resources/print_preview/cloud_print_interface.js
@@ -14,7 +14,6 @@ PRINTER_DONE: 'cloudprint.CloudPrintInterface.PRINTER_DONE', PRINTER_FAILED: 'cloudprint.CloudPrintInterface.PRINTER_FAILED', PROCESS_INVITE_DONE: 'cloudprint.CloudPrintInterface.PROCESS_INVITE_DONE', - PROCESS_INVITE_FAILED: 'cloudprint.CloudPrintInterface.PROCESS_INVITE_FAILED', SEARCH_DONE: 'cloudprint.CloudPrintInterface.SEARCH_DONE', SEARCH_FAILED: 'cloudprint.CloudPrintInterface.SEARCH_FAILED', SUBMIT_DONE: 'cloudprint.CloudPrintInterface.SUBMIT_DONE', @@ -25,25 +24,19 @@ * @typedef {{ * user: string, * origin: !print_preview.DestinationOrigin, - * printers: (!Array<!print_preview.Destination>|undefined) + * printers: (!Array<!print_preview.Destination>|undefined), + * searchDone: boolean, * }} */ -cloudprint.CloudPrintInterfaceSearchDoneEvent; - -/** - * @typedef {{ - * printer: !print_preview.Destination, - * }} - */ -cloudprint.CloudPrintInterfacePrinterDoneEvent; +cloudprint.CloudPrintInterfaceSearchDoneDetail; /** * @typedef {{ * destinationId: string, - * destinationOrigin: !print_preview.DestinationOrigin, + * origin: !print_preview.DestinationOrigin, * }} */ -cloudprint.CloudPrintInterfacePrinterFailedEvent; +cloudprint.CloudPrintInterfacePrinterFailedDetail; /** * @typedef {{ @@ -51,21 +44,17 @@ * user: string, * }} */ -cloudprint.CloudPrintInterfaceInvitesDoneEvent; - -/** - * @typedef {{ - * user: string, - * }} - */ -cloudprint.CloudPrintInterfaceInvitesFailedEvent; +cloudprint.CloudPrintInterfaceInvitesDoneDetail; /** * @typedef {{ * invitation: !print_preview.Invitation, + * printer: ?print_preview.Destination, + * accept: boolean, + * user: string, * }} */ -cloudprint.CloudPrintInterfaceProcessInviteEvent; +cloudprint.CloudPrintInterfaceProcessInviteDetail; cr.define('cloudprint', function() { /** @interface */
diff --git a/chrome/browser/resources/print_preview/cloud_print_interface_js.js b/chrome/browser/resources/print_preview/cloud_print_interface_js.js index 6a115e2..d92ff2e 100644 --- a/chrome/browser/resources/print_preview/cloud_print_interface_js.js +++ b/chrome/browser/resources/print_preview/cloud_print_interface_js.js
@@ -287,26 +287,25 @@ } /** - * Creates a Google Cloud Print interface error that is ready to dispatch. - * @param {!cloudprint.CloudPrintInterfaceEventType} type Type of the - * error. + * Creates an object containing information about the error based on the + * request. * @param {!cloudprint.CloudPrintRequest} request Request that has been * completed. - * @return {!Event} Google Cloud Print interface error event. + * @return {!{ status: number, + * errorCode: number, + * message: string, + * origin: !print_preview.DestinationOrigin }} Information + * about the error. * @private */ - createErrorEvent_(type, request) { - const errorEvent = new Event(type); - errorEvent.status = request.xhr.status; - if (request.xhr.status == 200) { - errorEvent.errorCode = request.result['errorCode']; - errorEvent.message = request.result['message']; - } else { - errorEvent.errorCode = 0; - errorEvent.message = ''; - } - errorEvent.origin = request.origin; - return errorEvent; + createErrorEventDetail_(request) { + const status200 = request.xhr.status === 200; + return { + status: request.xhr.status, + errorCode: status200 ? request.result['errorCode'] : 0, + message: status200 ? request.result['message'] : '', + origin: request.origin, + }; } /** @@ -407,7 +406,6 @@ activeUser = request.result && request.result['request'] && request.result['request']['user']; } - let event = null; if (request.xhr.status == 200 && request.result['success']) { // Extract printers. const printerListJson = request.result['printers'] || []; @@ -423,17 +421,24 @@ // Extract and store users. this.setUsers_(request); // Dispatch SEARCH_DONE event. - event = new Event(CloudPrintInterfaceEventType.SEARCH_DONE); - event.origin = request.origin; - event.printers = printerList; - event.isRecent = isRecent; + this.eventTarget_.dispatchEvent( + new CustomEvent(CloudPrintInterfaceEventType.SEARCH_DONE, { + detail: { + origin: request.origin, + printers: printerList, + isRecent: isRecent, + user: activeUser, + searchDone: lastRequestForThisOrigin, + } + })); } else { - event = this.createErrorEvent_( - CloudPrintInterfaceEventType.SEARCH_FAILED, request); + const errorEventDetail = this.createErrorEventDetail_(request); + errorEventDetail.user = activeUser; + errorEventDetail.searchDone = lastRequestForThisOrigin; + this.eventTarget_.dispatchEvent(new CustomEvent( + CloudPrintInterfaceEventType.SEARCH_FAILED, + {detail: errorEventDetail})); } - event.user = activeUser; - event.searchDone = lastRequestForThisOrigin; - this.eventTarget_.dispatchEvent(event); } /** @@ -443,7 +448,6 @@ * @private */ onInvitesDone_(request) { - let event = null; const activeUser = (request.result && request.result['request'] && request.result['request']['user']) || ''; @@ -460,14 +464,17 @@ } }); // Dispatch INVITES_DONE event. - event = new Event(CloudPrintInterfaceEventType.INVITES_DONE); - event.invitations = invitationList; + this.eventTarget_.dispatchEvent( + new CustomEvent(CloudPrintInterfaceEventType.INVITES_DONE, { + detail: { + invitations: invitationList, + user: activeUser, + } + })); } else { - event = this.createErrorEvent_( - CloudPrintInterfaceEventType.INVITES_FAILED, request); + this.eventTarget_.dispatchEvent(new CustomEvent( + CloudPrintInterfaceEventType.INVITES_FAILED, {detail: activeUser})); } - event.user = activeUser; - this.eventTarget_.dispatchEvent(event); } /** @@ -479,28 +486,27 @@ * @private */ onProcessInviteDone_(invitation, accept, request) { - let event = null; const activeUser = (request.result && request.result['request'] && request.result['request']['user']) || ''; - if (request.xhr.status == 200 && request.result['success']) { - event = new Event(CloudPrintInterfaceEventType.PROCESS_INVITE_DONE); - if (accept) { - try { - event.printer = cloudprint.parseCloudDestination( - request.result['printer'], request.origin, activeUser); - } catch (e) { - console.error('Failed to parse cloud print destination: ' + e); - } + let printer = null; + if (request.xhr.status == 200 && request.result['success'] && accept) { + try { + printer = cloudprint.parseCloudDestination( + request.result['printer'], request.origin, activeUser); + } catch (e) { + console.error('Failed to parse cloud print destination: ' + e); } - } else { - event = this.createErrorEvent_( - CloudPrintInterfaceEventType.PROCESS_INVITE_FAILED, request); } - event.invitation = invitation; - event.accept = accept; - event.user = activeUser; - this.eventTarget_.dispatchEvent(event); + this.eventTarget_.dispatchEvent( + new CustomEvent(CloudPrintInterfaceEventType.PROCESS_INVITE_DONE, { + detail: { + printer: printer, + invitation: invitation, + accept: accept, + user: activeUser, + } + })); } /** @@ -511,14 +517,14 @@ */ onSubmitDone_(request) { if (request.xhr.status == 200 && request.result['success']) { - const submitDoneEvent = - new Event(CloudPrintInterfaceEventType.SUBMIT_DONE); - submitDoneEvent.jobId = request.result['job']['id']; - this.eventTarget_.dispatchEvent(submitDoneEvent); + this.eventTarget_.dispatchEvent(new CustomEvent( + CloudPrintInterfaceEventType.SUBMIT_DONE, + {detail: request.result['job']['id']})); } else { - const errorEvent = this.createErrorEvent_( - CloudPrintInterfaceEventType.SUBMIT_FAILED, request); - this.eventTarget_.dispatchEvent(errorEvent); + const errorEventDetail = this.createErrorEventDetail_(request); + this.eventTarget_.dispatchEvent(new CustomEvent( + CloudPrintInterfaceEventType.SUBMIT_FAILED, + {detail: errorEventDetail})); } } @@ -567,16 +573,14 @@ JSON.stringify(printerJson)); return; } - const printerDoneEvent = - new Event(CloudPrintInterfaceEventType.PRINTER_DONE); - printerDoneEvent.printer = printer; - this.eventTarget_.dispatchEvent(printerDoneEvent); + this.eventTarget_.dispatchEvent(new CustomEvent( + CloudPrintInterfaceEventType.PRINTER_DONE, {detail: printer})); } else { - const errorEvent = this.createErrorEvent_( - CloudPrintInterfaceEventType.PRINTER_FAILED, request); - errorEvent.destinationId = destinationId; - errorEvent.destinationOrigin = request.origin; - this.eventTarget_.dispatchEvent(errorEvent); + const errorEventDetail = this.createErrorEventDetail_(request); + errorEventDetail.destinationId = destinationId; + this.eventTarget_.dispatchEvent(new CustomEvent( + CloudPrintInterfaceEventType.PRINTER_FAILED, + {detail: errorEventDetail})); } } }
diff --git a/chrome/browser/resources/print_preview/data/destination_store.js b/chrome/browser/resources/print_preview/data/destination_store.js index 7948ef7..e67d3ba 100644 --- a/chrome/browser/resources/print_preview/data/destination_store.js +++ b/chrome/browser/resources/print_preview/data/destination_store.js
@@ -518,11 +518,9 @@ if (capabilities) { this.selectedDestination_.capabilities = capabilities; - - cr.dispatchSimpleEvent( - this, - DestinationStore.EventType - .CACHED_SELECTED_DESTINATION_INFO_READY); + this.dispatchEvent( + new CustomEvent(DestinationStore.EventType + .SELECTED_DESTINATION_CAPABILITIES_READY)); } return true; } @@ -690,8 +688,8 @@ } if (destination == null) { this.selectedDestination_ = null; - cr.dispatchSimpleEvent( - this, DestinationStore.EventType.DESTINATION_SELECT); + this.dispatchEvent( + new CustomEvent(DestinationStore.EventType.DESTINATION_SELECT)); return; } @@ -715,8 +713,8 @@ .CLOUD_DUPLICATE_SELECTED); } // Notify about selected destination change. - cr.dispatchSimpleEvent( - this, DestinationStore.EventType.DESTINATION_SELECT); + this.dispatchEvent( + new CustomEvent(DestinationStore.EventType.DESTINATION_SELECT)); // Request destination capabilities from backend, since they are not // known yet. if (destination.capabilities == null) { @@ -768,26 +766,20 @@ /** * Removes the destination from the store and replaces it with a * destination created from the resolved destination properties, - * if any are reported. Then sends a - * PROVISIONAL_DESTINATION_RESOLVED event. + * if any are reported. Then returns the new destination. */ this.removeProvisionalDestination_(destination.id); const parsedDestination = print_preview.parseExtensionDestination(destinationInfo); this.insertIntoStore_(parsedDestination); - this.dispatchProvisionalDestinationResolvedEvent_( - destination.id, parsedDestination); return parsedDestination; }, () => { /** - * The provisional destination is removed from the store and a - * PROVISIONAL_DESTINATION_RESOLVED event is dispatched with a - * null destination. + * The provisional destination is removed from the store and + * null is returned. */ this.removeProvisionalDestination_(destination.id); - this.dispatchProvisionalDestinationResolvedEvent_( - destination.id, null); return null; }); } @@ -861,8 +853,6 @@ this.destinationSearchStatus_.set( type, print_preview.DestinationStorePrinterSearchStatus.DONE); }); - cr.dispatchSimpleEvent( - this, DestinationStore.EventType.DESTINATION_SEARCH_STARTED); } /** @@ -878,8 +868,6 @@ (opt_origin && origins.indexOf(opt_origin) < 0)) { this.cloudPrintInterface_.search( this.userInfo_.activeUser, opt_origin); - cr.dispatchSimpleEvent( - this, DestinationStore.EventType.DESTINATION_SEARCH_STARTED); } } } @@ -888,8 +876,8 @@ reloadUserCookieBasedDestinations() { const origins = this.loadedCloudOrigins_[this.userInfo_.activeUser] || []; if (origins.indexOf(print_preview.DestinationOrigin.COOKIES) >= 0) { - cr.dispatchSimpleEvent( - this, DestinationStore.EventType.DESTINATION_SEARCH_DONE); + this.dispatchEvent(new CustomEvent( + DestinationStore.EventType.DESTINATION_SEARCH_DONE)); } else { this.startLoadCloudDestinations( print_preview.DestinationOrigin.COOKIES); @@ -947,22 +935,6 @@ } /** - * Dispatches the PROVISIONAL_DESTINATION_RESOLVED event for id - * |provisionalId| and destination |destination|. - * @param {string} provisionalId The ID of the destination that was - * resolved. - * @param {?print_preview.Destination} destination Information about the - * destination if it was resolved successfully. - */ - dispatchProvisionalDestinationResolvedEvent_(provisionalId, destination) { - const event = new Event( - DestinationStore.EventType.PROVISIONAL_DESTINATION_RESOLVED); - event.provisionalId = provisionalId; - event.destination = destination; - this.dispatchEvent(event); - } - - /** * Inserts {@code destination} to the data store and dispatches a * DESTINATIONS_INSERTED event. * @param {!print_preview.Destination} destination Print destination to @@ -1010,8 +982,8 @@ * {@code autoSelectMatchingDestination_}. */ destinationsInserted_(opt_destination) { - cr.dispatchSimpleEvent( - this, DestinationStore.EventType.DESTINATIONS_INSERTED); + this.dispatchEvent( + new CustomEvent(DestinationStore.EventType.DESTINATIONS_INSERTED)); if (this.autoSelectMatchingDestination_) { const destinationsToSearch = opt_destination && [opt_destination] || this.destinations_; @@ -1030,12 +1002,11 @@ * @private */ sendSelectedDestinationUpdateEvent_() { - cr.dispatchSimpleEvent( - this, + this.dispatchEvent(new CustomEvent( this.selectedDestination_.shouldShowInvalidCertificateError ? DestinationStore.EventType.SELECTED_DESTINATION_UNSUPPORTED : DestinationStore.EventType - .SELECTED_DESTINATION_CAPABILITIES_READY); + .SELECTED_DESTINATION_CAPABILITIES_READY)); } /** @@ -1152,8 +1123,8 @@ this.autoSelectTimeout_ = setTimeout( this.selectDefaultDestination_.bind(this), DestinationStore.AUTO_SELECT_TIMEOUT_); - cr.dispatchSimpleEvent( - this, DestinationStore.EventType.DESTINATIONS_RESET); + this.dispatchEvent( + new CustomEvent(DestinationStore.EventType.DESTINATIONS_RESET)); } @@ -1165,8 +1136,8 @@ onDestinationSearchDone_(type) { this.destinationSearchStatus_.set( type, print_preview.DestinationStorePrinterSearchStatus.DONE); - cr.dispatchSimpleEvent( - this, DestinationStore.EventType.DESTINATION_SEARCH_DONE); + this.dispatchEvent( + new CustomEvent(DestinationStore.EventType.DESTINATION_SEARCH_DONE)); if (type === print_preview.PrinterType.EXTENSION_PRINTER) { this.endExtensionPrinterSearch_(); } @@ -1236,10 +1207,8 @@ 'Failed to get print capabilities for printer ' + destinationId); if (this.selectedDestination_ && this.selectedDestination_.id == destinationId) { - const event = - new Event(DestinationStore.EventType.SELECTED_DESTINATION_INVALID); - event.destinationId = destinationId; - this.dispatchEvent(event); + this.dispatchEvent(new CustomEvent( + DestinationStore.EventType.SELECTED_DESTINATION_INVALID)); } if (this.autoSelectMatchingDestination_ && this.autoSelectMatchingDestination_.matchIdAndOrigin( @@ -1251,26 +1220,29 @@ /** * Called when the /search call completes, either successfully or not. * In case of success, stores fetched destinations. - * @param {!cloudprint.CloudPrintInterfaceSearchDoneEvent} event Contains - * the request result. + * @param {!CustomEvent} event Contains the request result. * @private */ onCloudPrintSearchDone_(event) { - if (event.printers && event.printers.length > 0) { - this.insertDestinations_(event.printers); + const payload = + /** @type {!cloudprint.CloudPrintInterfaceSearchDoneDetail} */ ( + event.detail); + if (payload.printers && payload.printers.length > 0) { + this.insertDestinations_(payload.printers); if (this.selectFirstDestination_) { this.selectDestination(this.destinations_[0]); this.selectFirstDestination_ = false; } } - if (event.searchDone) { - const origins = this.loadedCloudOrigins_[event.user] || []; - if (origins.indexOf(event.origin) < 0) { - this.loadedCloudOrigins_[event.user] = origins.concat([event.origin]); + if (payload.searchDone) { + const origins = this.loadedCloudOrigins_[payload.user] || []; + if (origins.indexOf(payload.origin) < 0) { + this.loadedCloudOrigins_[payload.user] = + origins.concat([payload.origin]); } } - cr.dispatchSimpleEvent( - this, DestinationStore.EventType.DESTINATION_SEARCH_DONE); + this.dispatchEvent( + new CustomEvent(DestinationStore.EventType.DESTINATION_SEARCH_DONE)); this.sendNoPrinterEventIfNeeded_(); } @@ -1286,50 +1258,53 @@ } this.selectFirstDestination_ = false; - cr.dispatchSimpleEvent( - this, DestinationStore.EventType.NO_DESTINATIONS_FOUND); + this.dispatchEvent( + new CustomEvent(DestinationStore.EventType.NO_DESTINATIONS_FOUND)); } /** * Called when /printer call completes. Updates the specified destination's * print capabilities. - * @param {!cloudprint.CloudPrintInterfacePrinterDoneEvent} event Contains - * detailed information about the destination. + * @param {!CustomEvent} event Contains detailed information about the + * destination. * @private */ onCloudPrintPrinterDone_(event) { - this.updateDestination_(event.printer); + this.updateDestination_( + /** @type {!print_preview.Destination} */ (event.detail)); } /** * Called when the Google Cloud Print interface fails to lookup a * destination. Selects another destination if the failed destination was * the initial destination. - * @param {!cloudprint.CloudPrintInterfacePrinterFailedEvent} event - * Contains the ID of the destination that was failed to be looked up. + * @param {!CustomEvent} event Contains the ID of the destination that was + * failed to be looked up. * @private */ onCloudPrintPrinterFailed_(event) { + const eventDetail = + /** @type {!cloudprint.CloudPrintInterfacePrinterFailedDetail } */ ( + event.detail); if (this.autoSelectMatchingDestination_ && this.autoSelectMatchingDestination_.matchIdAndOrigin( - event.destinationId, event.destinationOrigin)) { + eventDetail.destinationId, eventDetail.origin)) { console.error( - 'Failed to fetch last used printer caps: ' + event.destinationId); + 'Failed to fetch last used printer caps: ' + + eventDetail.destinationId); this.selectDefaultDestination_(); } } /** * Called when printer sharing invitation was processed successfully. - * @param {Event} event Contains detailed information about the invite and - * newly accepted destination (if known). + * @param {!CustomEvent} event Contains detailed information about the + * invite and newly accepted destination (if known). * @private */ onCloudPrintProcessInviteDone_(event) { - if (event.accept && event.printer) { - // Hint the destination list to promote this new destination. - event.printer.isRecent = true; - this.insertDestination_(event.printer); + if (event.detail.accept && event.detail.printer) { + this.insertDestination_(event.detail.printer); } } @@ -1399,22 +1374,16 @@ } /** - * Event types dispatched by the data store. + * Event types dispatched by the destination store. * @enum {string} */ DestinationStore.EventType = { DESTINATION_SEARCH_DONE: 'print_preview.DestinationStore.DESTINATION_SEARCH_DONE', - DESTINATION_SEARCH_STARTED: - 'print_preview.DestinationStore.DESTINATION_SEARCH_STARTED', DESTINATION_SELECT: 'print_preview.DestinationStore.DESTINATION_SELECT', - DESTINATIONS_RESET: 'print_preview.DestinationStore.DESTINATIONS_RESET', DESTINATIONS_INSERTED: 'print_preview.DestinationStore.DESTINATIONS_INSERTED', - PROVISIONAL_DESTINATION_RESOLVED: - 'print_preview.DestinationStore.PROVISIONAL_DESTINATION_RESOLVED', - CACHED_SELECTED_DESTINATION_INFO_READY: - 'print_preview.DestinationStore.CACHED_SELECTED_DESTINATION_INFO_READY', + DESTINATIONS_RESET: 'print_preview.DestinationStore.DESTINATIONS_RESET', NO_DESTINATIONS_FOUND: 'print_preview.DestinationStore.NO_DESTINATIONS_FOUND', SELECTED_DESTINATION_CAPABILITIES_READY: 'print_preview.DestinationStore' +
diff --git a/chrome/browser/resources/print_preview/data/invitation_store.js b/chrome/browser/resources/print_preview/data/invitation_store.js index 24ef8cd..dd6d613 100644 --- a/chrome/browser/resources/print_preview/data/invitation_store.js +++ b/chrome/browser/resources/print_preview/data/invitation_store.js
@@ -96,15 +96,11 @@ this.tracker_.add( this.cloudPrintInterface_.getEventTarget(), cloudprint.CloudPrintInterfaceEventType.INVITES_FAILED, - this.onCloudPrintInvitesDone_.bind(this)); + this.onCloudPrintInvitesFailed_.bind(this)); this.tracker_.add( this.cloudPrintInterface_.getEventTarget(), cloudprint.CloudPrintInterfaceEventType.PROCESS_INVITE_DONE, this.onCloudPrintProcessInviteDone_.bind(this)); - this.tracker_.add( - this.cloudPrintInterface_.getEventTarget(), - cloudprint.CloudPrintInterfaceEventType.PROCESS_INVITE_FAILED, - this.onCloudPrintProcessInviteFailed_.bind(this)); } /** Initiates loading of cloud printer sharing invitations. */ @@ -118,8 +114,8 @@ if (this.loadStatus_.hasOwnProperty(this.userInfo_.activeUser)) { if (this.loadStatus_[this.userInfo_.activeUser] == print_preview.InvitationStoreLoadStatus.DONE) { - cr.dispatchSimpleEvent( - this, InvitationStore.EventType.INVITATION_SEARCH_DONE); + this.dispatchEvent(new CustomEvent( + InvitationStore.EventType.INVITATION_SEARCH_DONE)); } return; } @@ -161,54 +157,44 @@ /** * Called when printer sharing invitations are fetched. - * @param {!cloudprint.CloudPrintInterfaceInvitesDoneEvent} event Contains - * the list of invitations. + * @param {!CustomEvent} event Contains the list of invitations. * @private */ onCloudPrintInvitesDone_(event) { - this.loadStatus_[event.user] = + const invitesDoneDetail = + /** @type {!cloudprint.CloudPrintInterfaceInvitesDoneDetail} */ ( + event.detail); + this.loadStatus_[invitesDoneDetail.user] = print_preview.InvitationStoreLoadStatus.DONE; - this.invitations_[event.user] = event.invitations; + this.invitations_[invitesDoneDetail.user] = invitesDoneDetail.invitations; - cr.dispatchSimpleEvent( - this, InvitationStore.EventType.INVITATION_SEARCH_DONE); + this.dispatchEvent( + new CustomEvent(InvitationStore.EventType.INVITATION_SEARCH_DONE)); } /** * Called when printer sharing invitations fetch has failed. - * @param {!cloudprint.CloudPrintInterfaceInvitesFailedEvent} event + * @param {!CustomEvent} event * @private */ onCloudPrintInvitesFailed_(event) { - this.loadStatus_[event.user] = + this.loadStatus_[/** @type {string} */ (event.detail)] = print_preview.InvitationStoreLoadStatus.FAILED; } /** * Called when printer sharing invitation was processed successfully. - * @param {!cloudprint.CloudPrintInterfaceProcessInviteEvent} event - * Contains detailed information about the invite and newly accepted - * destination. + * @param {!CustomEvent} event Contains detailed information about the + * invite. * @private */ onCloudPrintProcessInviteDone_(event) { - this.invitationProcessed_(event.invitation); - cr.dispatchSimpleEvent( - this, InvitationStore.EventType.INVITATION_PROCESSED); - } - - /** - * Called when /printer call completes. Updates the specified destination's - * print capabilities. - * @param {!cloudprint.CloudPrintInterfaceProcessInviteEvent} event - * Contains detailed information about the invite and destination. - * @private - */ - onCloudPrintProcessInviteFailed_(event) { - this.invitationProcessed_(event.invitation); - // TODO: Display an error. - cr.dispatchSimpleEvent( - this, InvitationStore.EventType.INVITATION_PROCESSED); + this.invitationProcessed_( + /** @type {!cloudprint.CloudPrintInterfaceProcessInviteDetail} */ ( + event.detail) + .invitation); + this.dispatchEvent( + new CustomEvent(InvitationStore.EventType.INVITATION_PROCESSED)); } }
diff --git a/chrome/browser/resources/print_preview/new/app.js b/chrome/browser/resources/print_preview/new/app.js index 543fd1f..95510f7 100644 --- a/chrome/browser/resources/print_preview/new/app.js +++ b/chrome/browser/resources/print_preview/new/app.js
@@ -210,6 +210,10 @@ print_preview.DestinationStore.EventType .SELECTED_DESTINATION_UNSUPPORTED, this.onInvalidPrinter_.bind(this)); + this.tracker_.add( + this.destinationStore_, + print_preview.DestinationStore.EventType.SELECTED_DESTINATION_INVALID, + this.onInvalidPrinter_.bind(this)); this.nativeLayer_.getInitialSettings().then( this.onInitialSettingsSet_.bind(this)); }, @@ -569,6 +573,11 @@ }, /** @private */ + onInvalidPrinterCapabilities_: function() { + this.previewState_ = print_preview_new.PreviewAreaState.INVALID_SETTINGS; + }, + + /** @private */ onPreviewAreaStateChanged_: function() { switch (this.previewState_) { case print_preview_new.PreviewAreaState.PREVIEW_FAILED: @@ -595,26 +604,29 @@ /** * Called when there was an error communicating with Google Cloud print. * Displays an error message in the print header. - * @param {!Event} event Contains the error message. + * @param {!CustomEvent} event Contains the error message. * @private */ onCloudPrintError_: function(event) { - if (event.status == 0) { + if (event.detail.status == 0) { return; // Ignore, the system does not have internet connectivity. } - if (event.status == 403) { + if (event.detail.status == 403) { if (!this.isInAppKioskMode_) { this.$.destinationSettings.showCloudPrintPromo(); } } else { - this.errorMessage_ = event.message; + this.errorMessage_ = event.detail.message; this.$.state.transitTo(print_preview_new.State.FATAL_ERROR); } - if (event.status == 200) { + if (event.detail.status == 200) { console.error( - `Google Cloud Print Error: (${event.errorCode}) ${event.message}`); + 'Google Cloud Print Error: ' + + `(${event.detail.errorCode}) ${event.detail.message}`); } else { - console.error(`Google Cloud Print Error: HTTP status ${event.status}`); + console.error( + 'Google Cloud Print Error: ' + + `HTTP status ${event.detail.status}`); } },
diff --git a/chrome/browser/signin/chrome_signin_client_unittest.cc b/chrome/browser/signin/chrome_signin_client_unittest.cc index 93811cf..33f6e8f 100644 --- a/chrome/browser/signin/chrome_signin_client_unittest.cc +++ b/chrome/browser/signin/chrome_signin_client_unittest.cc
@@ -22,7 +22,6 @@ #include "components/signin/core/browser/account_consistency_method.h" #include "content/public/browser/network_service_instance.h" #include "content/public/test/test_browser_thread_bundle.h" -#include "google_apis/gaia/fake_oauth2_token_service.h" #include "services/network/test/test_network_connection_tracker.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -136,24 +135,12 @@ MOCK_METHOD1(ShowUserManager, void(const base::FilePath&)); MOCK_METHOD1(LockForceSigninProfile, void(const base::FilePath&)); -}; -class MockSigninManager : public SigninManager { - public: - explicit MockSigninManager(SigninClient* client) - : SigninManager(client, - nullptr, - &fake_service_, - nullptr, - signin::AccountConsistencyMethod::kDisabled) {} - - MOCK_METHOD4(OnSignoutDecisionReached, + MOCK_METHOD4(SignOutCallback, void(signin_metrics::ProfileSignout, signin_metrics::SignoutDelete, - RemoveAccountsOption remove_option, + SigninManager::RemoveAccountsOption remove_option, SigninClient::SignoutDecision signout_decision)); - - AccountTrackerService fake_service_; }; class ChromeSigninClientSignoutTest : public BrowserWithTestWindowTest { @@ -163,7 +150,6 @@ signin_util::SetForceSigninForTesting(true); CreateClient(browser()->profile()); - manager_ = std::make_unique<MockSigninManager>(client_.get()); } void TearDown() override { @@ -173,12 +159,19 @@ void CreateClient(Profile* profile) { client_ = std::make_unique<MockChromeSigninClient>(profile); - token_service_ = std::make_unique<FakeOAuth2TokenService>(); + } + + void PreSignOut(signin_metrics::ProfileSignout source_metric, + signin_metrics::SignoutDelete delete_metric) { + client_->PreSignOut( + base::BindOnce(&MockChromeSigninClient::SignOutCallback, + base::Unretained(client_.get()), source_metric, + delete_metric, + SigninManager::RemoveAccountsOption::kRemoveAllAccounts), + source_metric); } std::unique_ptr<MockChromeSigninClient> client_; - std::unique_ptr<FakeOAuth2TokenService> token_service_; - std::unique_ptr<MockSigninManager> manager_; }; TEST_F(ChromeSigninClientSignoutTest, SignOut) { @@ -191,14 +184,14 @@ .Times(1); EXPECT_CALL(*client_, LockForceSigninProfile(browser()->profile()->GetPath())) .Times(1); - EXPECT_CALL(*manager_, - OnSignoutDecisionReached( - source_metric, delete_metric, - SigninManager::RemoveAccountsOption::kRemoveAllAccounts, - SigninClient::SignoutDecision::ALLOW_SIGNOUT)) + EXPECT_CALL( + *client_, + SignOutCallback(source_metric, delete_metric, + SigninManager::RemoveAccountsOption::kRemoveAllAccounts, + SigninClient::SignoutDecision::ALLOW_SIGNOUT)) .Times(1); - manager_->SignOut(source_metric, delete_metric); + PreSignOut(source_metric, delete_metric); } TEST_F(ChromeSigninClientSignoutTest, SignOutWithoutManager) { @@ -207,40 +200,41 @@ signin_metrics::SignoutDelete delete_metric = signin_metrics::SignoutDelete::IGNORE_METRIC; - MockSigninManager other_manager(client_.get()); - other_manager.CopyCredentialsFrom(*manager_.get()); + // Call the method below instead calling SigninManager::CopyCredentialsFrom, + // keeping the same behavior. + client_->AfterCredentialsCopied(); EXPECT_CALL(*client_, ShowUserManager(browser()->profile()->GetPath())) .Times(0); EXPECT_CALL(*client_, LockForceSigninProfile(browser()->profile()->GetPath())) .Times(1); - EXPECT_CALL(*manager_, - OnSignoutDecisionReached( - source_metric, delete_metric, - SigninManager::RemoveAccountsOption::kRemoveAllAccounts, - SigninClient::SignoutDecision::ALLOW_SIGNOUT)) + EXPECT_CALL( + *client_, + SignOutCallback(source_metric, delete_metric, + SigninManager::RemoveAccountsOption::kRemoveAllAccounts, + SigninClient::SignoutDecision::ALLOW_SIGNOUT)) .Times(1); - manager_->SignOut(source_metric, delete_metric); - ::testing::Mock::VerifyAndClearExpectations(manager_.get()); + PreSignOut(source_metric, delete_metric); + + ::testing::Mock::VerifyAndClearExpectations(client_.get()); EXPECT_CALL(*client_, ShowUserManager(browser()->profile()->GetPath())) .Times(1); EXPECT_CALL(*client_, LockForceSigninProfile(browser()->profile()->GetPath())) .Times(1); - EXPECT_CALL(*manager_, - OnSignoutDecisionReached( - source_metric, delete_metric, - SigninManager::RemoveAccountsOption::kRemoveAllAccounts, - SigninClient::SignoutDecision::ALLOW_SIGNOUT)) + EXPECT_CALL( + *client_, + SignOutCallback(source_metric, delete_metric, + SigninManager::RemoveAccountsOption::kRemoveAllAccounts, + SigninClient::SignoutDecision::ALLOW_SIGNOUT)) .Times(1); - manager_->SignOut(source_metric, delete_metric); + PreSignOut(source_metric, delete_metric); } TEST_F(ChromeSigninClientSignoutTest, SignOutWithoutForceSignin) { signin_util::SetForceSigninForTesting(false); CreateClient(browser()->profile()); - manager_ = std::make_unique<MockSigninManager>(client_.get()); signin_metrics::ProfileSignout source_metric = signin_metrics::ProfileSignout::USER_CLICKED_SIGNOUT_SETTINGS; @@ -251,13 +245,13 @@ .Times(0); EXPECT_CALL(*client_, LockForceSigninProfile(browser()->profile()->GetPath())) .Times(0); - EXPECT_CALL(*manager_, - OnSignoutDecisionReached( - source_metric, delete_metric, - SigninManager::RemoveAccountsOption::kRemoveAllAccounts, - SigninClient::SignoutDecision::ALLOW_SIGNOUT)) + EXPECT_CALL( + *client_, + SignOutCallback(source_metric, delete_metric, + SigninManager::RemoveAccountsOption::kRemoveAllAccounts, + SigninClient::SignoutDecision::ALLOW_SIGNOUT)) .Times(1); - manager_->SignOut(source_metric, delete_metric); + PreSignOut(source_metric, delete_metric); } class ChromeSigninClientSignoutSourceTest @@ -306,20 +300,19 @@ std::unique_ptr<TestingProfile> profile = builder.Build(); CreateClient(profile.get()); - manager_ = std::make_unique<MockSigninManager>(client_.get()); ASSERT_TRUE(signin_util::IsUserSignoutAllowedForProfile(profile.get())); // Verify SigninManager gets callback indicating sign-out is always allowed. signin_metrics::SignoutDelete delete_metric = signin_metrics::SignoutDelete::IGNORE_METRIC; - EXPECT_CALL(*manager_, - OnSignoutDecisionReached( - signout_source, delete_metric, - SigninManager::RemoveAccountsOption::kRemoveAllAccounts, - SigninClient::SignoutDecision::ALLOW_SIGNOUT)) + EXPECT_CALL( + *client_, + SignOutCallback(signout_source, delete_metric, + SigninManager::RemoveAccountsOption::kRemoveAllAccounts, + SigninClient::SignoutDecision::ALLOW_SIGNOUT)) .Times(1); - manager_->SignOut(signout_source, delete_metric); + PreSignOut(signout_source, delete_metric); } #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_MACOSX) @@ -331,7 +324,6 @@ std::unique_ptr<TestingProfile> profile = builder.Build(); CreateClient(profile.get()); - manager_ = std::make_unique<MockSigninManager>(client_.get()); ASSERT_TRUE(signin_util::IsUserSignoutAllowedForProfile(profile.get())); signin_util::SetUserSignoutAllowedForProfile(profile.get(), false); @@ -345,14 +337,14 @@ : SigninClient::SignoutDecision::ALLOW_SIGNOUT; signin_metrics::SignoutDelete delete_metric = signin_metrics::SignoutDelete::IGNORE_METRIC; - EXPECT_CALL(*manager_, - OnSignoutDecisionReached( - signout_source, delete_metric, - SigninManager::RemoveAccountsOption::kRemoveAllAccounts, - signout_decision)) + EXPECT_CALL( + *client_, + SignOutCallback(signout_source, delete_metric, + SigninManager::RemoveAccountsOption::kRemoveAllAccounts, + signout_decision)) .Times(1); - manager_->SignOut(signout_source, delete_metric); + PreSignOut(signout_source, delete_metric); } #endif
diff --git a/chrome/browser/signin/dice_response_handler_unittest.cc b/chrome/browser/signin/dice_response_handler_unittest.cc index 0eb3db7..6ff7c2d8 100644 --- a/chrome/browser/signin/dice_response_handler_unittest.cc +++ b/chrome/browser/signin/dice_response_handler_unittest.cc
@@ -34,6 +34,7 @@ #include "content/public/test/test_browser_thread_bundle.h" #include "google_apis/gaia/fake_oauth2_token_service_delegate.h" #include "services/identity/public/cpp/identity_test_environment.h" +#include "services/identity/public/cpp/identity_test_utils.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -44,10 +45,7 @@ namespace { const char kAuthorizationCode[] = "authorization_code"; -const char kEmail[] = "email"; -const char kGaiaID[] = "gaia_id_for_email"; // This matches the gaia_id value - // to be used by - // IdentityTestEnvironment. +const char kEmail[] = "test@email.com"; const int kSessionIndex = 42; // TestSigninClient implementation that intercepts the GaiaAuthConsumer and @@ -80,28 +78,6 @@ DISALLOW_COPY_AND_ASSIGN(DiceTestSigninClient); }; -// Checks if OnRefreshTokenAvailable() has been called for the specified -// account. -class DiceTestTokenServiceObserver : public OAuth2TokenService::Observer { - public: - explicit DiceTestTokenServiceObserver(const std::string& account_id) - : account_id_(account_id) {} - - bool token_received() { return token_received_; } - - private: - // OAuth2TokenServiceObserver: - void OnRefreshTokenAvailable(const std::string& account_id) override { - if (account_id == account_id_) - token_received_ = true; - } - - bool token_received_ = false; - std::string account_id_; - - DISALLOW_COPY_AND_ASSIGN(DiceTestTokenServiceObserver); -}; - class DiceResponseHandlerTest : public testing::Test, public AccountReconcilor::Observer { public: @@ -188,7 +164,7 @@ DiceResponseParams dice_params; dice_params.user_intention = action; DiceResponseParams::AccountInfo account_info; - account_info.gaia_id = kGaiaID; + account_info.gaia_id = identity::GetTestGaiaIdForEmail(kEmail); account_info.email = kEmail; account_info.session_index = kSessionIndex; switch (action) { @@ -215,12 +191,6 @@ return dice_params; } - std::string GetRefreshToken(const std::string& account_id) { - return static_cast<FakeOAuth2TokenServiceDelegate*>( - token_service_.GetDelegate()) - ->GetRefreshToken(account_id); - } - // AccountReconcilor::Observer: void OnBlockReconcile() override { ++reconcilor_blocked_count_; } void OnUnblockReconcile() override { ++reconcilor_unblocked_count_; } @@ -501,21 +471,19 @@ TEST_F(DiceResponseHandlerTest, SignoutMainAccount) { InitializeDiceResponseHandler(signin::AccountConsistencyMethod::kDice); - const char kSecondaryGaiaID[] = "secondary_account"; const char kSecondaryEmail[] = "other@gmail.com"; DiceResponseParams dice_params = MakeDiceParams(DiceAction::SIGNOUT); const auto& dice_account_info = dice_params.signout_info->account_infos[0]; - std::string secondary_account_id = account_tracker_service_.SeedAccountInfo( - kSecondaryGaiaID, kSecondaryEmail); // User is signed in to Chrome, and has some refresh token for a secondary // account. AccountInfo account_info = identity_test_env_.MakePrimaryAccountAvailable(dice_account_info.email); - identity_test_env_.SetRefreshTokenForAccount(secondary_account_id); + AccountInfo secondary_account_info = + identity_test_env_.MakeAccountAvailable(kSecondaryEmail); EXPECT_TRUE( identity_manager()->HasAccountWithRefreshToken(account_info.account_id)); - EXPECT_TRUE( - identity_manager()->HasAccountWithRefreshToken(secondary_account_id)); + EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken( + secondary_account_info.account_id)); EXPECT_TRUE(identity_manager()->HasPrimaryAccount()); // Receive signout response for the main account. dice_response_handler_->ProcessDiceHeader( @@ -525,12 +493,22 @@ // secondary account is untouched. EXPECT_TRUE( identity_manager()->HasAccountWithRefreshToken(account_info.account_id)); - EXPECT_EQ(MutableProfileOAuth2TokenServiceDelegate::kInvalidRefreshToken, - GetRefreshToken(account_info.account_id)); EXPECT_TRUE( - identity_manager()->HasAccountWithRefreshToken(secondary_account_id)); - EXPECT_EQ(std::string("refresh_token_for_") + secondary_account_id, - GetRefreshToken(secondary_account_id)); + identity_manager()->HasAccountWithRefreshTokenInPersistentErrorState( + account_info.account_id)); + auto error = identity_manager()->GetErrorStateOfRefreshTokenForAccount( + account_info.account_id); + EXPECT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS, error.state()); + EXPECT_EQ(GoogleServiceAuthError::InvalidGaiaCredentialsReason:: + CREDENTIALS_REJECTED_BY_CLIENT, + error.GetInvalidGaiaCredentialsReason()); + + EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken( + secondary_account_info.account_id)); + EXPECT_FALSE( + identity_manager()->HasAccountWithRefreshTokenInPersistentErrorState( + secondary_account_info.account_id)); + EXPECT_TRUE(identity_manager()->HasPrimaryAccount()); // Check that the reconcilor was not blocked. EXPECT_EQ(0, reconcilor_blocked_count_); @@ -540,24 +518,22 @@ TEST_F(DiceResponseHandlerTest, MigrationSignout) { InitializeDiceResponseHandler( signin::AccountConsistencyMethod::kDiceMigration); - const char kSecondaryGaiaID[] = "secondary_account"; const char kSecondaryEmail[] = "other@gmail.com"; DiceResponseParams dice_params = MakeDiceParams(DiceAction::SIGNOUT); - dice_params.signout_info->account_infos.emplace_back(kSecondaryGaiaID, - kSecondaryEmail, 1); + dice_params.signout_info->account_infos.emplace_back( + identity::GetTestGaiaIdForEmail(kSecondaryEmail), kSecondaryEmail, 1); const auto& main_account_info = dice_params.signout_info->account_infos[0]; - std::string secondary_account_id = account_tracker_service_.SeedAccountInfo( - kSecondaryGaiaID, kSecondaryEmail); // User is signed in to Chrome, and has some refresh token for a secondary // account. AccountInfo account_info = identity_test_env_.MakePrimaryAccountAvailable(main_account_info.email); - identity_test_env_.SetRefreshTokenForAccount(secondary_account_id); + AccountInfo secondary_account_info = + identity_test_env_.MakeAccountAvailable(kSecondaryEmail); EXPECT_TRUE( identity_manager()->HasAccountWithRefreshToken(account_info.account_id)); - EXPECT_TRUE( - identity_manager()->HasAccountWithRefreshToken(secondary_account_id)); + EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken( + secondary_account_info.account_id)); EXPECT_TRUE(identity_manager()->HasPrimaryAccount()); // Receive signout response for all accounts. @@ -567,8 +543,8 @@ // User is not signed out from Chrome, only the secondary token is deleted. EXPECT_TRUE( identity_manager()->HasAccountWithRefreshToken(account_info.account_id)); - EXPECT_FALSE( - identity_manager()->HasAccountWithRefreshToken(secondary_account_id)); + EXPECT_FALSE(identity_manager()->HasAccountWithRefreshToken( + secondary_account_info.account_id)); EXPECT_TRUE(identity_manager()->HasPrimaryAccount()); // Check that the reconcilor was not blocked. EXPECT_EQ(0, reconcilor_blocked_count_); @@ -579,15 +555,16 @@ InitializeDiceResponseHandler(signin::AccountConsistencyMethod::kDice); const char kMainEmail[] = "main@gmail.com"; DiceResponseParams dice_params = MakeDiceParams(DiceAction::SIGNOUT); - const auto& account_info = dice_params.signout_info->account_infos[0]; - std::string account_id = account_tracker_service_.SeedAccountInfo( - account_info.gaia_id, account_info.email); + const auto& secondary_dice_account_info = + dice_params.signout_info->account_infos[0]; // User is signed in to Chrome, and has some refresh token for a secondary // account. - auto main_account_info = + AccountInfo main_account_info = identity_test_env_.MakePrimaryAccountAvailable(kMainEmail); - identity_test_env_.SetRefreshTokenForAccount(account_id); - EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken(account_id)); + AccountInfo secondary_account_info = identity_test_env_.MakeAccountAvailable( + secondary_dice_account_info.email); + EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken( + secondary_account_info.account_id)); EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken( main_account_info.account_id)); EXPECT_TRUE(identity_manager()->HasPrimaryAccount()); @@ -597,7 +574,8 @@ // Only the token corresponding the the Dice parameter has been removed, and // the user is still signed in. - EXPECT_FALSE(identity_manager()->HasAccountWithRefreshToken(account_id)); + EXPECT_FALSE(identity_manager()->HasAccountWithRefreshToken( + secondary_account_info.account_id)); EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken( main_account_info.account_id)); EXPECT_TRUE(identity_manager()->HasPrimaryAccount()); @@ -605,29 +583,28 @@ TEST_F(DiceResponseHandlerTest, SignoutWebOnly) { InitializeDiceResponseHandler(signin::AccountConsistencyMethod::kDice); - const char kSecondaryGaiaID[] = "secondary_account"; const char kSecondaryEmail[] = "other@gmail.com"; DiceResponseParams dice_params = MakeDiceParams(DiceAction::SIGNOUT); - const auto& account_info = dice_params.signout_info->account_infos[0]; - std::string account_id = account_tracker_service_.SeedAccountInfo( - account_info.gaia_id, account_info.email); - std::string secondary_account_id = account_tracker_service_.SeedAccountInfo( - kSecondaryGaiaID, kSecondaryEmail); + const auto& dice_account_info = dice_params.signout_info->account_infos[0]; // User is NOT signed in to Chrome, and has some refresh tokens for two // accounts. - identity_test_env_.SetRefreshTokenForAccount(account_id); - identity_test_env_.SetRefreshTokenForAccount(secondary_account_id); - EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken(account_id)); + AccountInfo account_info = + identity_test_env_.MakeAccountAvailable(dice_account_info.email); + AccountInfo secondary_account_info = + identity_test_env_.MakeAccountAvailable(kSecondaryEmail); EXPECT_TRUE( - identity_manager()->HasAccountWithRefreshToken(secondary_account_id)); + identity_manager()->HasAccountWithRefreshToken(account_info.account_id)); + EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken( + secondary_account_info.account_id)); EXPECT_FALSE(identity_manager()->HasPrimaryAccount()); // Receive signout response. dice_response_handler_->ProcessDiceHeader( dice_params, std::make_unique<TestProcessDiceHeaderDelegate>(this)); // Only the token corresponding the the Dice parameter has been removed. - EXPECT_FALSE(identity_manager()->HasAccountWithRefreshToken(account_id)); - EXPECT_TRUE( - identity_manager()->HasAccountWithRefreshToken(secondary_account_id)); + EXPECT_FALSE( + identity_manager()->HasAccountWithRefreshToken(account_info.account_id)); + EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken( + secondary_account_info.account_id)); EXPECT_FALSE(identity_manager()->HasPrimaryAccount()); } @@ -661,8 +638,15 @@ 0u, dice_response_handler_->GetPendingDiceTokenFetchersCountForTesting()); EXPECT_TRUE( identity_manager()->HasAccountWithRefreshToken(account_info.account_id)); - EXPECT_EQ(MutableProfileOAuth2TokenServiceDelegate::kInvalidRefreshToken, - GetRefreshToken(account_info.account_id)); + EXPECT_TRUE( + identity_manager()->HasAccountWithRefreshTokenInPersistentErrorState( + account_info.account_id)); + auto error = identity_manager()->GetErrorStateOfRefreshTokenForAccount( + account_info.account_id); + EXPECT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS, error.state()); + EXPECT_EQ(GoogleServiceAuthError::InvalidGaiaCredentialsReason:: + CREDENTIALS_REJECTED_BY_CLIENT, + error.GetInvalidGaiaCredentialsReason()); } // Checks that signin in progress is not canceled by a signout for a different @@ -714,7 +698,9 @@ // Check that the right token is available. EXPECT_FALSE(identity_manager()->HasAccountWithRefreshToken(account_id_1)); EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken(account_id_2)); - EXPECT_EQ("refresh_token", GetRefreshToken(account_id_2)); + EXPECT_FALSE( + identity_manager()->HasAccountWithRefreshTokenInPersistentErrorState( + account_id_2)); } // Tests that the DiceResponseHandler is created for a normal profile but not
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 32c95502..dcf5c6b 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -2732,6 +2732,8 @@ "views/relaunch_notification/relaunch_required_timer.h", "views/relaunch_notification/relaunch_required_timer_internal.cc", "views/relaunch_notification/relaunch_required_timer_internal.h", + "views/relaunch_notification/wall_clock_timer.cc", + "views/relaunch_notification/wall_clock_timer.h", "views/sad_tab_view.cc", "views/sad_tab_view.h", "views/safe_browsing/password_reuse_modal_warning_dialog.cc",
diff --git a/chrome/browser/ui/views/relaunch_notification/relaunch_recommended_timer.h b/chrome/browser/ui/views/relaunch_notification/relaunch_recommended_timer.h index a9d1a208..3424468c 100644 --- a/chrome/browser/ui/views/relaunch_notification/relaunch_recommended_timer.h +++ b/chrome/browser/ui/views/relaunch_notification/relaunch_recommended_timer.h
@@ -8,7 +8,7 @@ #include "base/callback.h" #include "base/macros.h" #include "base/time/time.h" -#include "base/timer/timer.h" +#include "chrome/browser/ui/views/relaunch_notification/wall_clock_timer.h" // Timer that handles notification title refresh for relaunch recommended // notification. Created either by RelaunchRecommendedBubbleView for Chrome @@ -42,7 +42,7 @@ const base::TimeTicks upgrade_detected_time_; // A timer with which title refreshes are scheduled. - base::OneShotTimer refresh_timer_; + WallClockTimer refresh_timer_; // Callback which triggers the actual title update, which differs on Chrome // for desktop vs for Chrome OS.
diff --git a/chrome/browser/ui/views/relaunch_notification/relaunch_required_timer.h b/chrome/browser/ui/views/relaunch_notification/relaunch_required_timer.h index 17ad9b76..ce71f8c 100644 --- a/chrome/browser/ui/views/relaunch_notification/relaunch_required_timer.h +++ b/chrome/browser/ui/views/relaunch_notification/relaunch_required_timer.h
@@ -8,7 +8,7 @@ #include "base/callback.h" #include "base/macros.h" #include "base/time/time.h" -#include "base/timer/timer.h" +#include "chrome/browser/ui/views/relaunch_notification/wall_clock_timer.h" // Timer that handles notification title refresh for relaunch required // notification. Created either by RelaunchRequiredDialogView for Chrome @@ -44,7 +44,7 @@ base::TimeTicks deadline_; // A timer with which title refreshes are scheduled. - base::OneShotTimer refresh_timer_; + WallClockTimer refresh_timer_; // Callback which triggers the actual title update, which differs on Chrome // for desktop vs for Chrome OS.
diff --git a/chrome/browser/ui/views/relaunch_notification/wall_clock_timer.cc b/chrome/browser/ui/views/relaunch_notification/wall_clock_timer.cc new file mode 100644 index 0000000..a7cbd230 --- /dev/null +++ b/chrome/browser/ui/views/relaunch_notification/wall_clock_timer.cc
@@ -0,0 +1,76 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/relaunch_notification/wall_clock_timer.h" + +#include <utility> + +#include "base/power_monitor/power_monitor.h" +#include "base/time/clock.h" +#include "base/time/default_clock.h" +#include "base/time/default_tick_clock.h" +#include "base/time/tick_clock.h" + +WallClockTimer::WallClockTimer() : WallClockTimer(nullptr, nullptr) {} + +WallClockTimer::WallClockTimer(const base::Clock* clock, + const base::TickClock* tick_clock) + : timer_(tick_clock), + clock_(clock ? clock : base::DefaultClock::GetInstance()) {} + +WallClockTimer::~WallClockTimer() { + RemoveObserver(); +} + +void WallClockTimer::Start(const base::Location& posted_from, + base::TimeDelta delay, + base::OnceClosure user_task) { + user_task_ = std::move(user_task); + posted_from_ = posted_from; + delay_ = delay; + desired_run_time_ = Now() + delay_; + AddObserver(); + timer_.Start(posted_from_, delay, this, &WallClockTimer::RunUserTask); +} + +base::Time WallClockTimer::Now() const { + return clock_->Now(); +} + +void WallClockTimer::Stop() { + timer_.Stop(); + user_task_.Reset(); + RemoveObserver(); +} + +bool WallClockTimer::IsRunning() { + return timer_.IsRunning(); +} + +void WallClockTimer::RunUserTask() { + DCHECK(user_task_); + base::OnceClosure task = std::move(user_task_); + std::move(task).Run(); + RemoveObserver(); +} + +void WallClockTimer::OnResume() { + // This will actually restart timer with smaller delay + timer_.Start(posted_from_, desired_run_time_ - Now(), this, + &WallClockTimer::RunUserTask); +} + +void WallClockTimer::AddObserver() { + if (!observer_added_) { + base::PowerMonitor::Get()->AddObserver(this); + observer_added_ = true; + } +} + +void WallClockTimer::RemoveObserver() { + if (observer_added_) { + base::PowerMonitor::Get()->RemoveObserver(this); + observer_added_ = false; + } +}
diff --git a/chrome/browser/ui/views/relaunch_notification/wall_clock_timer.h b/chrome/browser/ui/views/relaunch_notification/wall_clock_timer.h new file mode 100644 index 0000000..8bd4cfc --- /dev/null +++ b/chrome/browser/ui/views/relaunch_notification/wall_clock_timer.h
@@ -0,0 +1,103 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_RELAUNCH_NOTIFICATION_WALL_CLOCK_TIMER_H_ +#define CHROME_BROWSER_UI_VIEWS_RELAUNCH_NOTIFICATION_WALL_CLOCK_TIMER_H_ + +#include "base/bind.h" +#include "base/callback.h" +#include "base/location.h" +#include "base/macros.h" +#include "base/power_monitor/power_observer.h" +#include "base/time/time.h" +#include "base/timer/timer.h" + +namespace base { +class Clock; +class TickClock; +} // namespace base + +// WallClockTimer is based on OneShotTimer and provides a simple timer API +// which is mostly similar to OneShotTimer's API. The main difference is that +// WallClockTimer is using Time (which is system-dependent) to schedule task. +// WallClockTimer calls you back once scheduled time has come. +// +// Comparison with OneShotTimer: WallClockTimer runs |user_task_| after |delay_| +// expires according to usual time, while OneShotTimer runs |user_task_| after +// |delay_| expires according to TimeTicks which freezes when power suspends +// (desktop falls asleep). +// +// The API is not thread safe. All methods must be called from the same +// sequence (not necessarily the construction sequence), except for the +// destructor. +// - The destructor may be called from any sequence when the timer is not +// running and there is no scheduled task active. +class WallClockTimer : public base::PowerObserver { + public: + WallClockTimer(); + WallClockTimer(const base::Clock* clock, const base::TickClock* tick_clock); + + ~WallClockTimer() override; + + // Start the timer to run at the given |delay| from now. If the timer is + // already running, it will be replaced to call the given |user_task|. + virtual void Start(const base::Location& posted_from, + base::TimeDelta delay, + base::OnceClosure user_task); + + // Start the timer to run at the given |delay| from now. If the timer is + // already running, it will be replaced to call a task formed from + // |reviewer->*method|. + template <class Receiver> + void Start(const base::Location& posted_from, + base::TimeDelta delay, + Receiver* receiver, + void (Receiver::*method)()) { + Start(posted_from, delay, + base::BindOnce(method, base::Unretained(receiver))); + } + + void Stop(); + + bool IsRunning(); + + // base::PowerObserver: + void OnResume() override; + + base::Time desired_run_time() const { return desired_run_time_; } + + private: + void AddObserver(); + + void RemoveObserver(); + + // Actually run scheduled task + void RunUserTask(); + + // Returns the current time count. + base::Time Now() const; + + bool observer_added_ = false; + + // Location in user code. + base::Location posted_from_; + + // Delay requested by user. + base::TimeDelta delay_; + + // The desired run time of |user_task_|. + base::Time desired_run_time_; + + base::OnceClosure user_task_; + + // Timer which should notify to run task in the period while system awake + base::OneShotTimer timer_; + + // The clock used to calculate the run time for scheduled tasks. + const base::Clock* const clock_; + + DISALLOW_COPY_AND_ASSIGN(WallClockTimer); +}; + +#endif // CHROME_BROWSER_UI_VIEWS_RELAUNCH_NOTIFICATION_WALL_CLOCK_TIMER_H_
diff --git a/chrome/browser/ui/views/relaunch_notification/wall_clock_timer_unittest.cc b/chrome/browser/ui/views/relaunch_notification/wall_clock_timer_unittest.cc new file mode 100644 index 0000000..7f9f0df --- /dev/null +++ b/chrome/browser/ui/views/relaunch_notification/wall_clock_timer_unittest.cc
@@ -0,0 +1,85 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/relaunch_notification/wall_clock_timer.h" + +#include <memory> +#include <utility> + +#include "base/macros.h" +#include "base/power_monitor/power_monitor.h" +#include "base/power_monitor/power_monitor_source.h" +#include "base/test/mock_callback.h" +#include "base/test/scoped_task_environment.h" +#include "base/test/simple_test_clock.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +class StubPowerMonitorSource : public base::PowerMonitorSource { + public: + // Use this method to send a power resume event. + void Resume() { ProcessPowerEvent(RESUME_EVENT); } + + // Use this method to send a power suspend event. + void Suspend() { ProcessPowerEvent(SUSPEND_EVENT); } + + // base::PowerMonitorSource: + void Shutdown() override {} + bool IsOnBatteryPowerImpl() override { return false; } +}; + +} // namespace + +class WallClockTimerTest : public ::testing::Test { + protected: + WallClockTimerTest() + : task_environment_( + base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME) { + auto mock_power_monitor_source = std::make_unique<StubPowerMonitorSource>(); + mock_power_monitor_source_ = mock_power_monitor_source.get(); + power_monitor_ = std::make_unique<base::PowerMonitor>( + std::move(mock_power_monitor_source)); + } + + std::unique_ptr<base::PowerMonitor> power_monitor_; + // Owned by power_monitor_. Use this to simulate a power suspend and resume. + StubPowerMonitorSource* mock_power_monitor_source_ = nullptr; + base::test::ScopedTaskEnvironment task_environment_; + + private: + DISALLOW_COPY_AND_ASSIGN(WallClockTimerTest); +}; + +TEST_F(WallClockTimerTest, PowerResume) { + ::testing::StrictMock<base::MockCallback<base::OnceClosure>> callback; + base::SimpleTestClock clock; + // Set up a WallClockTimer that will fire in one minute. + WallClockTimer wall_clock_timer(&clock, task_environment_.GetMockTickClock()); + auto delay = base::TimeDelta::FromMinutes(1); + auto start_time = base::Time::Now(); + clock.SetNow(start_time); + wall_clock_timer.Start(FROM_HERE, delay, callback.Get()); + EXPECT_EQ(wall_clock_timer.desired_run_time(), start_time + delay); + + mock_power_monitor_source_->Suspend(); + // Pretend that time jumps forward 30 seconds while the machine is suspended. + auto past_time = base::TimeDelta::FromSeconds(30); + clock.SetNow(start_time + past_time); + mock_power_monitor_source_->Resume(); + task_environment_.RunUntilIdle(); + // Ensure that the timer has not yet fired. + ::testing::Mock::VerifyAndClearExpectations(&callback); + EXPECT_EQ(wall_clock_timer.desired_run_time(), start_time + delay); + + // Expect that the timer fires at the desired run time. + EXPECT_CALL(callback, Run()); + // Both Time::Now() and |task_environment_| MockTickClock::Now() + // go forward by (|delay| - |past_time|): + clock.SetNow(start_time + delay); + task_environment_.FastForwardBy(delay - past_time); + ::testing::Mock::VerifyAndClearExpectations(&callback); + EXPECT_FALSE(wall_clock_timer.IsRunning()); +}
diff --git a/chrome/browser/ui/webui/app_management/app_management.mojom b/chrome/browser/ui/webui/app_management/app_management.mojom index 468f320..8b33207e 100644 --- a/chrome/browser/ui/webui/app_management/app_management.mojom +++ b/chrome/browser/ui/webui/app_management/app_management.mojom
@@ -27,12 +27,12 @@ // Browser interface. interface PageHandler { - GetApps(); + GetApps() => (array<App> apps); }; // Frontend interface. interface Page { - OnAppsAdded(array<App> apps); + OnAppAdded(App app); OnAppChanged(App update); OnAppRemoved(string app_id); };
diff --git a/chrome/browser/ui/webui/app_management/app_management_page_handler.cc b/chrome/browser/ui/webui/app_management/app_management_page_handler.cc index 0bde332..ef4e9ba 100644 --- a/chrome/browser/ui/webui/app_management/app_management_page_handler.cc +++ b/chrome/browser/ui/webui/app_management/app_management_page_handler.cc
@@ -12,6 +12,18 @@ #include "chrome/services/app_service/public/cpp/app_registry_cache.h" #include "chrome/services/app_service/public/mojom/types.mojom.h" +namespace { + +app_management::mojom::AppPtr CreateUIAppPtr(const apps::AppUpdate& update) { + return app_management::mojom::App::New( + update.AppId(), update.AppType(), update.Name(), + base::nullopt /*description*/, + apps::mojom::OptionalBool::kUnknown /*is_pinned*/, + base::nullopt /*version*/, base::nullopt /*size*/); +} + +} // namespace + AppManagementPageHandler::AppManagementPageHandler( app_management::mojom::PageHandlerRequest request, app_management::mojom::PagePtr page, @@ -22,7 +34,7 @@ AppManagementPageHandler::~AppManagementPageHandler() {} -void AppManagementPageHandler::GetApps() { +void AppManagementPageHandler::GetApps(GetAppsCallback callback) { apps::AppServiceProxy* proxy = apps::AppServiceProxy::Get(profile_); // TODO(crbug.com/826982): revisit pending decision on AppServiceProxy in @@ -32,13 +44,12 @@ std::vector<app_management::mojom::AppPtr> apps; proxy->Cache().ForEachApp([&apps](const apps::AppUpdate& update) { - apps.push_back(app_management::mojom::App::New( - update.AppId(), update.AppType(), update.Name(), - base::nullopt /*description*/, - apps::mojom::OptionalBool::kUnknown /*is_pinned*/, - base::nullopt /*version*/, base::nullopt /*size*/)); + apps.push_back(CreateUIAppPtr(update)); }); - page_->OnAppsAdded(std::move(apps)); + + Observe(&proxy->Cache()); + + std::move(callback).Run(std::move(apps)); } void AppManagementPageHandler::OnAppUpdate(const apps::AppUpdate& update) { @@ -48,9 +59,10 @@ return; } - page_->OnAppChanged(app_management::mojom::App::New( - update.AppId(), update.AppType(), update.Name(), - base::nullopt /*description*/, - apps::mojom::OptionalBool::kUnknown /*is_pinned*/, - base::nullopt /*version*/, base::nullopt /*size*/)); + if (update.ReadinessChanged() && + update.Readiness() == apps::mojom::Readiness::kReady) { + page_->OnAppAdded(CreateUIAppPtr(update)); + } else { + page_->OnAppChanged(CreateUIAppPtr(update)); + } }
diff --git a/chrome/browser/ui/webui/app_management/app_management_page_handler.h b/chrome/browser/ui/webui/app_management/app_management_page_handler.h index 0b5f710a..2e6274ea 100644 --- a/chrome/browser/ui/webui/app_management/app_management_page_handler.h +++ b/chrome/browser/ui/webui/app_management/app_management_page_handler.h
@@ -25,7 +25,7 @@ ~AppManagementPageHandler() override; // app_management::mojom::PageHandler: - void GetApps() override; + void GetApps(GetAppsCallback callback) override; private: // apps::AppRegistryCache::Observer overrides:
diff --git a/chrome/browser/ui/webui/app_management/app_management_ui.cc b/chrome/browser/ui/webui/app_management/app_management_ui.cc index 99ee1ef8..ff147e5f 100644 --- a/chrome/browser/ui/webui/app_management/app_management_ui.cc +++ b/chrome/browser/ui/webui/app_management/app_management_ui.cc
@@ -84,6 +84,10 @@ source->AddResourcePath("item.js", IDR_APP_MANAGEMENT_ITEM_JS); source->AddResourcePath("main_view.html", IDR_APP_MANAGEMENT_MAIN_VIEW_HTML); source->AddResourcePath("main_view.js", IDR_APP_MANAGEMENT_MAIN_VIEW_JS); + source->AddResourcePath("permission_view_header.html", + IDR_APP_MANAGEMENT_PERMISSION_VIEW_HEADER_HTML); + source->AddResourcePath("permission_view_header.js", + IDR_APP_MANAGEMENT_PERMISSION_VIEW_HEADER_JS); source->AddResourcePath("metadata_view.html", IDR_APP_MANAGEMENT_METADATA_VIEW_HTML); source->AddResourcePath("metadata_view.js",
diff --git a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc index ccb4860..682010b 100644 --- a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc +++ b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
@@ -696,6 +696,11 @@ form_element); } + void CheckFirstFillingResult(FillingResult result) { + histogram_tester_.ExpectUniqueSample( + "PasswordManager.FirstRendererFillingResult", result, 1); + } + void SubmitForm() { FormTracker* tracker = autofill_agent_->form_tracker_for_testing(); static_cast<content::RenderFrameObserver*>(tracker)->WillSubmitForm( @@ -767,6 +772,8 @@ // The username and password should have been autocompleted. CheckTextFieldsSuggestedState(kAliceUsername, true, kAlicePassword, true); + + CheckFirstFillingResult(FillingResult::kSuccess); } // Tests that we correctly fill forms having an empty 'action' attribute. @@ -804,6 +811,8 @@ SimulateOnFillPasswordForm(fill_data_); CheckTextFieldsSuggestedState(std::string(), false, std::string(), false); + + CheckFirstFillingResult(FillingResult::kPasswordElementIsNotAutocompleteable); } // Can still fill a password field if the username is set to a value that @@ -817,6 +826,8 @@ SimulateOnFillPasswordForm(fill_data_); CheckUsernameDOMStatePasswordSuggestedState(UTF16ToUTF8(username3_), false, UTF16ToUTF8(password3_), true); + + CheckFirstFillingResult(FillingResult::kSuccess); } // Fill username and password fields when username field contains a prefilled @@ -852,11 +863,13 @@ histogram_tester_.ExpectUniqueSample( "PasswordManager.PrefilledUsernameFillOutcome", PrefilledUsernameFillOutcome::kPrefilledPlaceholderUsernameOverridden, 1); + + CheckFirstFillingResult(FillingResult::kSuccess); } // Tests that if filling is invoked twice for the same autofill agent the -// prefilled username metrics are only logged once. -TEST_F(PasswordAutofillAgentTest, PrefilledUsernameMetricsOnlyLoggedOnce) { +// prefilled username and first filling metrics are only logged once. +TEST_F(PasswordAutofillAgentTest, MetricsOnlyLoggedOnce) { // Set the username element to a value from the prefilled values list. // Comparison should be insensitive to leading and trailing whitespaces. username_element_.SetValue( @@ -870,6 +883,8 @@ histogram_tester_.ExpectUniqueSample( "PasswordManager.PrefilledUsernameFillOutcome", PrefilledUsernameFillOutcome::kPrefilledPlaceholderUsernameOverridden, 1); + + CheckFirstFillingResult(FillingResult::kSuccess); } // Fill a password field if the stored username is a prefix of username in @@ -901,6 +916,9 @@ SimulateOnFillPasswordForm(fill_data_); CheckUsernameDOMStatePasswordSuggestedState(UTF16ToUTF8(prefilled_username), false, std::string(), false); + + CheckFirstFillingResult( + FillingResult::kUsernamePrefilledWithIncompatibleValue); } // Do not fill a password field if the field isn't readonly despite the stored @@ -928,6 +946,8 @@ SimulateOnFillPasswordForm(fill_data_); CheckUsernameDOMStatePasswordSuggestedState(std::string(), false, std::string(), false); + + CheckFirstFillingResult(FillingResult::kFoundNoPasswordForUsername); } // Tests that having a non-matching username precludes the autocomplete. @@ -941,6 +961,9 @@ // Neither field should be autocompleted. CheckUsernameDOMStatePasswordSuggestedState("bogus", false, std::string(), false); + + CheckFirstFillingResult( + FillingResult::kUsernamePrefilledWithIncompatibleValue); } // Don't try to complete a prefilled value that is a partial match @@ -992,6 +1015,8 @@ // Fields should still be empty. CheckTextFieldsSuggestedState(std::string(), false, std::string(), false); + + CheckFirstFillingResult(FillingResult::kNoFillableElementsFound); } TEST_F(PasswordAutofillAgentTest, NoAutocompleteForPasswordFieldUsernames) { @@ -1013,6 +1038,8 @@ // Fields should still be empty. CheckTextFieldsSuggestedState(std::string(), false, std::string(), false); + + CheckFirstFillingResult(FillingResult::kNoFillableElementsFound); } // Tests that having a matching username does not preclude the autocomplete. @@ -1026,6 +1053,8 @@ // The username and password should have been autocompleted. CheckUsernameDOMStatePasswordSuggestedState(kAliceUsername, true, kAlicePassword, true); + + CheckFirstFillingResult(FillingResult::kSuccess); } TEST_F(PasswordAutofillAgentTest, PasswordNotClearedOnEdit) { @@ -1057,6 +1086,8 @@ // No autocomplete should happen when text is entered in the username. CheckUsernameDOMStatePasswordSuggestedState(kAliceUsername, false, std::string(), false); + + CheckFirstFillingResult(FillingResult::kWaitForUsername); } TEST_F(PasswordAutofillAgentTest, IsWebElementVisibleTest) { @@ -1424,6 +1455,8 @@ ASCIIToUTF16(kAlicePassword))); CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); + + CheckFirstFillingResult(FillingResult::kWaitForUsername); } // Tests that |FillSuggestion| doesn't change non-empty non-autofilled username @@ -2304,6 +2337,38 @@ std::string(), false); } +// If credentials contain username+password but the form contains only a +// password field, we don't autofill on page load. +TEST_F(PasswordAutofillAgentTest, DontFillFormWithNoUsername_WithRendererIds) { + // Load a form with no username and update test data. + LoadHTML(kVisibleFormWithNoUsernameHTML); + UpdateOnlyPasswordElement(); + UpdateRendererIDs(); + + SimulateOnFillPasswordForm(fill_data_); + + // As the credential contains a username, but the form does not, the + // credential is not filled. + CheckFirstFillingResult(FillingResult::kFoundNoPasswordForUsername); +} + +// If credentials contain username+password but the form contains only a +// password field, we don't autofill on page load. +TEST_F(PasswordAutofillAgentTest, + DontFillFormWithNoUsername_WithoutRendererIds) { + // Load a form with no username and update test data. + LoadHTML(kVisibleFormWithNoUsernameHTML); + UpdateOnlyPasswordElement(); + UpdateOriginForHTML(kVisibleFormWithNoUsernameHTML); + fill_data_.username_field.name.clear(); + + SimulateOnFillPasswordForm(fill_data_); + + // As the credential contains a username, but the form does not, the + // credential is not filled. + CheckFirstFillingResult(FillingResult::kFoundNoPasswordForUsername); +} + TEST_F(PasswordAutofillAgentTest, FillOnAccountSelectOnlyNoUsername) { SetFillOnAccountSelect(); @@ -3608,6 +3673,8 @@ UpdateRendererIDs(); SimulateOnFillPasswordForm(fill_data_); CheckTextFieldsSuggestedState(kAliceUsername, true, kAlicePassword, true); + + CheckFirstFillingResult(FillingResult::kSuccess); } // Tests that the password form is filled as expected on load even if form/field
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 7621b57..5bd6051 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -4356,6 +4356,7 @@ "../browser/ui/views/payments/view_stack_unittest.cc", "../browser/ui/views/relaunch_notification/relaunch_notification_controller_unittest.cc", "../browser/ui/views/relaunch_notification/relaunch_required_timer_internal_unittest.cc", + "../browser/ui/views/relaunch_notification/wall_clock_timer_unittest.cc", "../browser/ui/views/status_icons/status_tray_win_unittest.cc", "../browser/ui/views/sync/bubble_sync_promo_view_unittest.cc", "../browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_unittest.cc",
diff --git a/chrome/test/data/webui/app_management/app_test.js b/chrome/test/data/webui/app_management/app_test.js index 293b64b..c2eddaf2 100644 --- a/chrome/test/data/webui/app_management/app_test.js +++ b/chrome/test/data/webui/app_management/app_test.js
@@ -3,11 +3,9 @@ // found in the LICENSE file. suite('<app-management-app>', function() { - test('loads', function(done) { - app_management.BrowserProxy.getInstance().handler.getApps(); - - let callbackRouter = - app_management.BrowserProxy.getInstance().callbackRouter; - callbackRouter.onAppsAdded.addListener(() => done()); + test('loads', async function() { + // Check that the browser responds to the getApps() message. + const {apps: initialApps} = + await app_management.BrowserProxy.getInstance().handler.getApps(); }); });
diff --git a/chrome/test/data/webui/app_management/main_view_test.js b/chrome/test/data/webui/app_management/main_view_test.js index d945712..1628e675 100644 --- a/chrome/test/data/webui/app_management/main_view_test.js +++ b/chrome/test/data/webui/app_management/main_view_test.js
@@ -41,9 +41,15 @@ return apps; } + function addApps(apps) { + for (const app of apps) { + callbackRouterProxy.onAppAdded(app); + } + } + test('simple app addition', async function() { let apps = createTestApps(1); - callbackRouterProxy.onAppsAdded(apps); + addApps(apps); await callbackRouterProxy.flushForTesting(); let appItems = mainView.root.querySelectorAll('app-management-item'); expectEquals(1, appItems.length); @@ -58,14 +64,14 @@ expectTrue(mainView.$['expander-row'].hidden); // The more apps bar shouldn't appear when there are 4 apps. - callbackRouterProxy.onAppsAdded(createTestApps(4)); + addApps(createTestApps(4)); await callbackRouterProxy.flushForTesting(); expectEquals( 4, mainView.root.querySelectorAll('app-management-item').length); expectTrue(mainView.$['expander-row'].hidden); // The more apps bar appears when there are 5 apps. - callbackRouterProxy.onAppsAdded(createTestApps(1)); + addApps(createTestApps(1)); await callbackRouterProxy.flushForTesting(); expectEquals( 5, mainView.root.querySelectorAll('app-management-item').length);
diff --git a/chrome/test/data/webui/app_management/reducers_test.js b/chrome/test/data/webui/app_management/reducers_test.js index 60a99001..cd424c46 100644 --- a/chrome/test/data/webui/app_management/reducers_test.js +++ b/chrome/test/data/webui/app_management/reducers_test.js
@@ -25,20 +25,16 @@ ]); }); - test('updates when apps are added', function() { - appsToAdd = [ - createApp('3', {type: 1, title: 'a'}), - createApp('4'), - ]; + test('updates when an app is added', function() { + const newApp = createApp('3', {type: 1, title: 'a'}); - action = app_management.actions.addApps(appsToAdd); + action = app_management.actions.addApp(newApp); apps = app_management.AppState.updateApps(apps, action); // Check that apps contains a key for each app id. assertTrue(!!apps['1']); assertTrue(!!apps['2']); assertTrue(!!apps['3']); - assertTrue(!!apps['4']); // Check that id corresponds to the right app. const app = apps['3'];
diff --git a/chrome/test/data/webui/print_preview/cloud_print_interface_stub.js b/chrome/test/data/webui/print_preview/cloud_print_interface_stub.js index dad9813..5989fa1 100644 --- a/chrome/test/data/webui/print_preview/cloud_print_interface_stub.js +++ b/chrome/test/data/webui/print_preview/cloud_print_interface_stub.js
@@ -45,16 +45,19 @@ */ search() { this.searchInProgress_ = true; + const printers = []; + this.cloudPrintersMap_.forEach((value) => printers.push(value)); + const searchDoneEvent = - new Event(cloudprint.CloudPrintInterfaceEventType.SEARCH_DONE); - searchDoneEvent.origin = print_preview.DestinationOrigin.COOKIES; - searchDoneEvent.printers = []; - this.cloudPrintersMap_.forEach((value) => { - searchDoneEvent.printers.push(value); - }); - searchDoneEvent.isRecent = true; - searchDoneEvent.user = 'foo@chromium.org'; - searchDoneEvent.searchDone = true; + new CustomEvent(cloudprint.CloudPrintInterfaceEventType.SEARCH_DONE, { + detail: { + origin: print_preview.DestinationOrigin.COOKIES, + printers: printers, + isRecent: true, + user: 'foo@chromium.org', + searchDone: true, + } + }); this.searchInProgress_ = false; this.eventTarget_.dispatchEvent(searchDoneEvent); } @@ -70,12 +73,11 @@ printer(printerId, origin, account) { const printer = this.cloudPrintersMap_.get(printerId); if (!!printer) { - const printerDoneEvent = - new Event(cloudprint.CloudPrintInterfaceEventType.PRINTER_DONE); - printerDoneEvent.printer = printer; - printerDoneEvent.printer.capabilities = + printer.capabilities = print_preview_test_utils.getCddTemplate(printerId); - this.eventTarget_.dispatchEvent(printerDoneEvent); + this.eventTarget_.dispatchEvent(new CustomEvent( + cloudprint.CloudPrintInterfaceEventType.PRINTER_DONE, + {detail: printer})); } } }
diff --git a/chromeos/dbus/fake_smb_provider_client.cc b/chromeos/dbus/fake_smb_provider_client.cc index 7f4f2563..0e47ede2 100644 --- a/chromeos/dbus/fake_smb_provider_client.cc +++ b/chromeos/dbus/fake_smb_provider_client.cc
@@ -259,6 +259,15 @@ base::BindOnce(std::move(callback), smbprovider::ERROR_OK, entry_list)); } +void FakeSmbProviderClient::UpdateMountCredentials(int32_t mount_id, + std::string workgroup, + std::string username, + base::ScopedFD password_fd, + StatusCallback callback) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), smbprovider::ERROR_OK)); +} + void FakeSmbProviderClient::ClearShares() { shares_.clear(); }
diff --git a/chromeos/dbus/fake_smb_provider_client.h b/chromeos/dbus/fake_smb_provider_client.h index e560d1ca..5535d4d0 100644 --- a/chromeos/dbus/fake_smb_provider_client.h +++ b/chromeos/dbus/fake_smb_provider_client.h
@@ -130,6 +130,12 @@ int32_t read_dir_token, ReadDirectoryCallback callback) override; + void UpdateMountCredentials(int32_t mount_id, + std::string workgroup, + std::string username, + base::ScopedFD password_fd, + StatusCallback callback) override; + // Adds |share| to the list of shares for |server_url| in |shares_|. void AddToShares(const std::string& server_url, const std::string& share);
diff --git a/chromeos/dbus/smb_provider_client.cc b/chromeos/dbus/smb_provider_client.cc index 985a815..57a1ae7c 100644 --- a/chromeos/dbus/smb_provider_client.cc +++ b/chromeos/dbus/smb_provider_client.cc
@@ -360,6 +360,25 @@ &callback); } + void UpdateMountCredentials(int32_t mount_id, + std::string workgroup, + std::string username, + base::ScopedFD password_fd, + StatusCallback callback) override { + smbprovider::UpdateMountCredentialsOptionsProto options; + options.set_mount_id(mount_id); + options.set_workgroup(workgroup); + options.set_username(username); + + dbus::MethodCall method_call(smbprovider::kSmbProviderInterface, + smbprovider::kUpdateMountCredentialsMethod); + dbus::MessageWriter writer(&method_call); + writer.AppendProtoAsArrayOfBytes(options); + writer.AppendFileDescriptor(password_fd.get()); + + CallDefaultMethod(&method_call, &callback); + } + protected: // DBusClient override. void Init(dbus::Bus* bus) override {
diff --git a/chromeos/dbus/smb_provider_client.h b/chromeos/dbus/smb_provider_client.h index 2c49bc14..594d3a6 100644 --- a/chromeos/dbus/smb_provider_client.h +++ b/chromeos/dbus/smb_provider_client.h
@@ -231,6 +231,16 @@ int32_t read_dir_token, ReadDirectoryCallback callback) = 0; + // Calls UpdateMountCredentials. This will update a mount's credentials with + // |workgroup|, |username|, and |password_fd|. Returns smbprovider::ERROR_OK + // if the mount's credentials successfully updated. Returns + // smbprovider::ERROR_NOT_FOUND if the mount's credentials were not updated. + virtual void UpdateMountCredentials(int32_t mount_id, + std::string workgroup, + std::string username, + base::ScopedFD password_fd, + StatusCallback callback) = 0; + protected: // Create() should be used instead. SmbProviderClient();
diff --git a/components/autofill/android/java/res/layout/autofill_dropdown_footer_item_refresh.xml b/components/autofill/android/java/res/layout/autofill_dropdown_footer_item_refresh.xml index b97c548..c36837ee 100644 --- a/components/autofill/android/java/res/layout/autofill_dropdown_footer_item_refresh.xml +++ b/components/autofill/android/java/res/layout/autofill_dropdown_footer_item_refresh.xml
@@ -26,7 +26,7 @@ android:includeFontPadding="false" android:singleLine="true" android:textAlignment="viewStart" - android:textAppearance="@style/BlackHint2" /> + android:textAppearance="@style/TextAppearance.BlackHint2" /> <ImageView android:id="@+id/dropdown_icon"
diff --git a/components/autofill/android/java/res/layout/autofill_dropdown_item.xml b/components/autofill/android/java/res/layout/autofill_dropdown_item.xml index 93512e2..5b0c931 100644 --- a/components/autofill/android/java/res/layout/autofill_dropdown_item.xml +++ b/components/autofill/android/java/res/layout/autofill_dropdown_item.xml
@@ -39,7 +39,7 @@ android:includeFontPadding="false" android:singleLine="true" android:textAlignment="viewStart" - android:textAppearance="@style/BlackTitle1" /> + android:textAppearance="@style/TextAppearance.BlackTitle1" /> <TextView android:id="@+id/dropdown_sublabel" @@ -51,7 +51,7 @@ android:includeFontPadding="false" android:singleLine="true" android:textAlignment="viewStart" - android:textAppearance="@style/BlackCaption" /> + android:textAppearance="@style/TextAppearance.BlackCaption" /> </LinearLayout> <ImageView
diff --git a/components/autofill/android/java/res/layout/autofill_dropdown_item_refresh.xml b/components/autofill/android/java/res/layout/autofill_dropdown_item_refresh.xml index 3760277..0c77e09 100644 --- a/components/autofill/android/java/res/layout/autofill_dropdown_item_refresh.xml +++ b/components/autofill/android/java/res/layout/autofill_dropdown_item_refresh.xml
@@ -34,7 +34,7 @@ android:ellipsize="end" android:includeFontPadding="false" android:singleLine="true" - android:textAppearance="@style/BlackBodyDefault" /> + android:textAppearance="@style/TextAppearance.BlackBodyDefault" /> <TextView android:id="@+id/dropdown_sublabel" @@ -44,7 +44,7 @@ android:includeFontPadding="false" android:singleLine="true" android:textAlignment="viewStart" - android:textAppearance="@style/BlackCaption" /> + android:textAppearance="@style/TextAppearance.BlackCaption" /> </LinearLayout> <ImageView
diff --git a/components/autofill/content/renderer/form_autofill_util.cc b/components/autofill/content/renderer/form_autofill_util.cc index bdc47a09..8ec7ae7b 100644 --- a/components/autofill/content/renderer/form_autofill_util.cc +++ b/components/autofill/content/renderer/form_autofill_util.cc
@@ -132,7 +132,8 @@ return base::ContainsValue(control_elements, form_control_element); } -bool IsElementInsideFormOrFieldSet(const WebElement& element) { +bool IsElementInsideFormOrFieldSet(const WebElement& element, + bool consider_fieldset_tags) { for (WebNode parent_node = element.ParentNode(); !parent_node.IsNull(); parent_node = parent_node.ParentNode()) { if (!parent_node.IsElementNode()) @@ -140,7 +141,7 @@ WebElement cur_element = parent_node.To<WebElement>(); if (cur_element.HasHTMLTagName("form") || - cur_element.HasHTMLTagName("fieldset")) { + (consider_fieldset_tags && cur_element.HasHTMLTagName("fieldset"))) { return true; } } @@ -371,24 +372,15 @@ return false; } -// Helper function to add a button's |title| to the |list| and updates the -// |total_length| of stored titles. Returns true iff the list still have free -// capacity. -bool AddButtonTitleToList(base::string16 title, +// Helper function to add a button's |title| to the |list|. +void AddButtonTitleToList(base::string16 title, ButtonTitleType button_type, - ButtonTitleList* list, - int* total_length) { - if (*total_length >= kMaxLengthForAllButtonTitles) - return false; + ButtonTitleList* list) { title = base::CollapseWhitespace(std::move(title), false); if (title.empty()) - return true; - TruncateString(&title, - std::min(kMaxLengthForSingleButtonTitle, - kMaxLengthForAllButtonTitles - *total_length)); - *total_length += title.length(); + return; + TruncateString(&title, kMaxLengthForSingleButtonTitle); list->push_back(std::make_pair(std::move(title), button_type)); - return *total_length < kMaxLengthForAllButtonTitles; } // Returns true iff |attribute| contains one of |kButtonFeatures|. @@ -417,19 +409,20 @@ // title. Otherwise, |WebElement::TextContent| (aka innerText in Javascript) is // extracted as a title. void FindElementsWithButtonFeatures(const WebElementCollection& elements, + bool only_formless_elements, ButtonTitleType button_type, bool extract_value_attribute, - ButtonTitleList* list, - int* total_length) { + ButtonTitleList* list) { static base::NoDestructor<WebString> kValue("value"); - if (*total_length >= kMaxLengthForAllButtonTitles) - return; - for (WebElement item = elements.FirstItem(); - !item.IsNull() && *total_length < kMaxLengthForAllButtonTitles; + for (WebElement item = elements.FirstItem(); !item.IsNull(); item = elements.NextItem()) { if (!ElementAttributesHasButtonFeature(item)) continue; - + if (only_formless_elements && + IsElementInsideFormOrFieldSet(item, + false /* consider_fieldset_tags */)) { + continue; + } base::string16 title = extract_value_attribute ? (item.HasAttribute(*kValue) ? item.GetAttribute(*kValue).Utf16() @@ -437,10 +430,7 @@ : item.TextContent().Utf16(); if (extract_value_attribute && title.empty()) title = item.TextContent().Utf16(); - if (!AddButtonTitleToList(std::move(title), button_type, list, - total_length)) { - break; - } + AddButtonTitleToList(std::move(title), button_type, list); } } @@ -867,18 +857,60 @@ return false; } -ButtonTitleList InferButtonTitlesForForm(const WebFormElement& form_element) { - static base::NoDestructor<WebString> kSubmit("submit"); - static base::NoDestructor<WebString> kButton("button"); +// Removes the duplicate titles and limits totals length. The order of the list +// is preserved as first elements are more reliable features than following +// ones. +void RemoveDuplicatesAndLimitTotalLength(ButtonTitleList* result) { + std::set<ButtonTitleInfo> already_added; + ButtonTitleList unique_titles; + int total_length = 0; + for (auto title : *result) { + if (already_added.find(title) != already_added.end()) + continue; + already_added.insert(title); + + total_length += title.first.length(); + if (total_length > kMaxLengthForAllButtonTitles) { + int new_length = + title.first.length() - (total_length - kMaxLengthForAllButtonTitles); + TruncateString(&title.first, new_length); + } + unique_titles.push_back(std::move(title)); + + if (total_length >= kMaxLengthForAllButtonTitles) + break; + } + *result = std::move(unique_titles); +} + +// Infer button titles enclosed by |root_element|. |root_element| may be a +// <form> or a <body> if there are <input>s that are not enclosed in a <form> +// element. +ButtonTitleList InferButtonTitlesForForm(const WebElement& root_element) { static base::NoDestructor<WebString> kA("a"); + static base::NoDestructor<WebString> kButton("button"); static base::NoDestructor<WebString> kDiv("div"); + static base::NoDestructor<WebString> kForm("form"); + static base::NoDestructor<WebString> kInput("input"); static base::NoDestructor<WebString> kSpan("span"); + static base::NoDestructor<WebString> kSubmit("submit"); + + // If the |root_element| is not a <form>, ignore the elements inclosed in a + // <form>. + bool only_formless_elements = !root_element.HasHTMLTagName(*kForm); ButtonTitleList result; - WebVector<WebFormControlElement> control_elements; - form_element.GetFormControlElements(control_elements); + WebElementCollection input_elements = + root_element.GetElementsByHTMLTagName(*kInput); int total_length = 0; - for (const WebFormControlElement& control_element : control_elements) { + for (WebElement item = input_elements.FirstItem(); + !item.IsNull() && total_length < kMaxLengthForAllButtonTitles; + item = input_elements.NextItem()) { + DCHECK(item.IsFormControlElement()); + WebFormControlElement control_element = + item.ToConst<WebFormControlElement>(); + if (only_formless_elements && !control_element.Form().IsNull()) + continue; bool is_submit_input = control_element.FormControlTypeForAutofill() == *kSubmit; bool is_button_input = @@ -886,18 +918,15 @@ if (!is_submit_input && !is_button_input) continue; base::string16 title = control_element.Value().Utf16(); - if (!AddButtonTitleToList(std::move(title), - is_submit_input - ? ButtonTitleType::INPUT_ELEMENT_SUBMIT_TYPE - : ButtonTitleType::INPUT_ELEMENT_BUTTON_TYPE, - &result, &total_length)) { - break; - } + AddButtonTitleToList(std::move(title), + is_submit_input + ? ButtonTitleType::INPUT_ELEMENT_SUBMIT_TYPE + : ButtonTitleType::INPUT_ELEMENT_BUTTON_TYPE, + &result); } WebElementCollection buttons = - form_element.GetElementsByHTMLTagName(*kButton); - for (WebElement item = buttons.FirstItem(); - !item.IsNull() && total_length < kMaxLengthForAllButtonTitles; + root_element.GetElementsByHTMLTagName(*kButton); + for (WebElement item = buttons.FirstItem(); !item.IsNull(); item = buttons.NextItem()) { WebString type_attribute = item.GetAttribute("type"); if (!type_attribute.IsNull() && type_attribute != *kButton && @@ -905,25 +934,29 @@ // Neither type='submit' nor type='button'. Skip this button. continue; } + if (only_formless_elements && + IsElementInsideFormOrFieldSet(item, + false /* consider_fieldset_tags */)) { + continue; + } bool is_submit_type = type_attribute.IsNull() || type_attribute == *kSubmit; base::string16 title = item.TextContent().Utf16(); - if (!AddButtonTitleToList(std::move(title), - is_submit_type - ? ButtonTitleType::BUTTON_ELEMENT_SUBMIT_TYPE - : ButtonTitleType::BUTTON_ELEMENT_BUTTON_TYPE, - &result, &total_length)) { - break; - } + AddButtonTitleToList(std::move(title), + is_submit_type + ? ButtonTitleType::BUTTON_ELEMENT_SUBMIT_TYPE + : ButtonTitleType::BUTTON_ELEMENT_BUTTON_TYPE, + &result); } FindElementsWithButtonFeatures( - form_element.GetElementsByHTMLTagName(*kA), ButtonTitleType::HYPERLINK, - true /* extract_value_attribute */, &result, &total_length); - FindElementsWithButtonFeatures( - form_element.GetElementsByHTMLTagName(*kDiv), ButtonTitleType::DIV, - false /* extract_value_attribute */, &result, &total_length); - FindElementsWithButtonFeatures( - form_element.GetElementsByHTMLTagName(*kSpan), ButtonTitleType::SPAN, - false /* extract_value_attribute */, &result, &total_length); + root_element.GetElementsByHTMLTagName(*kA), only_formless_elements, + ButtonTitleType::HYPERLINK, true /* extract_value_attribute */, &result); + FindElementsWithButtonFeatures(root_element.GetElementsByHTMLTagName(*kDiv), + only_formless_elements, ButtonTitleType::DIV, + false /* extract_value_attribute */, &result); + FindElementsWithButtonFeatures(root_element.GetElementsByHTMLTagName(*kSpan), + only_formless_elements, ButtonTitleType::SPAN, + false /* extract_value_attribute */, &result); + RemoveDuplicatesAndLimitTotalLength(&result); return result; } @@ -1382,6 +1415,7 @@ FormData* form, FormFieldData* field) { form->origin = GetCanonicalOriginForDocument(document); + form->button_titles = InferButtonTitlesForForm(document.Body()); if (document.GetFrame() && document.GetFrame()->Top()) { form->main_frame_origin = document.GetFrame()->Top()->GetSecurityOrigin(); } else { @@ -1792,7 +1826,8 @@ } if (fieldsets && element.HasHTMLTagName("fieldset") && - !IsElementInsideFormOrFieldSet(element)) { + !IsElementInsideFormOrFieldSet(element, + true /* consider_fieldset_tags */)) { fieldsets->push_back(element); } } @@ -2128,8 +2163,7 @@ return InferLabelForElement(element, stop_words, label, label_source); } -ButtonTitleList InferButtonTitlesForTesting( - const WebFormElement& form_element) { +ButtonTitleList InferButtonTitlesForTesting(const WebElement& form_element) { return InferButtonTitlesForForm(form_element); }
diff --git a/components/autofill/content/renderer/form_autofill_util.h b/components/autofill/content/renderer/form_autofill_util.h index b439c3b..bb64fb7 100644 --- a/components/autofill/content/renderer/form_autofill_util.h +++ b/components/autofill/content/renderer/form_autofill_util.h
@@ -279,7 +279,7 @@ base::string16* label, FormFieldData::LabelSource* label_source); ButtonTitleList InferButtonTitlesForTesting( - const blink::WebFormElement& form_element); + const blink::WebElement& form_element); // Returns form by unique renderer id. Return null element if there is no form // with given form renderer id.
diff --git a/components/autofill/content/renderer/form_autofill_util_browsertest.cc b/components/autofill/content/renderer/form_autofill_util_browsertest.cc index a43be23..48ce8bb5 100644 --- a/components/autofill/content/renderer/form_autofill_util_browsertest.cc +++ b/components/autofill/content/renderer/form_autofill_util_browsertest.cc
@@ -5,6 +5,7 @@ #include "components/autofill/content/renderer/form_autofill_util.h" #include "base/stl_util.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "content/public/test/render_view_test.h" #include "testing/gtest/include/gtest/gtest.h" @@ -270,6 +271,9 @@ TEST_F(FormAutofillUtilsTest, InferButtonTitleForFormTest) { const char kHtml[] = "<form id='target'>" + " <input type='button' value='Clear field'>" + " <input type='button' value='Clear field'>" + " <input type='button' value='Clear field'>" " <input type='button' value='\n Show\t password '>" " <button>Sign Up</button>" " <button type='button'>Register</button>" @@ -290,6 +294,8 @@ autofill::ButtonTitleList actual = autofill::form_util::InferButtonTitlesForTesting(form_target); autofill::ButtonTitleList expected = { + {base::UTF8ToUTF16("Clear field"), + autofill::ButtonTitleType::INPUT_ELEMENT_BUTTON_TYPE}, {base::UTF8ToUTF16("Show password"), autofill::ButtonTitleType::INPUT_ELEMENT_BUTTON_TYPE}, {base::UTF8ToUTF16("Sign Up"), @@ -303,6 +309,69 @@ EXPECT_EQ(expected, actual); } +TEST_F(FormAutofillUtilsTest, InferButtonTitleForFormTest_TooLongTitle) { + std::string title; + for (int i = 0; i < 300; ++i) + title += "a"; + std::string kFormHtml = "<form id='target'>"; + for (int i = 0; i < 10; i++) { + std::string kFieldHtml = + "<input type='button' value='" + base::IntToString(i) + title + "'>"; + kFormHtml += kFieldHtml; + } + kFormHtml += "</form>"; + + LoadHTML(kFormHtml.c_str()); + WebLocalFrame* web_frame = GetMainFrame(); + ASSERT_NE(nullptr, web_frame); + const WebElement& target = web_frame->GetDocument().GetElementById("target"); + ASSERT_FALSE(target.IsNull()); + const WebFormElement& form_target = target.ToConst<WebFormElement>(); + ASSERT_FALSE(form_target.IsNull()); + + autofill::ButtonTitleList actual = + autofill::form_util::InferButtonTitlesForTesting(form_target); + + int total_length = 0; + for (auto title : actual) { + EXPECT_GE(30u, title.first.length()); + total_length += title.first.length(); + } + EXPECT_EQ(200, total_length); +} + +TEST_F(FormAutofillUtilsTest, InferButtonTitle_Formless) { + const char kNoFormHtml[] = + "<div class='reg-form'>" + " <input type='button' value='\n Show\t password '>" + " <button>Sign Up</button>" + " <button type='button'>Register</button>" + "</div>" + "<form id='ignored-form'>" + " <input type='button' value='Ignore this'>" + " <button>Ignore this</button>" + " <a id='Submit' value='Ignore this'>" + " <div name='BTN'>Ignore this</div>" + "</form>"; + + LoadHTML(kNoFormHtml); + WebLocalFrame* web_frame = GetMainFrame(); + ASSERT_NE(nullptr, web_frame); + const WebElement& body = web_frame->GetDocument().Body(); + ASSERT_FALSE(body.IsNull()); + + autofill::ButtonTitleList actual = + autofill::form_util::InferButtonTitlesForTesting(body); + autofill::ButtonTitleList expected = { + {base::UTF8ToUTF16("Show password"), + autofill::ButtonTitleType::INPUT_ELEMENT_BUTTON_TYPE}, + {base::UTF8ToUTF16("Sign Up"), + autofill::ButtonTitleType::BUTTON_ELEMENT_SUBMIT_TYPE}, + {base::UTF8ToUTF16("Register"), + autofill::ButtonTitleType::BUTTON_ELEMENT_BUTTON_TYPE}}; + EXPECT_EQ(expected, actual); +} + TEST_F(FormAutofillUtilsTest, IsEnabled) { LoadHTML( "<input type='text' id='name1'>"
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc index 5bab7a9..6cc1960 100644 --- a/components/autofill/content/renderer/password_autofill_agent.cc +++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -1322,6 +1322,7 @@ ui::PageTransition transition) { if (!is_same_document_navigation) { checked_safe_browsing_reputation_ = false; + recorded_first_filling_result_ = false; } } @@ -1472,6 +1473,7 @@ FindUsernamePasswordElements(form_data); if (password_element.IsNull()) { MaybeStoreFallbackData(form_data); + LogFirstFillingResult(FillingResult::kNoPasswordElement); return; } @@ -1500,8 +1502,13 @@ // If wait_for_username is true, we don't want to initially fill the form // until the user types in a valid username. - if (form_data.wait_for_username) + if (form_data.wait_for_username) { + LogFirstFillingResult(FillingResult::kWaitForUsername); return; + } + + if (elements.empty()) + LogFirstFillingResult(FillingResult::kNoFillableElementsFound); for (auto element : elements) { WebInputElement username_element = !element.IsPasswordFieldForAutofill() @@ -1778,6 +1785,7 @@ logger->LogMessage( Logger::STRING_FAILED_TO_FILL_NO_AUTOCOMPLETEABLE_ELEMENT); } + LogFirstFillingResult(FillingResult::kPasswordElementIsNotAutocompleteable); return false; } @@ -1827,12 +1835,15 @@ PrefilledUsernameFillOutcome::kPrefilledUsernameNotOverridden); if (logger) logger->LogMessage(Logger::STRING_FAILED_TO_FILL_PREFILLED_USERNAME); + LogFirstFillingResult( + FillingResult::kUsernamePrefilledWithIncompatibleValue); return false; } if (logger) { logger->LogMessage( Logger::STRING_FAILED_TO_FILL_FOUND_NO_PASSWORD_FOR_USERNAME); } + LogFirstFillingResult(FillingResult::kFoundNoPasswordForUsername); return false; } @@ -1886,6 +1897,7 @@ autofilled_elements_cache_.emplace( password_element->UniqueRendererFormControlId(), WebString::FromUTF16(password)); + LogFirstFillingResult(FillingResult::kSuccess); return true; } @@ -1918,6 +1930,7 @@ cur_frame->GetSecurityOrigin().ToString().Utf8())) { if (logger) logger->LogMessage(Logger::STRING_FAILED_TO_FILL_INTO_IFRAME); + LogFirstFillingResult(FillingResult::kBlockedByFrameHierarchy); return false; } } @@ -1928,6 +1941,7 @@ logger->LogMessage( Logger::STRING_FAILED_TO_FILL_NO_AUTOCOMPLETEABLE_ELEMENT); } + LogFirstFillingResult(FillingResult::kPasswordElementIsNotAutocompleteable); return false; } @@ -2084,6 +2098,14 @@ last_supplied_password_info_iter_ = web_input_to_password_info_.begin(); } +void PasswordAutofillAgent::LogFirstFillingResult(FillingResult result) { + if (recorded_first_filling_result_) + return; + UMA_HISTOGRAM_ENUMERATION("PasswordManager.FirstRendererFillingResult", + result); + recorded_first_filling_result_ = true; +} + PasswordAutofillAgent::FormStructureInfo PasswordAutofillAgent::ExtractFormStructureInfo(const FormData& form_data) { FormStructureInfo result;
diff --git a/components/autofill/content/renderer/password_autofill_agent.h b/components/autofill/content/renderer/password_autofill_agent.h index faec0c0..6e1b175 100644 --- a/components/autofill/content/renderer/password_autofill_agent.h +++ b/components/autofill/content/renderer/password_autofill_agent.h
@@ -80,6 +80,41 @@ kMaxValue = kPasswordFormWithoutId, }; +// Used in UMA histogram, please do NOT reorder. +// Metric: "PasswordManager.FirstRendererFillingResult". +// This metric records whether the PasswordAutofillAgent succeeded in filling +// credentials after being instructed to do so by the browser process. +enum class FillingResult { + kSuccess = 0, + // The password element to be filled could not be found. + kNoPasswordElement = 1, + // Filling only happens in iframes, if all parent frames PSL match the + // security origin of the iframe containing the password field. + kBlockedByFrameHierarchy = 2, + // Passwords are not filled into fields that are not editable. + kPasswordElementIsNotAutocompleteable = 3, + // The username field contains a string that does not match the username of + // any available credential. + kUsernamePrefilledWithIncompatibleValue = 4, + // No credential was filled due to mismatches with the username. This can + // happen in a number of cases: In case the username field is empty and + // readonly. In case of a username-first-flow where a user's credentials do + // contain a username but the form contains only a password field and no + // username field. In case of change password forms that contain no username + // field. In case the user name is given on a page but only PSL matched + // credentials exist for this username. There may be further cases. + kFoundNoPasswordForUsername = 5, + // Renderer was instructed to wait until user has manually picked a + // credential. This happens for example if the session is an incognito + // session, the credendial's URL matches the mainframe only via the PSL, the + // site is on HTTP, or the form has no current password field. + // TODO(crbug.com/918846): Record root causes in a separate histogram. + kWaitForUsername = 6, + // No fillable elements were found, only possible for old form parser. + kNoFillableElementsFound = 7, + kMaxValue = kNoFillableElementsFound, +}; + // Names of HTML attributes to show form and field signatures for debugging. extern const char kDebugAttributeForFormSignature[]; extern const char kDebugAttributeForFieldSignature[]; @@ -427,6 +462,12 @@ // |form_data|. void MaybeStoreFallbackData(const PasswordFormFillData& form_data); + // Records whether filling succeeded for the first attempt to fill on a site. + // The logging is a bit conservative: It is possible that user-perceived + // navigations (via dynamic HTML sites) not trigger any actual navigations + // and therefore, the |recorded_first_filling_result_| never gets reset. + void LogFirstFillingResult(FillingResult result); + // Extracts information about form structure. static FormStructureInfo ExtractFormStructureInfo(const FormData& form_data); // Checks whether the form structure (amount of elements, element types etc) @@ -514,6 +555,12 @@ // structure. Replace FormData with a smaller structure. std::map<unsigned /*unique renderer element id*/, FormStructureInfo> forms_structure_cache_; + + // Flag to prevent that multiple PasswordManager.FirstRendererFillingResult + // UMA metrics are recorded per page load. This is reset on + // DidCommitProvisionalLoad() but only for non-same-document-navigations. + bool recorded_first_filling_result_ = false; + DISALLOW_COPY_AND_ASSIGN(PasswordAutofillAgent); };
diff --git a/components/feed/core/feed_scheduler_host.cc b/components/feed/core/feed_scheduler_host.cc index 4f67e53..1ebb755 100644 --- a/components/feed/core/feed_scheduler_host.cc +++ b/components/feed/core/feed_scheduler_host.cc
@@ -317,6 +317,14 @@ } void FeedSchedulerHost::OnArticlesCleared(bool suppress_refreshes) { + base::TimeDelta attempt_age = + clock_->Now() - profile_prefs_->GetTime(prefs::kLastFetchAttemptTime); + UMA_HISTOGRAM_CUSTOM_TIMES( + "ContentSuggestions.Feed.Scheduler.TimeSinceLastFetchOnClear", + attempt_age, base::TimeDelta::FromSeconds(1), + base::TimeDelta::FromDays(7), + /*bucket_count=*/50); + // Since there are no stored articles, a refresh will be needed soon. profile_prefs_->ClearPref(prefs::kLastFetchAttemptTime);
diff --git a/components/metrics/serialization/serialization_utils.cc b/components/metrics/serialization/serialization_utils.cc index 7214b5d..21931d0 100644 --- a/components/metrics/serialization/serialization_utils.cc +++ b/components/metrics/serialization/serialization_utils.cc
@@ -14,6 +14,7 @@ #include "base/files/file_util.h" #include "base/files/scoped_file.h" #include "base/logging.h" +#include "base/numerics/safe_math.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "components/metrics/serialization/metric_sample.h" @@ -35,11 +36,11 @@ CHECK(message); int result; - int32_t message_size; - const int32_t message_header_size = sizeof(message_size); + uint32_t encoded_size; + const size_t message_header_size = sizeof(uint32_t); // The file containing the metrics does not leave the device so the writer and // the reader will always have the same endianness. - result = HANDLE_EINTR(read(fd, &message_size, message_header_size)); + result = HANDLE_EINTR(read(fd, &encoded_size, message_header_size)); if (result < 0) { DPLOG(ERROR) << "reading metrics message header"; return false; @@ -48,17 +49,19 @@ // This indicates a normal EOF. return false; } - if (result < message_header_size) { + if (base::checked_cast<size_t>(result) < message_header_size) { DLOG(ERROR) << "bad read size " << result << ", expecting " - << sizeof(message_size); + << message_header_size; return false; } // kMessageMaxLength applies to the entire message: the 4-byte // length field and the content. + size_t message_size = base::checked_cast<size_t>(encoded_size); if (message_size > SerializationUtils::kMessageMaxLength) { DLOG(ERROR) << "message too long : " << message_size; - if (HANDLE_EINTR(lseek(fd, message_size - 4, SEEK_CUR)) == -1) { + if (HANDLE_EINTR(lseek(fd, message_size - message_header_size, SEEK_CUR)) == + -1) { DLOG(ERROR) << "error while skipping message. abort"; return false; } @@ -192,17 +195,19 @@ } std::string msg = sample.ToString(); - int32_t size = msg.length() + sizeof(int32_t); - if (size > kMessageMaxLength) { + size_t size = 0; + if (!base::CheckAdd(msg.length(), sizeof(uint32_t)).AssignIfValid(&size) || + size > kMessageMaxLength) { DPLOG(ERROR) << "cannot write message: too long: " << filename; return false; } // The file containing the metrics samples will only be read by programs on // the same device so we do not check endianness. + uint32_t encoded_size = base::checked_cast<uint32_t>(size); if (!base::WriteFileDescriptor(file_descriptor.get(), - reinterpret_cast<char*>(&size), - sizeof(size))) { + reinterpret_cast<char*>(&encoded_size), + sizeof(uint32_t))) { DPLOG(ERROR) << "error writing message length: " << filename; return false; }
diff --git a/components/metrics/serialization/serialization_utils.h b/components/metrics/serialization/serialization_utils.h index c741cb2f..2052686 100644 --- a/components/metrics/serialization/serialization_utils.h +++ b/components/metrics/serialization/serialization_utils.h
@@ -40,7 +40,7 @@ bool WriteMetricToFile(const MetricSample& sample, const std::string& filename); // Maximum length of a serialized message -static const int kMessageMaxLength = 1024; +static const size_t kMessageMaxLength = 1024; } // namespace SerializationUtils } // namespace metrics
diff --git a/components/metrics/serialization/serialization_utils_unittest.cc b/components/metrics/serialization/serialization_utils_unittest.cc index 5685a1f2..6bf3c8c 100644 --- a/components/metrics/serialization/serialization_utils_unittest.cc +++ b/components/metrics/serialization/serialization_utils_unittest.cc
@@ -135,6 +135,50 @@ EXPECT_TRUE(crash->IsEqual(*samples[0])); } +TEST_F(SerializationUtilsTest, NegativeLengthTest) { + // This input is specifically constructed to yield a single crash sample when + // parsed by a buggy version of the code but fails to parse and doesn't yield + // samples when parsed by a correct implementation. + constexpr uint8_t kInput[] = { + // Length indicating that next length field is the negative one below. + // This sample is invalid as it contains more than three null bytes. + 0x14, + 0x00, + 0x00, + 0x00, + // Encoding of a valid crash sample. + 0x0c, + 0x00, + 0x00, + 0x00, + 0x63, + 0x72, + 0x61, + 0x73, + 0x68, + 0x00, + 0x61, + 0x00, + // Invalid sample that jumps past the negative length bytes below. + 0x08, + 0x00, + 0x00, + 0x00, + // This is -16 in two's complement interpretation, pointing to the valid + // crash sample before. + 0xf0, + 0xff, + 0xff, + 0xff, + }; + CHECK(base::WriteFile(filepath, reinterpret_cast<const char*>(kInput), + sizeof(kInput))); + + std::vector<std::unique_ptr<MetricSample>> samples; + SerializationUtils::ReadAndTruncateMetricsFromFile(filename, &samples); + ASSERT_EQ(0U, samples.size()); +} + TEST_F(SerializationUtilsTest, WriteReadTest) { std::unique_ptr<MetricSample> hist = MetricSample::HistogramSample("myhist", 1, 2, 3, 4);
diff --git a/components/ntp_snippets/remote/remote_suggestions_scheduler_impl.cc b/components/ntp_snippets/remote/remote_suggestions_scheduler_impl.cc index 6248cc6..451f558 100644 --- a/components/ntp_snippets/remote/remote_suggestions_scheduler_impl.cc +++ b/components/ntp_snippets/remote/remote_suggestions_scheduler_impl.cc
@@ -887,6 +887,16 @@ } void RemoteSuggestionsSchedulerImpl::ClearLastFetchAttemptTime() { + // Added during Feed rollout to help investigate https://crbug.com/908963. + base::TimeDelta attempt_age = + clock_->Now() - + profile_prefs_->GetTime(prefs::kSnippetLastFetchAttemptTime); + UMA_HISTOGRAM_CUSTOM_TIMES( + "ContentSuggestions.Feed.Scheduler.TimeSinceLastFetchOnClear", + attempt_age, base::TimeDelta::FromSeconds(1), + base::TimeDelta::FromDays(7), + /*bucket_count=*/50); + profile_prefs_->ClearPref(prefs::kSnippetLastFetchAttemptTime); // To mark the last fetch as stale, we need to keep the time in prefs, only // making sure it is long ago.
diff --git a/components/signin/core/browser/BUILD.gn b/components/signin/core/browser/BUILD.gn index 2b06659..c4d4177 100644 --- a/components/signin/core/browser/BUILD.gn +++ b/components/signin/core/browser/BUILD.gn
@@ -68,8 +68,6 @@ "profile_oauth2_token_service.h", "signin_client.cc", "signin_client.h", - "signin_error_controller.cc", - "signin_error_controller.h", "signin_internals_util.cc", "signin_internals_util.h", "signin_manager.cc", @@ -133,6 +131,8 @@ "dice_header_helper.h", "mirror_account_reconcilor_delegate.cc", "mirror_account_reconcilor_delegate.h", + "signin_error_controller.cc", + "signin_error_controller.h", "signin_header_helper.cc", "signin_header_helper.h", "signin_investigator.cc",
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc index 4bcd3d2..d24aaabe 100644 --- a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc +++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc
@@ -327,6 +327,20 @@ base::TimeDelta::FromMilliseconds(100), 50); } } + if (!needs_begin_frames_) { + TRACE_EVENT_WITH_FLOW1("viz,benchmark", "Graphics.Pipeline", + TRACE_ID_GLOBAL(args.trace_id), + TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, + "step", "ReceiveBeginFrameDiscard"); + // OnBeginFrame() can be called just to deliver presentation feedback, so + // report that we didn't use this BeginFrame. + DidNotProduceFrame(BeginFrameAck(args, false)); + return; + } + TRACE_EVENT_WITH_FLOW1("viz,benchmark", "Graphics.Pipeline", + TRACE_ID_GLOBAL(args.trace_id), + TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, + "step", "ReceiveBeginFrame"); begin_frame_source_->OnBeginFrame(args); } @@ -340,8 +354,9 @@ begin_frame_source_->OnSetBeginFrameSourcePaused(paused); } -void DirectLayerTreeFrameSink::OnNeedsBeginFrames(bool needs_begin_frame) { - support_->SetNeedsBeginFrame(needs_begin_frame); +void DirectLayerTreeFrameSink::OnNeedsBeginFrames(bool needs_begin_frames) { + needs_begin_frames_ = needs_begin_frames; + support_->SetNeedsBeginFrame(needs_begin_frames); } void DirectLayerTreeFrameSink::OnContextLost() {
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h index ee5d0f2..0ecaa73d 100644 --- a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h +++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h
@@ -99,7 +99,7 @@ void OnBeginFramePausedChanged(bool paused) override; // ExternalBeginFrameSourceClient implementation: - void OnNeedsBeginFrames(bool needs_begin_frame) override; + void OnNeedsBeginFrames(bool needs_begin_frames) override; // ContextLostObserver implementation: void OnContextLost() override; @@ -112,6 +112,7 @@ std::unique_ptr<CompositorFrameSinkSupport> support_; + bool needs_begin_frames_ = false; const FrameSinkId frame_sink_id_; CompositorFrameSinkSupportManager* const support_manager_; FrameSinkManagerImpl* frame_sink_manager_;
diff --git a/content/browser/background_fetch/background_fetch_context.cc b/content/browser/background_fetch/background_fetch_context.cc index f9e2835..203b145 100644 --- a/content/browser/background_fetch/background_fetch_context.cc +++ b/content/browser/background_fetch/background_fetch_context.cc
@@ -229,8 +229,8 @@ blink::mojom::BackgroundFetchService::UpdateUICallback callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - delegate_proxy_.UpdateUI(registration_id.unique_id(), title, icon); - std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE); + delegate_proxy_.UpdateUI(registration_id.unique_id(), title, icon, + std::move(callback)); } void BackgroundFetchContext::Abort(
diff --git a/content/browser/background_fetch/background_fetch_delegate_proxy.cc b/content/browser/background_fetch/background_fetch_delegate_proxy.cc index 6ac54fd3..e56ddcd 100644 --- a/content/browser/background_fetch/background_fetch_delegate_proxy.cc +++ b/content/browser/background_fetch/background_fetch_delegate_proxy.cc
@@ -207,6 +207,7 @@ const std::string& guid, std::unique_ptr<content::BackgroundFetchResponse> response) override; void OnUIActivated(const std::string& unique_id) override; + void OnUIUpdated(const std::string& unique_id) override; void GetUploadData( const std::string& job_unique_id, const std::string& download_guid, @@ -279,6 +280,16 @@ job_unique_id)); } +void BackgroundFetchDelegateProxy::Core::OnUIUpdated( + const std::string& job_unique_id) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + base::PostTaskWithTraits( + FROM_HERE, {BrowserThread::IO}, + base::BindOnce(&BackgroundFetchDelegateProxy::DidUpdateUI, io_parent_, + job_unique_id)); +} + void BackgroundFetchDelegateProxy::Core::GetUploadData( const std::string& job_unique_id, const std::string& download_guid, @@ -405,9 +416,20 @@ void BackgroundFetchDelegateProxy::UpdateUI( const std::string& job_unique_id, const base::Optional<std::string>& title, - const base::Optional<SkBitmap>& icon) { + const base::Optional<SkBitmap>& icon, + blink::mojom::BackgroundFetchService::UpdateUICallback update_ui_callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); + auto job_details_iter = job_details_map_.find(job_unique_id); + if (job_details_iter == job_details_map_.end()) { + std::move(update_ui_callback) + .Run(blink::mojom::BackgroundFetchError::INVALID_ID); + return; + } + + JobDetails& job_details = job_details_iter->second; + job_details.update_ui_callback = std::move(update_ui_callback); + base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, base::BindOnce(&Core::UpdateUI, ui_core_ptr_, job_unique_id, title, icon)); @@ -481,6 +503,19 @@ click_event_dispatcher_callback_.Run(job_unique_id); } +void BackgroundFetchDelegateProxy::DidUpdateUI( + const std::string& job_unique_id) { + auto job_details_iter = job_details_map_.find(job_unique_id); + if (job_details_iter == job_details_map_.end()) + return; + + JobDetails& job_details = job_details_iter->second; + + DCHECK(job_details.update_ui_callback); + std::move(job_details.update_ui_callback) + .Run(blink::mojom::BackgroundFetchError::NONE); +} + void BackgroundFetchDelegateProxy::OnDownloadUpdated( const std::string& job_unique_id, const std::string& guid,
diff --git a/content/browser/background_fetch/background_fetch_delegate_proxy.h b/content/browser/background_fetch/background_fetch_delegate_proxy.h index f54799925..2ec79134 100644 --- a/content/browser/background_fetch/background_fetch_delegate_proxy.h +++ b/content/browser/background_fetch/background_fetch_delegate_proxy.h
@@ -33,7 +33,7 @@ // Subclasses must only be destroyed on the IO thread, since these methods // will be called on the IO thread. using DispatchClickEventCallback = - base::RepeatingCallback<void(const std::string& /* unique_id */)>; + base::RepeatingCallback<void(const std::string& unique_id)>; class Controller { public: // Called when the given |request| has started fetching. @@ -110,11 +110,14 @@ scoped_refptr<BackgroundFetchRequestInfo> request); // Updates the representation of this registration in the user interface to - // match the given |title| or |icon|. + // match the given |title| or |icon|. |update_ui_callback| should be called + // after all the relevant UI information has been processed. // Called from the Controller (on the IO thread). void UpdateUI(const std::string& job_unique_id, const base::Optional<std::string>& title, - const base::Optional<SkBitmap>& icon); + const base::Optional<SkBitmap>& icon, + blink::mojom::BackgroundFetchService::UpdateUICallback + update_ui_callback); // Aborts in progress downloads for the given registration. Called from the // Controller (on the IO thread) after it is aborted. May occur even if all @@ -156,6 +159,9 @@ void DidActivateUI(const std::string& job_unique_id); // Should only be called from the BackgroundFetchDelegate (on the IO thread). + void DidUpdateUI(const std::string& job_unique_id); + + // Should only be called from the BackgroundFetchDelegate (on the IO thread). void GetUploadData(const std::string& job_unique_id, const std::string& download_guid, BackgroundFetchDelegate::GetUploadDataCallback callback); @@ -176,6 +182,8 @@ base::flat_map<std::string, scoped_refptr<BackgroundFetchRequestInfo>> current_request_map; + blink::mojom::BackgroundFetchService::UpdateUICallback update_ui_callback; + private: DISALLOW_COPY_AND_ASSIGN(JobDetails); };
diff --git a/content/browser/background_fetch/background_fetch_delegate_proxy_unittest.cc b/content/browser/background_fetch/background_fetch_delegate_proxy_unittest.cc index d6bae265..8ad7182 100644 --- a/content/browser/background_fetch/background_fetch_delegate_proxy_unittest.cc +++ b/content/browser/background_fetch/background_fetch_delegate_proxy_unittest.cc
@@ -324,7 +324,8 @@ EXPECT_TRUE(controller.request_started_); EXPECT_TRUE(controller.request_completed_); - delegate_proxy_.UpdateUI(kExampleUniqueId, "Job 1 Complete!", base::nullopt); + delegate_proxy_.UpdateUI(kExampleUniqueId, "Job 1 Complete!", base::nullopt, + base::DoNothing()); base::RunLoop().RunUntilIdle(); EXPECT_EQ(delegate_->ui_update_count_, 1); }
diff --git a/content/browser/background_fetch/background_fetch_registration_notifier.cc b/content/browser/background_fetch/background_fetch_registration_notifier.cc index 5b7b540b..a98b02c 100644 --- a/content/browser/background_fetch/background_fetch_registration_notifier.cc +++ b/content/browser/background_fetch/background_fetch_registration_notifier.cc
@@ -6,9 +6,7 @@ #include "base/bind.h" #include "base/command_line.h" -#include "base/feature_list.h" #include "content/common/background_fetch/background_fetch_types.h" -#include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" namespace content {
diff --git a/content/browser/background_fetch/background_fetch_registration_notifier_unittest.cc b/content/browser/background_fetch/background_fetch_registration_notifier_unittest.cc index 66a66b1..5c7ba2d 100644 --- a/content/browser/background_fetch/background_fetch_registration_notifier_unittest.cc +++ b/content/browser/background_fetch/background_fetch_registration_notifier_unittest.cc
@@ -9,11 +9,9 @@ #include <vector> #include "base/macros.h" -#include "base/test/scoped_feature_list.h" #include "base/test/test_simple_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "content/common/background_fetch/background_fetch_types.h" -#include "content/public/common/content_features.h" #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/interface_request.h" #include "testing/gtest/include/gtest/gtest.h" @@ -277,11 +275,6 @@ } TEST_F(BackgroundFetchRegistrationNotifierTest, NotifyRequestCompleted) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature( - features::kBackgroundFetchAccessActiveFetches); - ASSERT_TRUE(base::FeatureList::IsEnabled( - features::kBackgroundFetchAccessActiveFetches)); auto observer = std::make_unique<TestRegistrationObserver>(); notifier_->AddObserver(kPrimaryUniqueId, observer->GetPtr());
diff --git a/content/browser/background_fetch/mock_background_fetch_delegate.cc b/content/browser/background_fetch/mock_background_fetch_delegate.cc index 8d9aa68..681273d 100644 --- a/content/browser/background_fetch/mock_background_fetch_delegate.cc +++ b/content/browser/background_fetch/mock_background_fetch_delegate.cc
@@ -199,7 +199,9 @@ void MockBackgroundFetchDelegate::UpdateUI( const std::string& job_unique_id, const base::Optional<std::string>& title, - const base::Optional<SkBitmap>& icon) {} + const base::Optional<SkBitmap>& icon) { + job_id_to_client_map_[job_unique_id]->OnUIUpdated(job_unique_id); +} void MockBackgroundFetchDelegate::RegisterResponse( const GURL& url,
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index cad68ea..6bbc97b 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -4728,29 +4728,21 @@ ? find_request->second.get() : nullptr; - if (IsPerNavigationMojoInterfaceEnabled() && navigation_request_ && - navigation_request_->GetCommitNavigationClient()) { - navigation_request_->GetCommitNavigationClient()->CommitNavigation( - head, common_params, commit_params, - std::move(url_loader_client_endpoints), - std::move(subresource_loader_factories), - std::move(subresource_overrides), std::move(controller), - std::move(prefetch_loader_factory), devtools_navigation_token, - base::BindOnce(&RenderFrameHostImpl::OnCrossDocumentCommitProcessed, - base::Unretained(this), navigation_id)); - } else { - GetNavigationControl()->CommitNavigation( - head, common_params, commit_params, - std::move(url_loader_client_endpoints), - std::move(subresource_loader_factories), - std::move(subresource_overrides), std::move(controller), - std::move(prefetch_loader_factory), devtools_navigation_token, - request ? base::BindOnce( - &RenderFrameHostImpl::OnCrossDocumentCommitProcessed, - base::Unretained(this), navigation_id) - : content::mojom::FrameNavigationControl:: - CommitNavigationCallback()); - } + mojom::NavigationClient* navigation_client = nullptr; + if (IsPerNavigationMojoInterfaceEnabled() && request) + navigation_client = request->GetCommitNavigationClient(); + + SendCommitNavigation( + navigation_client, navigation_id, head, common_params, commit_params, + std::move(url_loader_client_endpoints), + std::move(subresource_loader_factories), + std::move(subresource_overrides), std::move(controller), + std::move(prefetch_loader_factory), devtools_navigation_token, + request ? base::BindOnce( + &RenderFrameHostImpl::OnCrossDocumentCommitProcessed, + base::Unretained(this), navigation_id) + : content::mojom::FrameNavigationControl:: + CommitNavigationCallback()); // |remote_object| is an associated interface ptr, so calls can't be made on // it until its request endpoint is sent. Now that the request endpoint was @@ -4815,20 +4807,17 @@ NavigationRequest* request = find_request != navigation_requests_.end() ? find_request->second.get() : nullptr; - if (IsPerNavigationMojoInterfaceEnabled() && request && - request->GetCommitNavigationClient()) { - request->GetCommitNavigationClient()->CommitFailedNavigation( - common_params, commit_params, has_stale_copy_in_cache, error_code, - error_page_content, std::move(subresource_loader_factories), - base::BindOnce(&RenderFrameHostImpl::OnCrossDocumentCommitProcessed, - base::Unretained(this), navigation_id)); - } else { - GetNavigationControl()->CommitFailedNavigation( - common_params, commit_params, has_stale_copy_in_cache, error_code, - error_page_content, std::move(subresource_loader_factories), - base::BindOnce(&RenderFrameHostImpl::OnCrossDocumentCommitProcessed, - base::Unretained(this), navigation_id)); - } + + mojom::NavigationClient* navigation_client = nullptr; + if (IsPerNavigationMojoInterfaceEnabled() && request) + navigation_client = request->GetCommitNavigationClient(); + + SendCommitFailedNavigation( + navigation_client, navigation_id, common_params, commit_params, + has_stale_copy_in_cache, error_code, error_page_content, + std::move(subresource_loader_factories), + base::BindOnce(&RenderFrameHostImpl::OnCrossDocumentCommitProcessed, + base::Unretained(this), navigation_id)); // An error page is expected to commit, hence why is_loading_ is set to true. is_loading_ = true; @@ -6215,4 +6204,62 @@ base::nullopt, std::move(body)); } +void RenderFrameHostImpl::SendCommitNavigation( + mojom::NavigationClient* navigation_client, + int64_t navigation_id, + const network::ResourceResponseHead& head, + const content::CommonNavigationParams& common_params, + const content::CommitNavigationParams& commit_params, + network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, + std::unique_ptr<blink::URLLoaderFactoryBundleInfo> + subresource_loader_factories, + base::Optional<std::vector<::content::mojom::TransferrableURLLoaderPtr>> + subresource_overrides, + blink::mojom::ControllerServiceWorkerInfoPtr controller, + network::mojom::URLLoaderFactoryPtr prefetch_loader_factory, + const base::UnguessableToken& devtools_navigation_token, + mojom::FrameNavigationControl::CommitNavigationCallback callback) { + if (navigation_client) { + navigation_client->CommitNavigation( + head, common_params, commit_params, + std::move(url_loader_client_endpoints), + std::move(subresource_loader_factories), + std::move(subresource_overrides), std::move(controller), + std::move(prefetch_loader_factory), devtools_navigation_token, + std::move(callback)); + } else { + GetNavigationControl()->CommitNavigation( + head, common_params, commit_params, + std::move(url_loader_client_endpoints), + std::move(subresource_loader_factories), + std::move(subresource_overrides), std::move(controller), + std::move(prefetch_loader_factory), devtools_navigation_token, + std::move(callback)); + } +} + +void RenderFrameHostImpl::SendCommitFailedNavigation( + mojom::NavigationClient* navigation_client, + int64_t navigation_id, + const content::CommonNavigationParams& common_params, + const content::CommitNavigationParams& commit_params, + bool has_stale_copy_in_cache, + int32_t error_code, + const base::Optional<std::string>& error_page_content, + std::unique_ptr<blink::URLLoaderFactoryBundleInfo> + subresource_loader_factories, + mojom::FrameNavigationControl::CommitFailedNavigationCallback callback) { + if (navigation_client) { + navigation_client->CommitFailedNavigation( + common_params, commit_params, has_stale_copy_in_cache, error_code, + error_page_content, std::move(subresource_loader_factories), + std::move(callback)); + } else { + GetNavigationControl()->CommitFailedNavigation( + common_params, commit_params, has_stale_copy_in_cache, error_code, + error_page_content, std::move(subresource_loader_factories), + std::move(callback)); + } +} + } // namespace content
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index b2ac802..e3543748 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -847,6 +847,38 @@ bool hidden, bool renderer_initiated_creation); + // The SendCommit* functions below are wrappers for commit calls + // made to mojom::FrameNavigationControl and mojom::NavigationClient. + // These exist to be overridden in tests to retain mojo callbacks. + // Note: |navigation_id| is used in test overrides, but is unused otherwise. + virtual void SendCommitNavigation( + mojom::NavigationClient* navigation_client, + int64_t navigation_id, + const network::ResourceResponseHead& head, + const content::CommonNavigationParams& common_params, + const content::CommitNavigationParams& commit_params, + network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, + std::unique_ptr<blink::URLLoaderFactoryBundleInfo> + subresource_loader_factories, + base::Optional<std::vector<::content::mojom::TransferrableURLLoaderPtr>> + subresource_overrides, + blink::mojom::ControllerServiceWorkerInfoPtr + controller_service_worker_info, + network::mojom::URLLoaderFactoryPtr prefetch_loader_factory, + const base::UnguessableToken& devtools_navigation_token, + mojom::FrameNavigationControl::CommitNavigationCallback callback); + virtual void SendCommitFailedNavigation( + mojom::NavigationClient* navigation_client, + int64_t navigation_id, + const content::CommonNavigationParams& common_params, + const content::CommitNavigationParams& commit_params, + bool has_stale_copy_in_cache, + int32_t error_code, + const base::Optional<std::string>& error_page_content, + std::unique_ptr<blink::URLLoaderFactoryBundleInfo> + subresource_loader_factories, + mojom::FrameNavigationControl::CommitFailedNavigationCallback callback); + private: friend class RenderFrameHostFeaturePolicyTest; friend class TestRenderFrameHost;
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.cc b/content/browser/gpu/gpu_data_manager_impl_private.cc index 03a570f..ed537418 100644 --- a/content/browser/gpu/gpu_data_manager_impl_private.cc +++ b/content/browser/gpu/gpu_data_manager_impl_private.cc
@@ -292,7 +292,6 @@ if (command_line->HasSwitch(switches::kSingleProcess) || command_line->HasSwitch(switches::kInProcessGPU)) { - in_process_gpu_ = true; AppendGpuCommandLine(command_line); } @@ -388,10 +387,6 @@ return; #if defined(OS_WIN) - if (!GpuAccessAllowed(nullptr)) - return; - if (in_process_gpu_) - return; complete_gpu_info_already_requested_ = true; GpuProcessHost::CallOnIO(GpuProcessHost::GPU_PROCESS_KIND_UNSANDBOXED_NO_GL, true /* force_create */, @@ -410,8 +405,6 @@ void GpuDataManagerImplPrivate::RequestGpuSupportedRuntimeVersion() { #if defined(OS_WIN) - if (in_process_gpu_) - return; base::OnceClosure task = base::BindOnce([]() { GpuProcessHost* host = GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_UNSANDBOXED_NO_GL,
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.h b/content/browser/gpu/gpu_data_manager_impl_private.h index 96346d5..f84f8070 100644 --- a/content/browser/gpu/gpu_data_manager_impl_private.h +++ b/content/browser/gpu/gpu_data_manager_impl_private.h
@@ -211,9 +211,6 @@ bool application_is_visible_ = true; - // True if --single-process or --in-process-gpu is passed in. - bool in_process_gpu_ = false; - DISALLOW_COPY_AND_ASSIGN(GpuDataManagerImplPrivate); };
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index de98ea5..d8e14d4 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -529,6 +529,15 @@ return nullptr; } + // Do not launch the unsandboxed GPU process if GPU is disabled + if (kind == GPU_PROCESS_KIND_UNSANDBOXED_NO_GL) { + auto* command_line = base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(switches::kDisableGpu) || + command_line->HasSwitch(switches::kSingleProcess) || + command_line->HasSwitch(switches::kInProcessGPU)) + return nullptr; + } + if (g_gpu_process_hosts[kind] && ValidateHost(g_gpu_process_hosts[kind])) return g_gpu_process_hosts[kind];
diff --git a/content/browser/indexed_db/indexed_db_browsertest.cc b/content/browser/indexed_db/indexed_db_browsertest.cc index f59d959f..16e4b231 100644 --- a/content/browser/indexed_db/indexed_db_browsertest.cc +++ b/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -336,6 +336,20 @@ DISALLOW_COPY_AND_ASSIGN(IndexedDBBrowserTestWithGCExposed); }; +class IndexedDBBrowserTestWithExperimentalWebFeatures + : public IndexedDBBrowserTest { + public: + IndexedDBBrowserTestWithExperimentalWebFeatures() = default; + + void SetUpCommandLine(base::CommandLine* command_line) override { + command_line->AppendSwitch( + switches::kEnableExperimentalWebPlatformFeatures); + } + + private: + DISALLOW_COPY_AND_ASSIGN(IndexedDBBrowserTestWithExperimentalWebFeatures); +}; + IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithGCExposed, DatabaseCallbacksTest) { SimpleTest(GetTestUrl("indexeddb", "database_callbacks_first.html")); @@ -925,6 +939,34 @@ EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle()); } +// Testing abort ordering for commit. Verifies that an explicitly committed +// transaction blocked by another pending transaction will be committed rather +// than aborted in the event that the page crashes before its committed. +IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithExperimentalWebFeatures, + CommitContinuesOnAbort) { + // Sets up a database, opens four transactions against it such that two end + // up indefinitely blocked, one of which is explicitly committed. + NavigateAndWaitForTitle(shell(), "blocked_explicit_commit.html", "#tab1", + "transactions registered"); + + // Crashes the tab to cause the database set up above to force close with the + // blocked transactions still open. + shell()->web_contents()->GetMainFrame()->GetProcess()->Shutdown(0); + + // Reopens the same page that was just crashed and inspects the database to + // see the results of the transactions that were open at time of crash. + Shell* new_shell = CreateBrowser(); + GURL url = GetTestUrl("indexeddb", "blocked_explicit_commit.html"); + url = GURL(url.spec() + "#tab2"); + base::string16 expected_title16( + ASCIIToUTF16("transactions aborted and committed as expected")); + TitleWatcher title_watcher(new_shell->web_contents(), expected_title16); + title_watcher.AlsoWaitForTitle( + ASCIIToUTF16("fail - transactions did not abort and commit as expected")); + NavigateToURL(new_shell, url); + EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle()); +} + // Verify that a "close" event is fired at database connections when // the backing store is deleted. IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ForceCloseEventTest) {
diff --git a/content/browser/indexed_db/indexed_db_connection.cc b/content/browser/indexed_db/indexed_db_connection.cc index 3d2768c..ee10e7f 100644 --- a/content/browser/indexed_db/indexed_db_connection.cc +++ b/content/browser/indexed_db/indexed_db_connection.cc
@@ -123,13 +123,21 @@ transaction->Abort(error); } -void IndexedDBConnection::AbortAllTransactions( +void IndexedDBConnection::FinishAllTransactions( const IndexedDBDatabaseError& error) { std::unordered_map<int64_t, std::unique_ptr<IndexedDBTransaction>> temp_map; std::swap(temp_map, transactions_); for (const auto& pair : temp_map) { - IDB_TRACE1("IndexedDBDatabase::Abort(error)", "txn.id", pair.second->id()); - pair.second->Abort(error); + auto& transaction = pair.second; + if (transaction->is_commit_pending()) { + IDB_TRACE1("IndexedDBDatabase::Commit", "transaction.id", + transaction->id()); + transaction->ForcePendingCommit(); + } else { + IDB_TRACE1("IndexedDBDatabase::Abort(error)", "transaction.id", + transaction->id()); + transaction->Abort(error); + } } }
diff --git a/content/browser/indexed_db/indexed_db_connection.h b/content/browser/indexed_db/indexed_db_connection.h index 940d403..66633368 100644 --- a/content/browser/indexed_db/indexed_db_connection.h +++ b/content/browser/indexed_db/indexed_db_connection.h
@@ -66,7 +66,11 @@ void AbortTransaction(IndexedDBTransaction* transaction, const IndexedDBDatabaseError& error); - void AbortAllTransactions(const IndexedDBDatabaseError& error); + // Aborts or commits each transaction owned by this connection depending on + // the transaction's current state. Any transaction with is_commit_pending_ + // false is aborted, and any transaction with is_commit_pending_ true is + // committed. + void FinishAllTransactions(const IndexedDBDatabaseError& error); IndexedDBTransaction* GetTransaction(int64_t id) const;
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc index c66a70c..daf241ca 100644 --- a/content/browser/indexed_db/indexed_db_database.cc +++ b/content/browser/indexed_db/indexed_db_database.cc
@@ -1892,7 +1892,7 @@ // happen if the close is requested by the connection itself as the // front-end defers the close until all transactions are complete, but can // occur on process termination or forced close. - connection->AbortAllTransactions(IndexedDBDatabaseError( + connection->FinishAllTransactions(IndexedDBDatabaseError( blink::kWebIDBDatabaseExceptionUnknownError, "Connection is closing.")); // Abort transactions before removing the connection; aborting may complete @@ -1947,7 +1947,7 @@ IDB_TRACE("IndexedDBDatabase::AbortAllTransactionsForConnections"); for (IndexedDBConnection* connection : connections_) { - connection->AbortAllTransactions( + connection->FinishAllTransactions( IndexedDBDatabaseError(blink::kWebIDBDatabaseExceptionUnknownError, "Database is compacting.")); }
diff --git a/content/browser/indexed_db/indexed_db_transaction.cc b/content/browser/indexed_db/indexed_db_transaction.cc index 2a22bcc..5c44332 100644 --- a/content/browser/indexed_db/indexed_db_transaction.cc +++ b/content/browser/indexed_db/indexed_db_transaction.cc
@@ -178,9 +178,27 @@ ptr_factory_.GetWeakPtr())); } +void IndexedDBTransaction::ForcePendingCommit() { + IDB_TRACE1("IndexedDBTransaction::ForceCommit", "txn.id", id()); + DCHECK(is_commit_pending_); + if (state_ == FINISHED) + return; + + should_process_queue_ = true; + state_ = STARTED; + if (!task_queue_.empty()) { + // Commits when completed. + ProcessTaskQueue(); + } else { + leveldb::Status result = Commit(); + if (!result.ok()) + database_->ReportError(result); + } +} + void IndexedDBTransaction::Abort(const IndexedDBDatabaseError& error) { - IDB_TRACE1("IndexedDBTransaction::Abort", "txn.id", id()); DCHECK(!processing_event_queue_); + DCHECK(!is_commit_pending_); if (state_ == FINISHED) return; @@ -254,7 +272,7 @@ diagnostics_.start_time = base::Time::Now(); if (!used_) { - if (commit_pending_) { + if (is_commit_pending_) { // The transaction has never had requests issued against it, but the // front-end previously requested a commit; do the commit now, but not // re-entrantly as that may renter the coordinator. @@ -328,7 +346,7 @@ return leveldb::Status::OK(); DCHECK_NE(state_, COMMITTING); - commit_pending_ = true; + is_commit_pending_ = true; // Front-end has requested a commit, but this transaction is blocked by // other transactions. The commit will be initiated when the transaction @@ -500,7 +518,7 @@ // If there are no pending tasks, we haven't already committed/aborted, // and the front-end requested a commit, it is now safe to do so. - if (!HasPendingTasks() && state_ != FINISHED && commit_pending_) { + if (!HasPendingTasks() && state_ != FINISHED && is_commit_pending_) { processing_event_queue_ = false; // This can delete |this|. leveldb::Status result = Commit();
diff --git a/content/browser/indexed_db/indexed_db_transaction.h b/content/browser/indexed_db/indexed_db_transaction.h index 1c33f53..469cbb6 100644 --- a/content/browser/indexed_db/indexed_db_transaction.h +++ b/content/browser/indexed_db/indexed_db_transaction.h
@@ -62,6 +62,11 @@ leveldb::Status Commit(); + // If is_commit_pending_ is true this method does the necessary state + // manipulation to prepare the transaction to be committed, processes its + // task_queue_, and commits the transaction. + void ForcePendingCommit(); + // This object is destroyed by this method. void Abort(const IndexedDBDatabaseError& error); @@ -104,6 +109,7 @@ IndexedDBDatabase* database() const { return database_.get(); } IndexedDBDatabaseCallbacks* callbacks() const { return callbacks_.get(); } IndexedDBConnection* connection() const { return connection_.get(); } + bool is_commit_pending() const { return is_commit_pending_; } State state() const { return state_; } bool IsTimeoutTimerRunning() const { return timeout_timer_.IsRunning(); } @@ -182,7 +188,7 @@ bool used_ = false; State state_ = CREATED; - bool commit_pending_ = false; + bool is_commit_pending_ = false; // We are owned by the connection object, but during force closes sometimes // there are issues if there is a pending OpenRequest. So use a WeakPtr. base::WeakPtr<IndexedDBConnection> connection_;
diff --git a/content/browser/indexed_db/indexed_db_transaction_unittest.cc b/content/browser/indexed_db/indexed_db_transaction_unittest.cc index 88f15cb..2e51dce7 100644 --- a/content/browser/indexed_db/indexed_db_transaction_unittest.cc +++ b/content/browser/indexed_db/indexed_db_transaction_unittest.cc
@@ -435,7 +435,7 @@ EXPECT_FALSE(transaction->should_process_queue_); EXPECT_TRUE(transaction->backing_store_transaction_begun_); EXPECT_TRUE(transaction->used_); - EXPECT_FALSE(transaction->commit_pending_); + EXPECT_FALSE(transaction->is_commit_pending_); // This task will be ignored. transaction->ScheduleTask(
diff --git a/content/browser/renderer_host/dwrite_font_proxy_impl_win.cc b/content/browser/renderer_host/dwrite_font_proxy_impl_win.cc index 5624cc4..f7ab7ae9 100644 --- a/content/browser/renderer_host/dwrite_font_proxy_impl_win.cc +++ b/content/browser/renderer_host/dwrite_font_proxy_impl_win.cc
@@ -303,7 +303,7 @@ // static void DWriteFontProxyImpl::Create( - mojom::DWriteFontProxyRequest request, + blink::mojom::DWriteFontProxyRequest request, const service_manager::BindSourceInfo& source_info) { mojo::MakeStrongBinding(std::make_unique<DWriteFontProxyImpl>(), std::move(request)); @@ -342,7 +342,7 @@ InitializeDirectWrite(); TRACE_EVENT0("dwrite", "FontProxyHost::OnGetFamilyNames"); callback = mojo::WrapCallbackWithDefaultInvokeIfNotRun( - std::move(callback), std::vector<mojom::DWriteStringPairPtr>()); + std::move(callback), std::vector<blink::mojom::DWriteStringPairPtr>()); if (!collection_) return; @@ -364,7 +364,7 @@ std::vector<base::char16> locale; std::vector<base::char16> name; - std::vector<mojom::DWriteStringPairPtr> family_names; + std::vector<blink::mojom::DWriteStringPairPtr> family_names; for (size_t index = 0; index < string_count; ++index) { UINT32 length = 0; hr = localized_names->GetLocaleNameLength(index, &length); @@ -464,20 +464,21 @@ std::move(callback).Run(file_paths, std::move(file_handles)); } -void DWriteFontProxyImpl::MapCharacters(const base::string16& text, - mojom::DWriteFontStylePtr font_style, - const base::string16& locale_name, - uint32_t reading_direction, - const base::string16& base_family_name, - MapCharactersCallback callback) { +void DWriteFontProxyImpl::MapCharacters( + const base::string16& text, + blink::mojom::DWriteFontStylePtr font_style, + const base::string16& locale_name, + uint32_t reading_direction, + const base::string16& base_family_name, + MapCharactersCallback callback) { InitializeDirectWrite(); callback = mojo::WrapCallbackWithDefaultInvokeIfNotRun( std::move(callback), - mojom::MapCharactersResult::New( + blink::mojom::MapCharactersResult::New( UINT32_MAX, L"", text.length(), 0.0, - mojom::DWriteFontStyle::New(DWRITE_FONT_STYLE_NORMAL, - DWRITE_FONT_STRETCH_NORMAL, - DWRITE_FONT_WEIGHT_NORMAL))); + blink::mojom::DWriteFontStyle::New(DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, + DWRITE_FONT_WEIGHT_NORMAL))); if (factory2_ == nullptr || collection_ == nullptr) return; if (font_fallback_ == nullptr) { @@ -503,11 +504,11 @@ return; } - auto result = mojom::MapCharactersResult::New( + auto result = blink::mojom::MapCharactersResult::New( UINT32_MAX, L"", text.length(), 0.0, - mojom::DWriteFontStyle::New(DWRITE_FONT_STYLE_NORMAL, - DWRITE_FONT_STRETCH_NORMAL, - DWRITE_FONT_WEIGHT_NORMAL)); + blink::mojom::DWriteFontStyle::New(DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, + DWRITE_FONT_WEIGHT_NORMAL)); if (FAILED(font_fallback_->MapCharacters( analysis_source.Get(), 0, text.length(), collection_.Get(), base_family_name.c_str(),
diff --git a/content/browser/renderer_host/dwrite_font_proxy_impl_win.h b/content/browser/renderer_host/dwrite_font_proxy_impl_win.h index 798b4e8..fd48943 100644 --- a/content/browser/renderer_host/dwrite_font_proxy_impl_win.h +++ b/content/browser/renderer_host/dwrite_font_proxy_impl_win.h
@@ -17,9 +17,9 @@ #include "base/memory/ref_counted.h" #include "base/strings/string16.h" #include "content/common/content_export.h" -#include "content/common/dwrite_font_proxy.mojom.h" #include "content/public/browser/browser_message_filter.h" #include "content/public/browser/browser_thread.h" +#include "third_party/blink/public/mojom/dwrite_font_proxy/dwrite_font_proxy.mojom.h" namespace service_manager { struct BindSourceInfo; @@ -30,18 +30,19 @@ // Implements a message filter that handles the dwrite font proxy messages. // If DWrite is enabled, calls into the system font collection to obtain // results. Otherwise, acts as if the system collection contains no fonts. -class CONTENT_EXPORT DWriteFontProxyImpl : public mojom::DWriteFontProxy { +class CONTENT_EXPORT DWriteFontProxyImpl + : public blink::mojom::DWriteFontProxy { public: DWriteFontProxyImpl(); ~DWriteFontProxyImpl() override; - static void Create(mojom::DWriteFontProxyRequest request, + static void Create(blink::mojom::DWriteFontProxyRequest request, const service_manager::BindSourceInfo& source_info); void SetWindowsFontsPathForTesting(base::string16 path); protected: - // mojom::DWriteFontProxy: + // blink::mojom::DWriteFontProxy: void FindFamily(const base::string16& family_name, FindFamilyCallback callback) override; void GetFamilyCount(GetFamilyCountCallback callback) override; @@ -50,7 +51,7 @@ void GetFontFiles(uint32_t family_index, GetFontFilesCallback callback) override; void MapCharacters(const base::string16& text, - mojom::DWriteFontStylePtr font_style, + blink::mojom::DWriteFontStylePtr font_style, const base::string16& locale_name, uint32_t reading_direction, const base::string16& base_family_name,
diff --git a/content/browser/renderer_host/dwrite_font_proxy_impl_win_unittest.cc b/content/browser/renderer_host/dwrite_font_proxy_impl_win_unittest.cc index b7e405d6..74d510fe6 100644 --- a/content/browser/renderer_host/dwrite_font_proxy_impl_win_unittest.cc +++ b/content/browser/renderer_host/dwrite_font_proxy_impl_win_unittest.cc
@@ -30,12 +30,14 @@ DWriteFontProxyImplUnitTest() : binding_(&impl_, mojo::MakeRequest(&dwrite_font_proxy_)) {} - mojom::DWriteFontProxy& dwrite_font_proxy() { return *dwrite_font_proxy_; } + blink::mojom::DWriteFontProxy& dwrite_font_proxy() { + return *dwrite_font_proxy_; + } base::test::ScopedTaskEnvironment scoped_task_environment_; - mojom::DWriteFontProxyPtr dwrite_font_proxy_; + blink::mojom::DWriteFontProxyPtr dwrite_font_proxy_; DWriteFontProxyImpl impl_; - mojo::Binding<mojom::DWriteFontProxy> binding_; + mojo::Binding<blink::mojom::DWriteFontProxy> binding_; }; TEST_F(DWriteFontProxyImplUnitTest, GetFamilyCount) { @@ -63,7 +65,7 @@ UINT32 arial_index = 0; dwrite_font_proxy().FindFamily(L"Arial", &arial_index); - std::vector<mojom::DWriteStringPairPtr> names; + std::vector<blink::mojom::DWriteStringPairPtr> names; dwrite_font_proxy().GetFamilyNames(arial_index, &names); EXPECT_LT(0u, names.size()); @@ -74,7 +76,7 @@ } TEST_F(DWriteFontProxyImplUnitTest, GetFamilyNamesIndexOutOfBounds) { - std::vector<mojom::DWriteStringPairPtr> names; + std::vector<blink::mojom::DWriteStringPairPtr> names; UINT32 invalid_index = 1000000; dwrite_font_proxy().GetFamilyNames(invalid_index, &names); @@ -108,12 +110,12 @@ if (!blink::DWriteRasterizerSupport::IsDWriteFactory2Available()) return; - mojom::MapCharactersResultPtr result; + blink::mojom::MapCharactersResultPtr result; dwrite_font_proxy().MapCharacters( L"abc", - mojom::DWriteFontStyle::New(DWRITE_FONT_WEIGHT_NORMAL, - DWRITE_FONT_STYLE_NORMAL, - DWRITE_FONT_STRETCH_NORMAL), + blink::mojom::DWriteFontStyle::New(DWRITE_FONT_WEIGHT_NORMAL, + DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL), L"", DWRITE_READING_DIRECTION_LEFT_TO_RIGHT, L"", &result); EXPECT_NE(UINT32_MAX, result->family_index); @@ -129,12 +131,12 @@ if (!blink::DWriteRasterizerSupport::IsDWriteFactory2Available()) return; - mojom::MapCharactersResultPtr result; + blink::mojom::MapCharactersResultPtr result; dwrite_font_proxy().MapCharacters( L"\ufffe\uffffabc", - mojom::DWriteFontStyle::New(DWRITE_FONT_WEIGHT_NORMAL, - DWRITE_FONT_STYLE_NORMAL, - DWRITE_FONT_STRETCH_NORMAL), + blink::mojom::DWriteFontStyle::New(DWRITE_FONT_WEIGHT_NORMAL, + DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL), L"en-us", DWRITE_READING_DIRECTION_LEFT_TO_RIGHT, L"", &result); EXPECT_EQ(UINT32_MAX, result->family_index); @@ -146,12 +148,12 @@ if (!blink::DWriteRasterizerSupport::IsDWriteFactory2Available()) return; - mojom::MapCharactersResultPtr result; + blink::mojom::MapCharactersResultPtr result; dwrite_font_proxy().MapCharacters( L"abc\ufffe\uffff", - mojom::DWriteFontStyle::New(DWRITE_FONT_WEIGHT_NORMAL, - DWRITE_FONT_STYLE_NORMAL, - DWRITE_FONT_STRETCH_NORMAL), + blink::mojom::DWriteFontStyle::New(DWRITE_FONT_WEIGHT_NORMAL, + DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL), L"en-us", DWRITE_READING_DIRECTION_LEFT_TO_RIGHT, L"", &result); EXPECT_NE(UINT32_MAX, result->family_index);
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc index f8555c0..28ba2bd 100644 --- a/content/browser/web_contents/web_contents_impl_unittest.cc +++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -427,45 +427,22 @@ // Browser initiated navigations to view-source URLs of WebUI pages should work. TEST_F(WebContentsImplTest, DirectNavigationToViewSourceWebUI) { - NavigationControllerImpl& cont = - static_cast<NavigationControllerImpl&>(controller()); - const GURL kGURL("view-source:chrome://blah"); + const GURL kGURL("view-source:chrome://blah/"); // NavigationControllerImpl rewrites view-source URLs, simulating that here. const GURL kRewrittenURL("chrome://blah"); process()->sink().ClearMessages(); - // Use LoadURLWithParams instead of LoadURL, because the former properly - // rewrites view-source:chrome://blah URLs to chrome://blah. - NavigationController::LoadURLParams load_params(kGURL); - load_params.transition_type = ui::PAGE_TRANSITION_TYPED; - load_params.extra_headers = "content-type: text/plain"; - load_params.load_type = NavigationController::LOAD_TYPE_DEFAULT; - load_params.is_renderer_initiated = false; - controller().LoadURLWithParams(load_params); + NavigationSimulator::NavigateAndCommitFromBrowser(contents(), kGURL); - NavigationRequest* request = - main_test_rfh()->frame_tree_node()->navigation_request(); - CHECK(request); - - int entry_id = cont.GetPendingEntry()->GetUniqueID(); // Did we get the expected message? EXPECT_TRUE(process()->sink().GetFirstMessageMatching( FrameMsg_EnableViewSourceMode::ID)); - FrameHostMsg_DidCommitProvisionalLoad_Params params; - InitNavigateParams(¶ms, entry_id, true, kRewrittenURL, - ui::PAGE_TRANSITION_TYPED); - main_test_rfh()->PrepareForCommit(); - main_test_rfh()->SimulateCommitProcessed( - request->navigation_handle()->GetNavigationId(), - true /* was_successful */); - main_test_rfh()->SendNavigateWithParams(¶ms, - false /* was_within_same_document */); - // This is the virtual URL. - EXPECT_EQ(base::ASCIIToUTF16("view-source:chrome://blah"), - contents()->GetTitle()); + EXPECT_EQ( + kGURL, + contents()->GetController().GetLastCommittedEntry()->GetVirtualURL()); // The actual URL navigated to. EXPECT_EQ(kRewrittenURL,
diff --git a/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc b/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc index 80894616..b5cd80b 100644 --- a/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc +++ b/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc
@@ -30,7 +30,7 @@ DWriteFontCollectionProxy* g_font_collection = nullptr; FontFallback* g_font_fallback = nullptr; -base::RepeatingCallback<mojom::DWriteFontProxyPtrInfo(void)>* +base::RepeatingCallback<blink::mojom::DWriteFontProxyPtrInfo(void)>* g_connection_callback_override = nullptr; // Windows-only DirectWrite support. These warm up the DirectWrite paths @@ -53,7 +53,7 @@ CreateDirectWriteFactory(&factory); if (!g_font_collection) { - mojom::DWriteFontProxyPtrInfo dwrite_font_proxy; + blink::mojom::DWriteFontProxyPtrInfo dwrite_font_proxy; if (g_connection_callback_override) { dwrite_font_proxy = g_connection_callback_override->Run(); } else if (connector) { @@ -99,10 +99,11 @@ } void SetDWriteFontProxySenderForTesting( - base::RepeatingCallback<mojom::DWriteFontProxyPtrInfo(void)> sender) { + base::RepeatingCallback<blink::mojom::DWriteFontProxyPtrInfo(void)> + sender) { DCHECK(!g_connection_callback_override); g_connection_callback_override = - new base::RepeatingCallback<mojom::DWriteFontProxyPtrInfo(void)>( + new base::RepeatingCallback<blink::mojom::DWriteFontProxyPtrInfo(void)>( std::move(sender)); }
diff --git a/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.h b/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.h index b2d4c1bc..42b8d18 100644 --- a/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.h +++ b/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.h
@@ -7,8 +7,8 @@ #include "base/callback.h" #include "content/common/content_export.h" -#include "content/common/dwrite_font_proxy.mojom.h" #include "content/public/child/dwrite_font_proxy_init_win.h" +#include "third_party/blink/public/mojom/dwrite_font_proxy/dwrite_font_proxy.mojom.h" namespace content { @@ -16,7 +16,7 @@ // useful in tests which use a fake render thread which is unable to process // font IPC messages. This should only be called when running as a test. CONTENT_EXPORT void SetDWriteFontProxySenderForTesting( - base::RepeatingCallback<mojom::DWriteFontProxyPtrInfo(void)> sender); + base::RepeatingCallback<blink::mojom::DWriteFontProxyPtrInfo(void)> sender); // Cleans up the fake dwrite font proxy connection factory. CONTENT_EXPORT void ClearDWriteFontProxySenderForTesting();
diff --git a/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc b/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc index af3869e..0aa429dd 100644 --- a/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc +++ b/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc
@@ -73,9 +73,10 @@ } // namespace -HRESULT DWriteFontCollectionProxy::Create(DWriteFontCollectionProxy** proxy_out, - IDWriteFactory* dwrite_factory, - mojom::DWriteFontProxyPtrInfo proxy) { +HRESULT DWriteFontCollectionProxy::Create( + DWriteFontCollectionProxy** proxy_out, + IDWriteFactory* dwrite_factory, + blink::mojom::DWriteFontProxyPtrInfo proxy) { return Microsoft::WRL::MakeAndInitialize<DWriteFontCollectionProxy>( proxy_out, dwrite_factory, std::move(proxy)); } @@ -261,7 +262,7 @@ HRESULT DWriteFontCollectionProxy::RuntimeClassInitialize( IDWriteFactory* factory, - mojom::DWriteFontProxyPtrInfo proxy) { + blink::mojom::DWriteFontProxyPtrInfo proxy) { DCHECK(factory); factory_ = factory; @@ -318,7 +319,7 @@ IDWriteLocalizedStrings** localized_strings) { TRACE_EVENT0("dwrite", "FontProxy::LoadFamilyNames"); - std::vector<mojom::DWriteStringPairPtr> pairs; + std::vector<blink::mojom::DWriteStringPairPtr> pairs; if (!GetFontProxy().GetFamilyNames(family_index, &pairs)) { return false; } @@ -355,22 +356,23 @@ return true; } -void DWriteFontCollectionProxy::SetProxy(mojom::DWriteFontProxyPtrInfo proxy) { - font_proxy_ = mojom::ThreadSafeDWriteFontProxyPtr::Create( +void DWriteFontCollectionProxy::SetProxy( + blink::mojom::DWriteFontProxyPtrInfo proxy) { + font_proxy_ = blink::mojom::ThreadSafeDWriteFontProxyPtr::Create( std::move(proxy), base::CreateSequencedTaskRunnerWithTraits( {base::WithBaseSyncPrimitives()})); } -mojom::DWriteFontProxy& DWriteFontCollectionProxy::GetFontProxy() { +blink::mojom::DWriteFontProxy& DWriteFontCollectionProxy::GetFontProxy() { if (!font_proxy_) { - mojom::DWriteFontProxyPtrInfo dwrite_font_proxy; + blink::mojom::DWriteFontProxyPtrInfo dwrite_font_proxy; if (main_task_runner_->RunsTasksInCurrentSequence()) { ChildThread::Get()->GetConnector()->BindInterface( mojom::kBrowserServiceName, mojo::MakeRequest(&dwrite_font_proxy)); } else { main_task_runner_->PostTask( FROM_HERE, base::BindOnce( - [](mojom::DWriteFontProxyRequest request) { + [](blink::mojom::DWriteFontProxyRequest request) { ChildThread::Get()->GetConnector()->BindInterface( mojom::kBrowserServiceName, std::move(request)); },
diff --git a/content/child/dwrite_font_proxy/dwrite_font_proxy_win.h b/content/child/dwrite_font_proxy/dwrite_font_proxy_win.h index 0943acd7..40c92d3 100644 --- a/content/child/dwrite_font_proxy/dwrite_font_proxy_win.h +++ b/content/child/dwrite_font_proxy/dwrite_font_proxy_win.h
@@ -16,7 +16,7 @@ #include "base/macros.h" #include "base/strings/string16.h" #include "content/common/content_export.h" -#include "content/common/dwrite_font_proxy.mojom.h" +#include "third_party/blink/public/mojom/dwrite_font_proxy/dwrite_font_proxy.mojom.h" namespace content { @@ -35,9 +35,10 @@ IDWriteFontFileLoader> { public: // Factory method to avoid exporting the class and all it derives from. - static CONTENT_EXPORT HRESULT Create(DWriteFontCollectionProxy** proxy_out, - IDWriteFactory* dwrite_factory, - mojom::DWriteFontProxyPtrInfo proxy); + static CONTENT_EXPORT HRESULT + Create(DWriteFontCollectionProxy** proxy_out, + IDWriteFactory* dwrite_factory, + blink::mojom::DWriteFontProxyPtrInfo proxy); // Use Create() to construct these objects. Direct calls to the constructor // are an error - it is only public because a WRL helper function creates the @@ -70,7 +71,7 @@ CONTENT_EXPORT HRESULT STDMETHODCALLTYPE RuntimeClassInitialize(IDWriteFactory* factory, - mojom::DWriteFontProxyPtrInfo proxy); + blink::mojom::DWriteFontProxyPtrInfo proxy); CONTENT_EXPORT void Unregister(); @@ -87,17 +88,17 @@ bool CreateFamily(UINT32 family_index); - mojom::DWriteFontProxy& GetFontProxy(); + blink::mojom::DWriteFontProxy& GetFontProxy(); private: - void SetProxy(mojom::DWriteFontProxyPtrInfo); + void SetProxy(blink::mojom::DWriteFontProxyPtrInfo); Microsoft::WRL::ComPtr<IDWriteFactory> factory_; std::vector<Microsoft::WRL::ComPtr<DWriteFontFamilyProxy>> families_; std::map<base::string16, UINT32> family_names_; UINT32 family_count_ = UINT_MAX; scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; - scoped_refptr<mojom::ThreadSafeDWriteFontProxyPtr> font_proxy_; + scoped_refptr<blink::mojom::ThreadSafeDWriteFontProxyPtr> font_proxy_; DISALLOW_ASSIGN(DWriteFontCollectionProxy); };
diff --git a/content/child/dwrite_font_proxy/font_fallback_win.cc b/content/child/dwrite_font_proxy/font_fallback_win.cc index 25dbef98..a2619d6 100644 --- a/content/child/dwrite_font_proxy/font_fallback_win.cc +++ b/content/child/dwrite_font_proxy/font_fallback_win.cc
@@ -98,13 +98,14 @@ locale = locale ? locale : L""; - mojom::MapCharactersResultPtr result; + blink::mojom::MapCharactersResultPtr result; - if (!GetFontProxy().MapCharacters( - text_chunk, - mojom::DWriteFontStyle::New(base_weight, base_style, base_stretch), - locale, source->GetParagraphReadingDirection(), base_family_name, - &result)) { + if (!GetFontProxy().MapCharacters(text_chunk, + blink::mojom::DWriteFontStyle::New( + base_weight, base_style, base_stretch), + locale, + source->GetParagraphReadingDirection(), + base_family_name, &result)) { DCHECK(false); return E_FAIL; } @@ -222,7 +223,7 @@ family_list.pop_back(); } -mojom::DWriteFontProxy& FontFallback::GetFontProxy() { +blink::mojom::DWriteFontProxy& FontFallback::GetFontProxy() { return collection_->GetFontProxy(); }
diff --git a/content/child/dwrite_font_proxy/font_fallback_win.h b/content/child/dwrite_font_proxy/font_fallback_win.h index ca22abc..5c0f011 100644 --- a/content/child/dwrite_font_proxy/font_fallback_win.h +++ b/content/child/dwrite_font_proxy/font_fallback_win.h
@@ -14,7 +14,7 @@ #include "content/child/dwrite_font_proxy/dwrite_font_proxy_win.h" #include "content/common/content_export.h" -#include "content/common/dwrite_font_proxy.mojom.h" +#include "third_party/blink/public/mojom/dwrite_font_proxy/dwrite_font_proxy.mojom.h" namespace content { @@ -65,7 +65,7 @@ const wchar_t* base_family_name); private: - mojom::DWriteFontProxy& GetFontProxy(); + blink::mojom::DWriteFontProxy& GetFontProxy(); Microsoft::WRL::ComPtr<DWriteFontCollectionProxy> collection_;
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index b3b1de9..f8cb3ab 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -518,11 +518,6 @@ if (!base::FeatureList::IsEnabled(features::kBackgroundFetch)) WebRuntimeFeatures::EnableBackgroundFetch(false); - WebRuntimeFeatures::EnableBackgroundFetchAccessActiveFetches( - base::FeatureList::IsEnabled( - features::kBackgroundFetchAccessActiveFetches) || - enable_experimental_web_platform_features); - WebRuntimeFeatures::EnableBackgroundFetchUploads( base::FeatureList::IsEnabled(features::kBackgroundFetchUploads) || enable_experimental_web_platform_features);
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index d6df7633..7e59f845 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -511,10 +511,6 @@ "widget.mojom", ] - if (is_win) { - sources += [ "dwrite_font_proxy.mojom" ] - } - if (is_mac) { sources += [ "render_widget_host_ns_view.mojom",
diff --git a/content/public/android/java/res/layout/text_edit_suggestion_list_footer.xml b/content/public/android/java/res/layout/text_edit_suggestion_list_footer.xml index 177739cd..c3bca876 100644 --- a/content/public/android/java/res/layout/text_edit_suggestion_list_footer.xml +++ b/content/public/android/java/res/layout/text_edit_suggestion_list_footer.xml
@@ -14,11 +14,11 @@ android:layout_height="1dp" android:layout_width="match_parent" /> <TextView - style="@style/TextSuggestionButton" + style="@style/TextAppearance.TextSuggestionButton" android:id="@+id/addToDictionaryButton" android:text="@string/add_to_dictionary" /> <TextView - style="@style/TextSuggestionButton" + style="@style/TextAppearance.TextSuggestionButton" android:id="@+id/deleteButton" android:text="@string/delete_suggestion_text" /> </LinearLayout>
diff --git a/content/public/android/java/res/values-v17/styles.xml b/content/public/android/java/res/values-v17/styles.xml index 15dfb4a..3bd394f 100644 --- a/content/public/android/java/res/values-v17/styles.xml +++ b/content/public/android/java/res/values-v17/styles.xml
@@ -16,12 +16,10 @@ <style name="SelectActionMenuWebSearch"> <item name="android:icon">@drawable/ic_search</item> </style> - <style name="SuggestionPrefixOrSuffix"> + <style name="TextAppearance.SuggestionPrefixOrSuffix"> <item name="android:textColor">?android:attr/textColorSecondary</item> </style> - <!-- TODO(https://crbug.com/856244): remove textAllCaps from button style and move it to - button textAppearance styles. --> - <style name="TextSuggestionButton"> + <style name="TextAppearance.TextSuggestionButton"> <item name="android:drawablePadding">8dp</item> <!-- v21 uses sans-serif-medium --> <item name="android:gravity">start|center_vertical</item> @@ -34,7 +32,6 @@ <item name="android:paddingTop">8dp</item> <item name="android:singleLine">true</item> <!-- v21 uses android:attr/colorAccent --> - <item name="android:textAppearance">@style/BlueButtonText2</item> - <item name="android:textAllCaps">true</item> + <item name="android:textAppearance">@style/TextAppearance.BlueButtonText2</item> </style> </resources>
diff --git a/content/public/android/java/res/values-v21/styles.xml b/content/public/android/java/res/values-v21/styles.xml index 1adf187..9805c49 100644 --- a/content/public/android/java/res/values-v21/styles.xml +++ b/content/public/android/java/res/values-v21/styles.xml
@@ -10,9 +10,7 @@ <style name="SelectActionMenuWebSearch"> <item name="android:icon">?android:attr/actionModeWebSearchDrawable</item> </style> - <!-- TODO(https://crbug.com/856244): remove textAllCaps from button style and move it to - button textAppearance styles. --> - <style name="TextSuggestionButton"> + <style name="TextAppearance.TextSuggestionButton"> <item name="android:drawablePadding">8dp</item> <item name="android:gravity">start|center_vertical</item> <item name="android:layout_gravity">start|center_vertical</item> @@ -24,11 +22,10 @@ <item name="android:paddingTop">8dp</item> <item name="android:singleLine">true</item> <!-- v17 hard codes modern_blue_600 --> - <item name="android:textAppearance">@style/TextSuggestionButtonText</item> - <item name="android:textAllCaps">true</item> + <item name="android:textAppearance">@style/TextAppearance.TextSuggestionButtonText</item> </style> - <style name="TextSuggestionButtonText" parent="@style/BlueButtonText2"> + <style name="TextAppearance.TextSuggestionButtonText" parent="@style/TextAppearance.BlueButtonText2"> <item name="android:textColor">?android:attr/colorAccent</item> </style> </resources>
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/TextSuggestionsPopupWindow.java b/content/public/android/java/src/org/chromium/content/browser/input/TextSuggestionsPopupWindow.java index f607e6733..84d65e89 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/TextSuggestionsPopupWindow.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/TextSuggestionsPopupWindow.java
@@ -32,8 +32,10 @@ WindowAndroid windowAndroid, View parentView) { super(context, textSuggestionHost, windowAndroid, parentView); - mPrefixSpan = new TextAppearanceSpan(context, R.style.SuggestionPrefixOrSuffix); - mSuffixSpan = new TextAppearanceSpan(context, R.style.SuggestionPrefixOrSuffix); + mPrefixSpan = + new TextAppearanceSpan(context, R.style.TextAppearance_SuggestionPrefixOrSuffix); + mSuffixSpan = + new TextAppearanceSpan(context, R.style.TextAppearance_SuggestionPrefixOrSuffix); } /**
diff --git a/content/public/app/mojo/content_browser_manifest.json b/content/public/app/mojo/content_browser_manifest.json index ebfeba7e..e87857b 100644 --- a/content/public/app/mojo/content_browser_manifest.json +++ b/content/public/app/mojo/content_browser_manifest.json
@@ -16,7 +16,7 @@ "memory_instrumentation.mojom.Coordinator" ], "dwrite_font_proxy": [ - "content.mojom.DWriteFontProxy" + "blink.mojom.DWriteFontProxy" ], "field_trials": [ "content.mojom.FieldTrialRecorder"
diff --git a/content/public/browser/background_fetch_delegate.h b/content/public/browser/background_fetch_delegate.h index 2c7574be..fb28a0f2 100644 --- a/content/public/browser/background_fetch_delegate.h +++ b/content/public/browser/background_fetch_delegate.h
@@ -99,6 +99,9 @@ // Called when the UI of a background fetch job is activated. virtual void OnUIActivated(const std::string& job_unique_id) = 0; + // Called after the UI has been updated. + virtual void OnUIUpdated(const std::string& job_unique_id) = 0; + // Called by the Download Client when it needs the upload data for // the given |download_guid|. virtual void GetUploadData(const std::string& job_unique_id,
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 2a10c60..958afbdb 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -57,10 +57,6 @@ const base::Feature kBackgroundFetch{"BackgroundFetch", base::FEATURE_ENABLED_BY_DEFAULT}; -// Enables access to active background fetches. -const base::Feature kBackgroundFetchAccessActiveFetches{ - "BackgroundFetchAccessActiveFetches", base::FEATURE_DISABLED_BY_DEFAULT}; - // Enables using uploads in a Background Fetch. const base::Feature kBackgroundFetchUploads{"BackgroundFetchUploads", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index 5728770..41d969d 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -27,7 +27,6 @@ CONTENT_EXPORT extern const base::Feature kAudioServiceOutOfProcess; CONTENT_EXPORT extern const base::Feature kAwaitOptimization; CONTENT_EXPORT extern const base::Feature kBackgroundFetch; -CONTENT_EXPORT extern const base::Feature kBackgroundFetchAccessActiveFetches; CONTENT_EXPORT extern const base::Feature kBackgroundFetchUploads; CONTENT_EXPORT extern const base::Feature kBackForwardCache; CONTENT_EXPORT extern const base::Feature kBlinkHeapIncrementalMarking;
diff --git a/content/public/test/navigation_simulator.cc b/content/public/test/navigation_simulator.cc index 13a90ac..4029c13 100644 --- a/content/public/test/navigation_simulator.cc +++ b/content/public/test/navigation_simulator.cc
@@ -20,7 +20,6 @@ #include "content/public/browser/web_contents.h" #include "content/public/common/navigation_policy.h" #include "content/public/common/url_utils.h" -#include "content/test/mock_navigation_client_impl.h" #include "content/test/test_navigation_url_loader.h" #include "content/test/test_render_frame_host.h" #include "content/test/test_web_contents.h" @@ -970,8 +969,7 @@ if (IsPerNavigationMojoInterfaceEnabled()) { mojom::NavigationClientAssociatedPtr navigation_client_ptr; - StoreNavigationClientRequest( - mojo::MakeRequestAssociatedWithDedicatedPipe(&navigation_client_ptr)); + mojo::MakeRequestAssociatedWithDedicatedPipe(&navigation_client_ptr); render_frame_host_->frame_host_binding_for_testing() .impl() ->BeginNavigation(common_params, std::move(begin_params), nullptr, @@ -1096,10 +1094,4 @@ ui::PageTransitionFromInt(transition_ | ui::PAGE_TRANSITION_FORWARD_BACK); } -void NavigationSimulator::StoreNavigationClientRequest( - mojom::NavigationClientAssociatedRequest navigation_client_request) { - navigation_client_impl_.reset( - new MockNavigationClientImpl(std::move(navigation_client_request))); -} - } // namespace content
diff --git a/content/public/test/navigation_simulator.h b/content/public/test/navigation_simulator.h index 4a94e00..d5cdf2a3 100644 --- a/content/public/test/navigation_simulator.h +++ b/content/public/test/navigation_simulator.h
@@ -25,7 +25,6 @@ namespace content { class FrameTreeNode; -class MockNavigationClientImpl; class NavigationHandle; class NavigationHandleImpl; class NavigationRequest; @@ -33,10 +32,6 @@ class TestRenderFrameHost; struct Referrer; -namespace mojom { -class NavigationClient; -} - // An interface for simulating a navigation in unit tests. Supports both // renderer and browser-initiated navigations. // Note: this should not be used in browser tests. @@ -366,11 +361,6 @@ // offset. Typically -1 for back navigations or 1 for forward navigations. void SetSessionHistoryOffset(int offset); - // Only used when PerNavigationMojoInterface is enabled. - void StoreNavigationClientRequest( - mojo::AssociatedInterfaceRequest<mojom::NavigationClient> - navigation_client_request); - enum State { INITIALIZATION, STARTED, @@ -440,12 +430,6 @@ // result. Calling this will quit the nested run loop. base::OnceClosure wait_closure_; - // A mock NavigationClient implementation that is used because we do not - // actually have a renderer. The navigations would be instantly aborted if - // this was not kept alive. - // Only used when PerNavigationMojoInterface is enabled. - std::unique_ptr<MockNavigationClientImpl> navigation_client_impl_; - base::WeakPtrFactory<NavigationSimulator> weak_factory_; };
diff --git a/content/shell/browser/web_test/web_test_background_fetch_delegate.cc b/content/shell/browser/web_test/web_test_background_fetch_delegate.cc index 2852feb9..f6d03d5c 100644 --- a/content/shell/browser/web_test/web_test_background_fetch_delegate.cc +++ b/content/shell/browser/web_test/web_test_background_fetch_delegate.cc
@@ -182,6 +182,11 @@ std::move(callback).Run(std::move(request_body)); } + const base::WeakPtr<content::BackgroundFetchDelegate::Client>& client() + const { + return client_; + } + private: base::WeakPtr<content::BackgroundFetchDelegate::Client> client_; base::flat_map<std::string, std::string> guid_to_unique_job_id_mapping_; @@ -286,6 +291,8 @@ void WebTestBackgroundFetchDelegate::UpdateUI( const std::string& job_unique_id, const base::Optional<std::string>& title, - const base::Optional<SkBitmap>& icon) {} + const base::Optional<SkBitmap>& icon) { + background_fetch_client_->client()->OnUIUpdated(job_unique_id); +} } // namespace content
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index dc7e463..d065315 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -234,8 +234,6 @@ "mock_keyboard.h", "mock_keyboard_driver_win.cc", "mock_keyboard_driver_win.h", - "mock_navigation_client_impl.cc", - "mock_navigation_client_impl.h", "mock_overscroll_observer.h", "mock_platform_notification_service.cc", "mock_platform_notification_service.h",
diff --git a/content/test/data/indexeddb/blocked_explicit_commit.html b/content/test/data/indexeddb/blocked_explicit_commit.html new file mode 100644 index 0000000..0893d73d --- /dev/null +++ b/content/test/data/indexeddb/blocked_explicit_commit.html
@@ -0,0 +1,11 @@ +<html> + <head> + <title>IndexedDB regression test for bug 98562</title> + <script type="text/javascript" src="shared.js"></script> + <script type="text/javascript" src="common.js"></script> + <script type="text/javascript" src="blocked_explicit_commit.js"></script> + </head> + <body onLoad="test()"> + <div id="status">Starting...</div> + </body> +</html>
diff --git a/content/test/data/indexeddb/blocked_explicit_commit.js b/content/test/data/indexeddb/blocked_explicit_commit.js new file mode 100644 index 0000000..b84ee472 --- /dev/null +++ b/content/test/data/indexeddb/blocked_explicit_commit.js
@@ -0,0 +1,85 @@ +// Copyright (c) 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. + +/** + * @fileoverview Javascript test code for verifying proper committing + * behaviour for transactions that are blocked when a tab is force + * closed. + */ + +function test() { + if (document.location.hash === '#tab1') { + setUpBlockedTransactions(); + } else if (document.location.hash === '#tab2') { + checkForCommit(); + } else { + result('fail - unexpected hash'); + } +} + +function upgradeCallback() { + db = event.target.result; + deleteAllObjectStores(db); + db.createObjectStore('store'); +} + +// We register four transactions, all on the same object store and all readwrite +// so as to incur blocking, and verify the expected results after a crash. +async function setUpBlockedTransactions() { + const db = await + promiseDeleteThenOpenDb('blocked-explicit-commit', upgradeCallback); + + // An auto-committed put that we expect to be committed. + db.transaction('store', 'readwrite').objectStore('store') + .put('auto', 'auto-key'); + + // A transaction with a put request on it that we keep alive with a request + // loop and which we expect to never commit. + const blockingTransaction = db.transaction('store', 'readwrite'); + const blockingRequest = blockingTransaction.objectStore('store') + .put('blocking', 'blocking-key'); + blockingRequest.onsuccess = () => { result('transactions registered'); }; + keepAlive(blockingTransaction, 'store'); + + // A transaction with a put request on it that is blocked by the previous + // transaction. We call an explicit commit on this transaction and so expect + // its data to be committed after tab1 crashes and the blocking transaction is + // aborted. + const commitTransaction = db.transaction('store', 'readwrite'); + commitTransaction.objectStore('store').put('explicit', 'explicit-key'); + commitTransaction.commit(); + + // A transaction with a put request on it that is blocked by the explicit + // commit transaction. It is expected to be aborted and thus never commit + // because it was not explicitly committed. + db.transaction('store', 'readwrite').objectStore('store') + .put('blocked', 'blocked-key'); +} + +async function checkForCommit() { + const db = await promiseOpenDb('blocked-explicit-commit'); + const transaction = db.transaction('store', 'readonly'); + const objectStore = transaction.objectStore('store'); + + const autoRequest = objectStore.get('auto-key'); + const blockingRequest = objectStore.get('blocking-key'); + const explicitRequest = objectStore.get('explicit-key'); + const blockedRequest = objectStore.get('blocked-key'); + + for (const request of [autoRequest, blockingRequest, explicitRequest, + blockedRequest]) { + request.onerror = unexpectedErrorCallback; + request.onblocked = unexpectedBlockedCallback; + } + + transaction.oncomplete = () => { + if (autoRequest.result == 'auto' && blockingRequest.result == undefined + && explicitRequest.result == 'explicit' + && blockedRequest.result == undefined) { + result('transactions aborted and committed as expected'); + } else { + result('fail - transactions did not abort and commit as expected'); + } + }; +}
diff --git a/content/test/data/indexeddb/common.js b/content/test/data/indexeddb/common.js index f0886ef..aa5e5a4 100644 --- a/content/test/data/indexeddb/common.js +++ b/content/test/data/indexeddb/common.js
@@ -147,6 +147,75 @@ }; } +function promiseDeleteThenOpenDb(dbName, upgradeCallback) { + return new Promise((resolve, reject) => { + const deleteRequest = indexedDB.deleteDatabase(dbName); + deleteRequest.onerror = () => { + reject(new Error('An error occurred on deleting database ${dbName}')); + }; + deleteRequest.onsuccess = () => { + const openRequest = indexedDB.open(dbName); + openRequest.onerror = () => { + reject(new Error('An error occurred on opening database ${dbName}')); + }; + openRequest.onblocked = () => { + reject(new Error('Opening database ${dbName} was blocked')); + }; + openRequest.onupgradeneeded = () => { + upgradeCallback(); + }; + openRequest.onsuccess = () => { + resolve(event.target.result); + }; + } + }); +} + +function promiseOpenDb(dbName, optionalUpgradeCallback) { + return new Promise((resolve, reject) => { + const openRequest = indexedDB.open(dbName); + openRequest.onerror = () => { + const e = new Error('Error opening database ${dbName}'); + unexepectedErrorCallback(e); + reject(e); + }; + openRequest.onblocked = () => { + const e = new Error('Opening database ${dbName}'); + unexpectedBlockedCallback(e); + reject(e); + }; + if (optionalUpgradeCallback) { + openRequest.onupgradeneeded = () => { + const db = event.target.result; + optionalUpgradeCallback(db); + }; + } + openRequest.onsuccess = () => { + db = event.target.result; + resolve(db); + }; + }); +} + +function keepAlive(transaction, storeName) { + let completed = false; + transaction.addEventListener('complete', () => { completed = true; }); + + let pin = true; + + function spin() { + if (!pin) + return; + transaction.objectStore(storeName).get(0).onsuccess = spin; + } + spin(); + + return () => { + shouldBeFalse(completed); + pin = false; + }; +} + if (typeof String.prototype.startsWith !== 'function') { String.prototype.startsWith = function (str) { return this.indexOf(str) === 0;
diff --git a/content/test/dwrite_font_fake_sender_win.cc b/content/test/dwrite_font_fake_sender_win.cc index b962bbe..5ba2fa8 100644 --- a/content/test/dwrite_font_fake_sender_win.cc +++ b/content/test/dwrite_font_fake_sender_win.cc
@@ -21,12 +21,12 @@ .AddFilePath(font_path.Append(L"\\" + base_family_name + L"i.ttf")); } -mojom::DWriteFontProxyPtrInfo CreateFakeCollectionPtr( +blink::mojom::DWriteFontProxyPtrInfo CreateFakeCollectionPtr( const std::unique_ptr<FakeFontCollection>& collection) { return collection->CreatePtr(); } -base::RepeatingCallback<mojom::DWriteFontProxyPtrInfo(void)> +base::RepeatingCallback<blink::mojom::DWriteFontProxyPtrInfo(void)> CreateFakeCollectionSender() { std::vector<base::char16> font_path_chars; font_path_chars.resize(MAX_PATH); @@ -56,8 +56,8 @@ return fonts_.back(); } -mojom::DWriteFontProxyPtrInfo FakeFontCollection::CreatePtr() { - mojom::DWriteFontProxyPtrInfo ptr; +blink::mojom::DWriteFontProxyPtrInfo FakeFontCollection::CreatePtr() { + blink::mojom::DWriteFontProxyPtrInfo ptr; bindings_.AddBinding(this, mojo::MakeRequest(&ptr)); return ptr; } @@ -90,7 +90,7 @@ void FakeFontCollection::GetFamilyNames(uint32_t family_index, GetFamilyNamesCallback callback) { message_types_.push_back(MessageType::kGetFamilyNames); - std::vector<mojom::DWriteStringPairPtr> family_names; + std::vector<blink::mojom::DWriteStringPairPtr> family_names; if (family_index < fonts_.size()) { for (const auto& name : fonts_[family_index].family_names_) { family_names.emplace_back(base::in_place, name.first, name.second); @@ -112,18 +112,19 @@ std::move(callback).Run(file_paths, std::move(file_handles)); } -void FakeFontCollection::MapCharacters(const base::string16& text, - mojom::DWriteFontStylePtr font_style, - const base::string16& locale_name, - uint32_t reading_direction, - const base::string16& base_family_name, - MapCharactersCallback callback) { +void FakeFontCollection::MapCharacters( + const base::string16& text, + blink::mojom::DWriteFontStylePtr font_style, + const base::string16& locale_name, + uint32_t reading_direction, + const base::string16& base_family_name, + MapCharactersCallback callback) { message_types_.push_back(MessageType::kMapCharacters); - std::move(callback).Run(mojom::MapCharactersResult::New( + std::move(callback).Run(blink::mojom::MapCharactersResult::New( 0, fonts_[0].font_name(), 1, 1.0, - mojom::DWriteFontStyle::New(DWRITE_FONT_WEIGHT_NORMAL, - DWRITE_FONT_STYLE_NORMAL, - DWRITE_FONT_STRETCH_NORMAL))); + blink::mojom::DWriteFontStyle::New(DWRITE_FONT_WEIGHT_NORMAL, + DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL))); } FakeFontCollection::~FakeFontCollection() = default;
diff --git a/content/test/dwrite_font_fake_sender_win.h b/content/test/dwrite_font_fake_sender_win.h index 3684265..d065803 100644 --- a/content/test/dwrite_font_fake_sender_win.h +++ b/content/test/dwrite_font_fake_sender_win.h
@@ -16,8 +16,8 @@ #include "base/files/file_path.h" #include "base/macros.h" #include "base/strings/string16.h" -#include "content/common/dwrite_font_proxy.mojom.h" #include "mojo/public/cpp/bindings/binding_set.h" +#include "third_party/blink/public/mojom/dwrite_font_proxy/dwrite_font_proxy.mojom.h" namespace content { @@ -25,7 +25,7 @@ // Creates a new FakeFontCollection, seeded with some basic data, and returns a // Sender that can be used to interact with the collection. -base::RepeatingCallback<mojom::DWriteFontProxyPtrInfo(void)> +base::RepeatingCallback<blink::mojom::DWriteFontProxyPtrInfo(void)> CreateFakeCollectionSender(); // Helper class for describing a font object. Use FakeFontCollection instead. @@ -85,7 +85,7 @@ // internally call ReplySender::On*() and ReplySender::Send() // ReplySender::Send() will save the reply message, to be used later. // FakeSender::Send() will retrieve the reply message and save the output. -class FakeFontCollection : public mojom::DWriteFontProxy { +class FakeFontCollection : public blink::mojom::DWriteFontProxy { public: enum class MessageType { kFindFamily, @@ -102,10 +102,10 @@ size_t MessageCount(); MessageType GetMessageType(size_t id); - mojom::DWriteFontProxyPtrInfo CreatePtr(); + blink::mojom::DWriteFontProxyPtrInfo CreatePtr(); protected: - // mojom::DWriteFontProxy: + // blink::mojom::DWriteFontProxy: void FindFamily(const base::string16& family_name, FindFamilyCallback callback) override; void GetFamilyCount(GetFamilyCountCallback callback) override; @@ -114,7 +114,7 @@ void GetFontFiles(uint32_t family_index, GetFontFilesCallback callback) override; void MapCharacters(const base::string16& text, - mojom::DWriteFontStylePtr font_style, + blink::mojom::DWriteFontStylePtr font_style, const base::string16& locale_name, uint32_t reading_direction, const base::string16& base_family_name, @@ -125,7 +125,7 @@ std::vector<MessageType> message_types_; - mojo::BindingSet<mojom::DWriteFontProxy> bindings_; + mojo::BindingSet<blink::mojom::DWriteFontProxy> bindings_; DISALLOW_COPY_AND_ASSIGN(FakeFontCollection); };
diff --git a/content/test/gpu/gpu_tests/pixel_expectations.py b/content/test/gpu/gpu_tests/pixel_expectations.py index 09da641c..9e5705d 100644 --- a/content/test/gpu/gpu_tests/pixel_expectations.py +++ b/content/test/gpu/gpu_tests/pixel_expectations.py
@@ -46,6 +46,13 @@ self.Fail('Pixel_ScissorTestWithPreserveDrawingBuffer', ['android'], bug=521588) + # TODO(kbr): re-enable after rebaseline to clear up Nexus 5 failures + self.Fail('Pixel_Canvas2DRedBox', bug=918952) + self.Fail('Pixel_CanvasDisplayLinearRGBAccelerated2D', bug=918952) + self.Fail('Pixel_CanvasDisplayLinearRGBUnaccelerated2DGPUCompositing', + bug=918952) + self.Fail('Pixel_CanvasLowLatency2D', bug=918952) + # TODO(vmiura) check / generate reference images for Android devices self.Fail('Pixel_SolidColorBackground', ['mac', 'android'], bug=624256)
diff --git a/content/test/gpu/gpu_tests/pixel_test_pages.py b/content/test/gpu/gpu_tests/pixel_test_pages.py index 0604571..dc353c4 100644 --- a/content/test/gpu/gpu_tests/pixel_test_pages.py +++ b/content/test/gpu/gpu_tests/pixel_test_pages.py
@@ -112,7 +112,7 @@ 'pixel_canvas2d.html', base_name + '_Canvas2DRedBox', test_rect=[0, 0, 300, 300], - revision=11), + revision=12), PixelTestPage( 'pixel_canvas2d_untagged.html', @@ -774,7 +774,7 @@ 'pixel_canvas_display_linear-rgb.html', base_name + '_CanvasDisplayLinearRGBAccelerated2D', test_rect=[0, 0, 140, 140], - revision=6, + revision=7, browser_args=browser_args), PixelTestPage( @@ -788,14 +788,14 @@ 'pixel_canvas_display_linear-rgb.html', base_name + '_CanvasDisplayLinearRGBUnaccelerated2DGPUCompositing', test_rect=[0, 0, 140, 140], - revision=6, + revision=7, browser_args=browser_args + ['--disable-accelerated-2d-canvas']), PixelTestPage( 'pixel_canvas_low_latency_2d.html', base_name + '_CanvasLowLatency2D', test_rect=[0, 0, 100, 100], - revision=4, + revision=5, browser_args=browser_args), PixelTestPage(
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py index a27e8a8..9e5a03d 100644 --- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -39,8 +39,6 @@ ['win', 'passthrough', 'opengl', 'intel'], bug=864524) self.Skip('WebglExtension_EXT_disjoint_timer_query_webgl2', ['android'], bug=808744) - self.Fail('WebglExtension_EXT_disjoint_timer_query_webgl2', - ['linux', 'intel'], bug=867675) self.Skip('WebglExtension_KHR_parallel_shader_compile', ['no_passthrough'], bug=849576) @@ -206,6 +204,30 @@ ['win', ('nvidia', 0x1cb3), 'opengl'], bug=822733) # Win / AMD + + # Recently many tests have become flaky on this configuration, returning + # (72, 72, 72) when reading back pixels, rather than the expected values. + # Going to try to skip the individual failing tests, rather than adding a + # wildcard flaky suppression for all of the tests. + self.Skip('conformance2/renderbuffers/' + + 'multisampled-renderbuffer-initialization.html', + ['win', 'amd', 'd3d11'], bug=844483) + self.Skip('conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-float.html', + ['win', 'amd', 'd3d11'], bug=844483) + self.Skip('conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-half_float.html', + ['win', 'amd', 'd3d11'], bug=844483) + self.Skip('conformance2/textures/canvas/tex-3d-rg8-rg-unsigned_byte.html', + ['win', 'amd', 'd3d11'], bug=844483) + self.Skip('conformance2/textures/image_bitmap_from_canvas/' + + 'tex-2d-rgb9_e5-rgb-float.html', + ['win', 'amd', 'd3d11'], bug=844483) + self.Skip('conformance2/textures/image_bitmap_from_canvas/' + + 'tex-2d-rgb9_e5-rgb-half_float.html', + ['win', 'amd', 'd3d11'], bug=844483) + self.Skip('deqp/functional/gles3/texturefiltering/' + + '2d_array_combinations_05.html', + ['win', 'amd', 'd3d11'], bug=844483) + self.Fail('conformance2/rendering/blitframebuffer-stencil-only.html', ['win', 'amd', 'd3d11'], bug=483282) # owner:jmadill @@ -855,11 +877,9 @@ 'tex-2d-rgb-rgb-unsigned_short_5_6_5.html', ['linux'], bug=627525) self.Fail('conformance2/glsl3/vector-dynamic-indexing-nv-driver-bug.html', - ['linux'], bug=905006) + ['linux', 'nvidia'], bug=905006) # Linux Multi-vendor failures. - self.Skip('deqp/data/gles3/shaders/qualification_order.html', - ['linux', 'amd', 'intel'], bug=483282) self.Flaky('deqp/functional/gles3/texturespecification/' + 'random_teximage2d_2d.html', ['linux', 'amd', 'intel'], bug=618447) @@ -979,22 +999,17 @@ self.Fail('deqp/functional/gles3/fbocompleteness.html', ['linux', ('nvidia', 0x1cb3), 'opengl'], bug=703779) - # Linux Intel + # Already fixed with Mesa 17.2.3 self.Fail('conformance2/textures/misc/tex-subimage3d-pixel-buffer-bug.html', ['linux', 'intel'], bug=905011) # WebGL 2.0.1 - self.Fail('deqp/functional/gles3/shadertexturefunction/texturesize.html', ['linux', 'intel'], bug=666384) self.Fail('conformance2/textures/misc/tex-3d-mipmap-levels-intel-bug.html', ['linux', 'intel'], bug=666384) - self.Fail('conformance/extensions/webgl-compressed-texture-astc.html', - ['linux', 'intel'], bug=680675) - # Linux Intel with ANGLE only - self.Fail('conformance2/rendering/blitframebuffer-filter-srgb.html', - ['linux', 'intel', 'opengl'], bug=680276) - self.Fail('conformance2/rendering/blitframebuffer-outside-readbuffer.html', - ['linux', 'intel', 'opengl'], bug=680276) + # Already fixed with Mesa 17.1.6 + self.Fail('conformance/extensions/webgl-compressed-texture-astc.html', + ['linux', 'intel'], bug=680675) # Linux AMD only. # It looks like AMD shader compiler rejects many valid ES3 semantics. @@ -1012,6 +1027,8 @@ ['linux', 'amd'], bug=483282) self.Skip('deqp/data/gles3/shaders/arrays.html', ['linux', 'amd'], bug=483282) + self.Skip('deqp/data/gles3/shaders/qualification_order.html', + ['linux', 'amd'], bug=483282) self.Fail('deqp/functional/gles3/internalformatquery.html', ['linux', 'amd'], bug=483282) self.Fail('deqp/functional/gles3/texturestatequery.html',
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py index 0eb24a3..de61db9 100644 --- a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
@@ -575,7 +575,7 @@ self.Fail('conformance/uniforms/uniform-samplers-test.html', ['mac', 'debug', ('nvidia', 0xfe9)], bug=871352) - # Linux failures + # Already fixed with Mesa 17.1.6 self.Fail('conformance/extensions/webgl-compressed-texture-astc.html', ['linux', 'intel'], bug=680675) @@ -596,6 +596,14 @@ self.Flaky('conformance/extensions/oes-texture-half-float-with-video.html', ['linux', ('nvidia', 0x1cb3)], bug=913969) + # NVIDIA P400 OpenGL, Debug + self.Flaky('conformance/canvas/draw-webgl-to-canvas-test.html', + ['linux', 'debug', ('nvidia', 0x1cb3)], bug=918995) + self.Flaky('conformance/extensions/webgl-depth-texture.html', + ['linux', 'debug', ('nvidia', 0x1cb3)], bug=918995) + self.Flaky('conformance/rendering/polygon-offset.html', + ['linux', 'debug', ('nvidia', 0x1cb3)], bug=918995) + # AMD self.Fail('conformance/glsl/misc/fragcolor-fragdata-invariant.html', ['linux', 'amd'], bug=844311)
diff --git a/content/test/mock_navigation_client_impl.cc b/content/test/mock_navigation_client_impl.cc deleted file mode 100644 index 452d53e9..0000000 --- a/content/test/mock_navigation_client_impl.cc +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/test/mock_navigation_client_impl.h" - -#include "content/public/browser/browser_thread.h" -#include "content/test/test_render_frame_host.h" - -namespace content { - -MockNavigationClientImpl::MockNavigationClientImpl( - mojom::NavigationClientAssociatedRequest request) - : navigation_client_binding_(this, std::move(request)) {} - -MockNavigationClientImpl::~MockNavigationClientImpl() {} - -void MockNavigationClientImpl::CommitNavigation( - const network::ResourceResponseHead& head, - const CommonNavigationParams& common_params, - const CommitNavigationParams& commit_params, - network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, - std::unique_ptr<blink::URLLoaderFactoryBundleInfo> subresource_loaders, - base::Optional<std::vector<::content::mojom::TransferrableURLLoaderPtr>> - subresource_overrides, - blink::mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info, - network::mojom::URLLoaderFactoryPtr prefetch_loader_factory, - const base::UnguessableToken& devtools_navigation_token, - CommitNavigationCallback callback) {} - -void MockNavigationClientImpl::CommitFailedNavigation( - const CommonNavigationParams& common_params, - const CommitNavigationParams& commit_params, - bool has_stale_copy_in_cache, - int error_code, - const base::Optional<std::string>& error_page_content, - std::unique_ptr<blink::URLLoaderFactoryBundleInfo> subresource_loaders, - CommitFailedNavigationCallback callback) {} - -} // namespace content
diff --git a/content/test/mock_navigation_client_impl.h b/content/test/mock_navigation_client_impl.h deleted file mode 100644 index c16d07c..0000000 --- a/content/test/mock_navigation_client_impl.h +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_TEST_MOCK_NAVIGATION_CLIENT_IMPL_H_ -#define CONTENT_TEST_MOCK_NAVIGATION_CLIENT_IMPL_H_ - -#include "content/common/frame.mojom.h" -#include "content/common/navigation_client.mojom.h" -#include "mojo/public/cpp/bindings/associated_binding.h" - -namespace content { - -class MockNavigationClientImpl : public mojom::NavigationClient { - public: - MockNavigationClientImpl(mojom::NavigationClientAssociatedRequest request); - ~MockNavigationClientImpl() override; - - // mojom::NavigationClient implementation - void CommitNavigation( - const network::ResourceResponseHead& head, - const CommonNavigationParams& common_params, - const CommitNavigationParams& commit_params, - network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, - std::unique_ptr<blink::URLLoaderFactoryBundleInfo> subresource_loaders, - base::Optional<std::vector<::content::mojom::TransferrableURLLoaderPtr>> - subresource_overrides, - blink::mojom::ControllerServiceWorkerInfoPtr - controller_service_worker_info, - network::mojom::URLLoaderFactoryPtr prefetch_loader_factory, - const base::UnguessableToken& devtools_navigation_token, - CommitNavigationCallback callback) override; - void CommitFailedNavigation( - const CommonNavigationParams& common_params, - const CommitNavigationParams& commit_params, - bool has_stale_copy_in_cache, - int error_code, - const base::Optional<std::string>& error_page_content, - std::unique_ptr<blink::URLLoaderFactoryBundleInfo> subresource_loaders, - CommitFailedNavigationCallback callback) override; - - private: - mojo::AssociatedBinding<mojom::NavigationClient> navigation_client_binding_; -}; - -} // namespace content - -#endif
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc index 44b1c47..0e7dba59 100644 --- a/content/test/test_render_frame_host.cc +++ b/content/test/test_render_frame_host.cc
@@ -488,9 +488,41 @@ void TestRenderFrameHost::SimulateCommitProcessed(int64_t navigation_id, bool was_successful) { - RenderFrameHostImpl::OnCrossDocumentCommitProcessed( - navigation_id, was_successful ? blink::mojom::CommitResult::Ok - : blink::mojom::CommitResult::Aborted); + blink::mojom::CommitResult result = was_successful + ? blink::mojom::CommitResult::Ok + : blink::mojom::CommitResult::Aborted; + { + auto callback_it = commit_callback_.find(navigation_id); + if (callback_it != commit_callback_.end()) { + std::move(callback_it->second).Run(result); + return; + } + } + + { + auto callback_it = navigation_client_commit_callback_.find(navigation_id); + if (callback_it != navigation_client_commit_callback_.end()) { + std::move(callback_it->second).Run(result); + return; + } + } + + { + auto callback_it = commit_failed_callback_.find(navigation_id); + if (callback_it != commit_failed_callback_.end()) { + std::move(callback_it->second).Run(result); + return; + } + } + + { + auto callback_it = + navigation_client_commit_failed_callback_.find(navigation_id); + if (callback_it != navigation_client_commit_failed_callback_.end()) { + std::move(callback_it->second).Run(result); + return; + } + } } WebBluetoothServiceImpl* @@ -507,6 +539,46 @@ DidSetFramePolicyHeaders(sandbox_flags, declared_policy); } +void TestRenderFrameHost::SendCommitNavigation( + mojom::NavigationClient* navigation_client, + int64_t navigation_id, + const network::ResourceResponseHead& head, + const content::CommonNavigationParams& common_params, + const content::CommitNavigationParams& commit_params, + network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, + std::unique_ptr<blink::URLLoaderFactoryBundleInfo> + subresource_loader_factories, + base::Optional<std::vector<::content::mojom::TransferrableURLLoaderPtr>> + subresource_overrides, + blink::mojom::ControllerServiceWorkerInfoPtr controller, + network::mojom::URLLoaderFactoryPtr prefetch_loader_factory, + const base::UnguessableToken& devtools_navigation_token, + mojom::FrameNavigationControl::CommitNavigationCallback callback) { + if (navigation_client) + navigation_client_commit_callback_[navigation_id] = std::move(callback); + else + commit_callback_[navigation_id] = std::move(callback); +} + +void TestRenderFrameHost::SendCommitFailedNavigation( + mojom::NavigationClient* navigation_client, + int64_t navigation_id, + const content::CommonNavigationParams& common_params, + const content::CommitNavigationParams& commit_params, + bool has_stale_copy_in_cache, + int32_t error_code, + const base::Optional<std::string>& error_page_content, + std::unique_ptr<blink::URLLoaderFactoryBundleInfo> + subresource_loader_factories, + mojom::FrameNavigationControl::CommitFailedNavigationCallback callback) { + if (navigation_client) { + navigation_client_commit_failed_callback_[navigation_id] = + std::move(callback); + } else { + commit_failed_callback_[navigation_id] = std::move(callback); + } +} + // static service_manager::mojom::InterfaceProviderRequest TestRenderFrameHost::CreateStubInterfaceProviderRequest() {
diff --git a/content/test/test_render_frame_host.h b/content/test/test_render_frame_host.h index 84d6795..f1ca410 100644 --- a/content/test/test_render_frame_host.h +++ b/content/test/test_render_frame_host.h
@@ -184,6 +184,37 @@ static service_manager::mojom::InterfaceProviderRequest CreateStubInterfaceProviderRequest(); + protected: + void SendCommitNavigation( + mojom::NavigationClient* navigation_client, + int64_t navigation_id, + const network::ResourceResponseHead& head, + const content::CommonNavigationParams& common_params, + const content::CommitNavigationParams& commit_params, + network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, + std::unique_ptr<blink::URLLoaderFactoryBundleInfo> + subresource_loader_factories, + base::Optional<std::vector<::content::mojom::TransferrableURLLoaderPtr>> + subresource_overrides, + blink::mojom::ControllerServiceWorkerInfoPtr + controller_service_worker_info, + network::mojom::URLLoaderFactoryPtr prefetch_loader_factory, + const base::UnguessableToken& devtools_navigation_token, + mojom::FrameNavigationControl::CommitNavigationCallback callback) + override; + void SendCommitFailedNavigation( + mojom::NavigationClient* navigation_client, + int64_t navigation_id, + const content::CommonNavigationParams& common_params, + const content::CommitNavigationParams& commit_params, + bool has_stale_copy_in_cache, + int32_t error_code, + const base::Optional<std::string>& error_page_content, + std::unique_ptr<blink::URLLoaderFactoryBundleInfo> + subresource_loader_factories, + mojom::FrameNavigationControl::CommitFailedNavigationCallback callback) + override; + private: void SendNavigateWithParameters(int nav_entry_id, bool did_create_new_entry, @@ -213,6 +244,16 @@ // The last commit was for an error page. bool last_commit_was_error_page_; + std::map<int64_t, mojom::FrameNavigationControl::CommitNavigationCallback> + commit_callback_; + std::map<int64_t, mojom::NavigationClient::CommitNavigationCallback> + navigation_client_commit_callback_; + std::map<int64_t, + mojom::FrameNavigationControl::CommitFailedNavigationCallback> + commit_failed_callback_; + std::map<int64_t, mojom::NavigationClient::CommitFailedNavigationCallback> + navigation_client_commit_failed_callback_; + DISALLOW_COPY_AND_ASSIGN(TestRenderFrameHost); };
diff --git a/extensions/browser/event_router.cc b/extensions/browser/event_router.cc index f29668a..57a5add 100644 --- a/extensions/browser/event_router.cc +++ b/extensions/browser/event_router.cc
@@ -71,6 +71,19 @@ args); } +LazyContextId LazyContextIdForBrowserContext(BrowserContext* browser_context, + const EventListener* listener) { + if (listener->is_for_service_worker()) + return LazyContextId(browser_context, listener->extension_id(), + listener->listener_url()); + return LazyContextId(browser_context, listener->extension_id()); +} + +LazyContextId LazyContextIdForListener(const EventListener* listener) { + return LazyContextIdForBrowserContext( + listener->process()->GetBrowserContext(), listener); +} + // A global identifier used to distinguish extension events. base::AtomicSequenceNumber g_extension_event_id; @@ -574,16 +587,12 @@ restrict_to_extension_id != listener->extension_id()) { continue; } - if (listener->IsLazy()) { - if (listener->is_for_service_worker()) { - lazy_event_dispatcher.DispatchToServiceWorker( - *event, listener->extension_id(), listener->listener_url(), - listener->filter()); - } else { - lazy_event_dispatcher.DispatchToEventPage( - *event, listener->extension_id(), listener->filter()); - } - } + if (!listener->IsLazy()) + continue; + + lazy_event_dispatcher.Dispatch( + *event, LazyContextIdForBrowserContext(browser_context_, listener), + listener->filter()); } for (const EventListener* listener : listeners) { @@ -591,10 +600,10 @@ restrict_to_extension_id != listener->extension_id()) { continue; } - if (!listener->process()) + if (listener->IsLazy()) continue; if (lazy_event_dispatcher.HasAlreadyDispatched( - listener->process()->GetBrowserContext(), listener)) { + LazyContextIdForListener(listener))) { continue; }
diff --git a/extensions/browser/events/lazy_event_dispatcher.cc b/extensions/browser/events/lazy_event_dispatcher.cc index 63bcd8b..a62e95c35 100644 --- a/extensions/browser/events/lazy_event_dispatcher.cc +++ b/extensions/browser/events/lazy_event_dispatcher.cc
@@ -24,46 +24,13 @@ LazyEventDispatcher::~LazyEventDispatcher() {} -void LazyEventDispatcher::DispatchToEventPage( +void LazyEventDispatcher::Dispatch( const Event& event, - const ExtensionId& extension_id, - const base::DictionaryValue* listener_filter) { - LazyContextId dispatch_context(browser_context_, extension_id); - DispatchToLazyContext(event, &dispatch_context, listener_filter); -} - -void LazyEventDispatcher::DispatchToServiceWorker( - const Event& event, - const ExtensionId& extension_id, - const GURL& service_worker_scope, - const base::DictionaryValue* listener_filter) { - LazyContextId dispatch_context(browser_context_, extension_id, - service_worker_scope); - DispatchToLazyContext(event, &dispatch_context, listener_filter); -} - -bool LazyEventDispatcher::HasAlreadyDispatched( - BrowserContext* context, - const EventListener* listener) const { - std::unique_ptr<LazyContextId> dispatch_context; - if (listener->is_for_service_worker()) { - dispatch_context = std::make_unique<LazyContextId>( - context, listener->extension_id(), listener->listener_url()); - } else { - dispatch_context = - std::make_unique<LazyContextId>(context, listener->extension_id()); - } - - return HasAlreadyDispatchedImpl(*dispatch_context); -} - -void LazyEventDispatcher::DispatchToLazyContext( - const Event& event, - LazyContextId* dispatch_context, + const LazyContextId& dispatch_context, const base::DictionaryValue* listener_filter) { const Extension* extension = ExtensionRegistry::Get(browser_context_) ->enabled_extensions() - .GetByID(dispatch_context->extension_id()); + .GetByID(dispatch_context.extension_id()); if (!extension) return; @@ -71,16 +38,24 @@ // should load a non-peristent context (a lazy background page or an // extension service worker) to handle the event. We need to use the incognito // context in the case of split-mode extensions. - if (QueueEventDispatch(event, *dispatch_context, extension, listener_filter)) - RecordAlreadyDispatched(*dispatch_context); + if (QueueEventDispatch(event, dispatch_context, extension, listener_filter)) + RecordAlreadyDispatched(dispatch_context); BrowserContext* additional_context = GetIncognitoContext(extension); if (!additional_context) return; - dispatch_context->set_browser_context(additional_context); - if (QueueEventDispatch(event, *dispatch_context, extension, listener_filter)) - RecordAlreadyDispatched(*dispatch_context); + LazyContextId additional_context_id(dispatch_context); + additional_context_id.set_browser_context(additional_context); + if (QueueEventDispatch(event, additional_context_id, extension, + listener_filter)) { + RecordAlreadyDispatched(additional_context_id); + } +} + +bool LazyEventDispatcher::HasAlreadyDispatched( + const LazyContextId& dispatch_context) const { + return base::ContainsKey(dispatched_ids_, dispatch_context); } bool LazyEventDispatcher::QueueEventDispatch( @@ -93,7 +68,7 @@ return false; } - if (HasAlreadyDispatchedImpl(dispatch_context)) + if (HasAlreadyDispatched(dispatch_context)) return false; LazyContextTaskQueue* queue = dispatch_context.GetTaskQueue(); @@ -127,31 +102,9 @@ return true; } -bool LazyEventDispatcher::HasAlreadyDispatchedImpl( - const LazyContextId& dispatch_context) const { - if (dispatch_context.is_for_service_worker()) { - ServiceWorkerDispatchIdentifier dispatch_id( - dispatch_context.browser_context(), - dispatch_context.service_worker_scope()); - return base::ContainsKey(dispatched_ids_for_service_worker_, dispatch_id); - } - DCHECK(dispatch_context.is_for_event_page()); - EventPageDispatchIdentifier dispatch_id(dispatch_context.browser_context(), - dispatch_context.extension_id()); - return base::ContainsKey(dispatched_ids_for_event_page_, dispatch_id); -} - void LazyEventDispatcher::RecordAlreadyDispatched( const LazyContextId& dispatch_context) { - if (dispatch_context.is_for_service_worker()) { - dispatched_ids_for_service_worker_.insert( - std::make_pair(dispatch_context.browser_context(), - dispatch_context.service_worker_scope())); - return; - } - DCHECK(dispatch_context.is_for_event_page()); - dispatched_ids_for_event_page_.insert(std::make_pair( - dispatch_context.browser_context(), dispatch_context.extension_id())); + dispatched_ids_.insert(dispatch_context); } BrowserContext* LazyEventDispatcher::GetIncognitoContext(
diff --git a/extensions/browser/events/lazy_event_dispatcher.h b/extensions/browser/events/lazy_event_dispatcher.h index e09ee60..9533cf8 100644 --- a/extensions/browser/events/lazy_event_dispatcher.h +++ b/extensions/browser/events/lazy_event_dispatcher.h
@@ -9,6 +9,7 @@ #include <utility> #include "base/callback.h" +#include "extensions/browser/lazy_context_id.h" #include "extensions/browser/lazy_context_task_queue.h" #include "extensions/common/extension_id.h" @@ -21,9 +22,7 @@ } namespace extensions { -class EventListener; class Extension; -class LazyContextId; struct Event; // Helper class for EventRouter to dispatch lazy events to lazy contexts. @@ -39,37 +38,23 @@ DispatchFunction dispatch_function); ~LazyEventDispatcher(); - // Dispatches the lazy |event| to |extension_id|. + // Dispatches the lazy |event| to |dispatch_context|. // - // Ensures that all lazy background pages that are interested in the given - // event are loaded, and queues the event if the page is not ready yet. - void DispatchToEventPage(const Event& event, - const ExtensionId& extension_id, - const base::DictionaryValue* listener_filter); - // Dispatches the lazy |event| to |extension_id|'s service worker. + // If [dispatch_context| is for an event page, it ensures all of the pages + // interested in the event are loaded and queues the event if any pages are + // not ready yet. // - // Service workers are started if they were stopped, before dispatching the - // event. - void DispatchToServiceWorker(const Event& event, - const ExtensionId& extension_id, - const GURL& service_worker_scope, - const base::DictionaryValue* listener_filter); + // If [dispatch_context| is for a service worker, it ensures the worker is + // started before dispatching the event. + void Dispatch(const Event& event, + const LazyContextId& dispatch_context, + const base::DictionaryValue* listener_filter); - // Returns whether or not an event listener identical to |listener| is queued - // for dispatch already. - bool HasAlreadyDispatched(content::BrowserContext* context, - const EventListener* listener) const; + // Returns whether or not an event listener identical for |dispatch_context| + // is already queued for dispatch. + bool HasAlreadyDispatched(const LazyContextId& dispatch_context) const; private: - using EventPageDispatchIdentifier = - std::pair<const content::BrowserContext*, std::string>; - using ServiceWorkerDispatchIdentifier = - std::pair<const content::BrowserContext*, GURL>; - - void DispatchToLazyContext(const Event& event, - LazyContextId* dispatch_context, - const base::DictionaryValue* listener_filter); - // Possibly loads given extension's background page or extension Service // Worker in preparation to dispatch an event. Returns true if the event was // queued for subsequent dispatch, false otherwise. @@ -78,8 +63,6 @@ const Extension* extension, const base::DictionaryValue* listener_filter); - bool HasAlreadyDispatchedImpl(const LazyContextId& dispatch_context) const; - void RecordAlreadyDispatched(const LazyContextId& dispatch_context); content::BrowserContext* GetIncognitoContext(const Extension* extension); @@ -87,10 +70,7 @@ content::BrowserContext* const browser_context_; DispatchFunction dispatch_function_; - // TODO(lazyboy): Instead of keeping these two std::sets, compbine them using - // LazyContextId key when service worker event listeners are more common. - std::set<EventPageDispatchIdentifier> dispatched_ids_for_event_page_; - std::set<ServiceWorkerDispatchIdentifier> dispatched_ids_for_service_worker_; + std::set<LazyContextId> dispatched_ids_; DISALLOW_COPY_AND_ASSIGN(LazyEventDispatcher); };
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc index 5cfb251..c6322e7 100644 --- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc +++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc
@@ -207,8 +207,13 @@ // to load a MimeHandlerView. The test passes if MHV loads. This is to catch the // potential race between the cross-origin renderer initiated navigation and // the navigation to "about:blank" started from the browser. +#if defined(OS_LINUX) +#define MAYBE_NavigationRaceFromEmbedder DISABLED_NavigationRaceFromEmbedder +#else +#define MAYBE_NavigationRaceFromEmbedder NavigationRaceFromEmbedder +#endif IN_PROC_BROWSER_TEST_P(MimeHandlerViewCrossProcessTest, - NavigationRaceFromEmbedder) { + MAYBE_NavigationRaceFromEmbedder) { if (!is_cross_process_mode()) { // Note that this test would pass trivially with BrowserPlugin-based guests // because loading a plugin is quite independent from navigating a plugin.
diff --git a/ios/chrome/browser/context_menu/BUILD.gn b/ios/chrome/browser/context_menu/BUILD.gn index a49caaa90..63b60e5 100644 --- a/ios/chrome/browser/context_menu/BUILD.gn +++ b/ios/chrome/browser/context_menu/BUILD.gn
@@ -11,6 +11,7 @@ deps = [ "//base", "//base/test:test_support", + "//components/strings", "//ios/chrome/app/strings", "//ios/chrome/browser/ui", "//ios/chrome/test/app:test_support",
diff --git a/ios/chrome/browser/context_menu/context_menu_egtest.mm b/ios/chrome/browser/context_menu/context_menu_egtest.mm index f75a001a0..ff39f45 100644 --- a/ios/chrome/browser/context_menu/context_menu_egtest.mm +++ b/ios/chrome/browser/context_menu/context_menu_egtest.mm
@@ -7,6 +7,7 @@ #import <XCTest/XCTest.h> #import "base/test/ios/wait_util.h" +#include "components/strings/grit/components_strings.h" #include "ios/chrome/browser/ui/util/ui_util.h" #include "ios/chrome/grit/ios_strings.h" #import "ios/chrome/test/app/chrome_test_util.h" @@ -71,7 +72,7 @@ const char kInitialPageUrl[] = "/scenarioContextMenuOpenInNewTab"; // HTML content of a page with a link to the destination page. const char kInitialPageHtml[] = - "<html><body><a style='margin-left:50px' href='/destination' id='link'>" + "<html><body><a style='margin-left:150px' href='/destination' id='link'>" "link</a></body></html>"; // The DOM element ID of the link to the destination page. const char kInitialPageDestinationLinkId[] = "link"; @@ -360,4 +361,71 @@ }); } +// Tests cancelling the context menu. +- (void)testDismissContextMenu { + const GURL initialURL = self.testServer->GetURL(kInitialPageUrl); + [ChromeEarlGrey loadURL:initialURL]; + [ChromeEarlGrey waitForWebViewContainingText:kInitialPageDestinationLinkText]; + + // Display the context menu twice. + for (NSInteger i = 0; i < 2; i++) { + LongPressElement(kInitialPageDestinationLinkId); + + // Make sure the context menu appeared. + [[EarlGrey selectElementWithMatcher:OpenLinkInNewTabButton()] + assertWithMatcher:grey_notNil()]; + + if (IsIPadIdiom()) { + // Tap the tools menu to dismiss the popover. + [[EarlGrey selectElementWithMatcher:chrome_test_util::ToolsMenuButton()] + performAction:grey_tap()]; + } else { + TapOnContextMenuButton(chrome_test_util::CancelButton()); + } + + // Make sure the context menu disappeared. + [[EarlGrey selectElementWithMatcher:OpenLinkInNewTabButton()] + assertWithMatcher:grey_nil()]; + } + + // Display the context menu one last time. + LongPressElement(kInitialPageDestinationLinkId); + + // Make sure the context menu appeared. + [[EarlGrey selectElementWithMatcher:OpenLinkInNewTabButton()] + assertWithMatcher:grey_notNil()]; +} + +// Checks that all the options are displayed in the context menu. +- (void)testAppropriateContextMenu { + const GURL initialURL = self.testServer->GetURL(kInitialPageUrl); + [ChromeEarlGrey loadURL:initialURL]; + [ChromeEarlGrey waitForWebViewContainingText:kInitialPageDestinationLinkText]; + + LongPressElement(kInitialPageDestinationLinkId); + + // Check the different buttons. + [[EarlGrey + selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId( + IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB)] + assertWithMatcher:grey_sufficientlyVisible()]; + [[EarlGrey selectElementWithMatcher: + chrome_test_util::ButtonWithAccessibilityLabelId( + IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWINCOGNITOTAB)] + assertWithMatcher:grey_sufficientlyVisible()]; + [[EarlGrey + selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId( + IDS_IOS_CONTENT_CONTEXT_ADDTOREADINGLIST)] + assertWithMatcher:grey_sufficientlyVisible()]; + [[EarlGrey + selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId( + IDS_IOS_CONTENT_CONTEXT_COPY)] + assertWithMatcher:grey_sufficientlyVisible()]; + if (!IsIPadIdiom()) { + [[EarlGrey selectElementWithMatcher: + chrome_test_util::ButtonWithAccessibilityLabelId(IDS_CANCEL)] + assertWithMatcher:grey_sufficientlyVisible()]; + } +} + @end
diff --git a/ios/chrome/browser/snapshots/fake_snapshot_generator_delegate.mm b/ios/chrome/browser/snapshots/fake_snapshot_generator_delegate.mm index 4e6357ba5..3565213 100644 --- a/ios/chrome/browser/snapshots/fake_snapshot_generator_delegate.mm +++ b/ios/chrome/browser/snapshots/fake_snapshot_generator_delegate.mm
@@ -32,11 +32,6 @@ willUpdateSnapshotForWebState:(web::WebState*)webState { } -- (void)snapshotGenerator:(SnapshotGenerator*)snapshotGenerator - didUpdateSnapshotForWebState:(web::WebState*)webState - withImage:(UIImage*)snapshot { -} - - (UIView*)snapshotGenerator:(SnapshotGenerator*)snapshotGenerator baseViewForWebState:(web::WebState*)webState { return self.view;
diff --git a/ios/chrome/browser/snapshots/snapshot_generator.mm b/ios/chrome/browser/snapshots/snapshot_generator.mm index ab84b72..8bd42a2 100644 --- a/ios/chrome/browser/snapshots/snapshot_generator.mm +++ b/ios/chrome/browser/snapshots/snapshot_generator.mm
@@ -48,12 +48,16 @@ // Property providing access to the snapshot's cache. May be nil. @property(nonatomic, readonly) SnapshotCache* snapshotCache; +// The unique ID for the web state. +@property(nonatomic, copy) NSString* sessionID; + +// The associated web state. +@property(nonatomic, assign) web::WebState* webState; + @end @implementation SnapshotGenerator { std::unique_ptr<web::WebStateObserver> _webStateObserver; - NSString* _snapshotSessionId; - web::WebState* _webState; } - (instancetype)initWithWebState:(web::WebState*)webState @@ -62,7 +66,7 @@ DCHECK(webState); DCHECK(snapshotSessionId); _webState = webState; - _snapshotSessionId = snapshotSessionId; + _sessionID = snapshotSessionId; _webStateObserver = std::make_unique<web::WebStateObserverBridge>(self); _webState->AddObserver(_webStateObserver.get()); @@ -81,7 +85,7 @@ - (void)retrieveSnapshot:(void (^)(UIImage*))callback { DCHECK(callback); if (self.snapshotCache) { - [self.snapshotCache retrieveImageForSessionID:_snapshotSessionId + [self.snapshotCache retrieveImageForSessionID:self.sessionID callback:callback]; } else { callback(nil); @@ -103,7 +107,7 @@ SnapshotCache* snapshotCache = self.snapshotCache; if (snapshotCache) { - [snapshotCache retrieveGreyImageForSessionID:_snapshotSessionId + [snapshotCache retrieveGreyImageForSessionID:self.sessionID callback:wrappedCallback]; } else { wrappedCallback(nil); @@ -113,17 +117,18 @@ - (UIImage*)updateSnapshot { UIImage* snapshot = [self generateSnapshotWithOverlays:YES]; if (snapshot) { - [self.snapshotCache setImage:snapshot withSessionID:_snapshotSessionId]; + [self.snapshotCache setImage:snapshot withSessionID:self.sessionID]; } return snapshot; } - (void)updateWebViewSnapshotWithCompletion:(void (^)(UIImage*))completion { - DCHECK(_webState); + DCHECK(self.webState); UIView* snapshotView = [self.delegate snapshotGenerator:self - baseViewForWebState:_webState]; - CGRect snapshotFrame = [_webState->GetView() convertRect:[self snapshotFrame] - fromView:snapshotView]; + baseViewForWebState:self.webState]; + CGRect snapshotFrame = + [self.webState->GetView() convertRect:[self snapshotFrame] + fromView:snapshotView]; if (CGRectIsEmpty(snapshotFrame)) { if (completion) { base::PostTaskWithTraits(FROM_HERE, {web::WebThread::UI}, @@ -138,36 +143,19 @@ << ": snapshotFrame.size.width=" << size.width; DCHECK(std::isnormal(size.height) && (size.height > 0)) << ": snapshotFrame.size.height=" << size.height; - NSArray<SnapshotOverlay*>* overlays = [_delegate snapshotGenerator:self - snapshotOverlaysForWebState:_webState]; + NSArray<SnapshotOverlay*>* overlays = + [self.delegate snapshotGenerator:self + snapshotOverlaysForWebState:self.webState]; - [_delegate snapshotGenerator:self willUpdateSnapshotForWebState:_webState]; + [self.delegate snapshotGenerator:self + willUpdateSnapshotForWebState:self.webState]; __weak SnapshotGenerator* weakSelf = self; - _webState->TakeSnapshot( + self.webState->TakeSnapshot( snapshotFrame, base::BindOnce(^(const gfx::Image& image) { - SnapshotGenerator* strongSelf = weakSelf; - if (!strongSelf || !_webState) - return; - UIImage* snapshot = nil; - if (!image.IsEmpty()) { - snapshot = image.ToUIImage(); - if (overlays.count > 0) { - snapshot = [strongSelf snapshotWithOverlays:overlays - snapshot:snapshot - frame:snapshotFrame]; - } - } - if (snapshot) { - [strongSelf.snapshotCache setImage:snapshot - withSessionID:_snapshotSessionId]; - } else { - // Remove any stale snapshot since the snapshot failed. - [strongSelf.snapshotCache - removeImageWithSessionID:_snapshotSessionId]; - } - [_delegate snapshotGenerator:self - didUpdateSnapshotForWebState:_webState - withImage:snapshot]; + UIImage* snapshot = [weakSelf snapshotWithOverlays:overlays + image:image + frame:snapshotFrame]; + [weakSelf updateSnapshotCacheWithImage:snapshot]; if (completion) completion(snapshot); })); @@ -179,24 +167,22 @@ return nil; NSArray<SnapshotOverlay*>* overlays = - shouldAddOverlay ? [_delegate snapshotGenerator:self - snapshotOverlaysForWebState:_webState] + shouldAddOverlay ? [self.delegate snapshotGenerator:self + snapshotOverlaysForWebState:self.webState] : nil; - [_delegate snapshotGenerator:self willUpdateSnapshotForWebState:_webState]; - UIView* view = [_delegate snapshotGenerator:self - baseViewForWebState:_webState]; + [self.delegate snapshotGenerator:self + willUpdateSnapshotForWebState:self.webState]; + UIView* view = [self.delegate snapshotGenerator:self + baseViewForWebState:self.webState]; UIImage* snapshot = [self generateSnapshotForView:view withRect:frame overlays:overlays]; - [_delegate snapshotGenerator:self - didUpdateSnapshotForWebState:_webState - withImage:snapshot]; return snapshot; } - (void)removeSnapshot { - [self.snapshotCache removeImageWithSessionID:_snapshotSessionId]; + [self.snapshotCache removeImageWithSessionID:self.sessionID]; } #pragma mark - Private methods @@ -206,19 +192,19 @@ - (CGRect)snapshotFrame { // Do not generate a snapshot if web usage is disabled (as the WebState's // view is blank in that case). - if (!_webState->IsWebUsageEnabled()) + if (!self.webState->IsWebUsageEnabled()) return CGRectZero; // Do not generate a snapshot if the delegate says the WebState view is // not ready (this generally mean a placeholder is displayed). - if (_delegate && ![_delegate snapshotGenerator:self - canTakeSnapshotForWebState:_webState]) + if (self.delegate && ![self.delegate snapshotGenerator:self + canTakeSnapshotForWebState:self.webState]) return CGRectZero; - UIView* view = [_delegate snapshotGenerator:self - baseViewForWebState:_webState]; - UIEdgeInsets headerInsets = [_delegate snapshotGenerator:self - snapshotEdgeInsetsForWebState:_webState]; + UIView* view = [self.delegate snapshotGenerator:self + baseViewForWebState:self.webState]; + UIEdgeInsets headerInsets = [self.delegate snapshotGenerator:self + snapshotEdgeInsetsForWebState:self.webState]; return UIEdgeInsetsInsetRect(view.bounds, headerInsets); } @@ -286,11 +272,15 @@ return image; } -// Returns an image of the |snapshot| overlaid with |overlays| with the given +// Returns an image of the |image| overlaid with |overlays| with the given // |frame|. - (UIImage*)snapshotWithOverlays:(NSArray<SnapshotOverlay*>*)overlays - snapshot:(UIImage*)snapshot + image:(const gfx::Image&)image frame:(CGRect)frame { + if (image.IsEmpty()) + return nil; + if (overlays.count == 0) + return image.ToUIImage(); CGSize size = frame.size; DCHECK(std::isnormal(size.width) && (size.width > 0)) << ": size.width=" << size.width; @@ -302,7 +292,7 @@ CGContext* context = UIGraphicsGetCurrentContext(); DCHECK(context); CGContextSaveGState(context); - [snapshot drawAtPoint:CGPointZero]; + [image.ToUIImage() drawAtPoint:CGPointZero]; for (SnapshotOverlay* overlay in overlays) { // Render the overlay view at the desired offset. It is achieved // by shifting origin of context because view frame is ignored when @@ -327,11 +317,22 @@ return snapshotWithOverlays; } +// Updates the snapshot cache with |snapshot|. +- (void)updateSnapshotCacheWithImage:(UIImage*)snapshot { + if (snapshot) { + [self.snapshotCache setImage:snapshot withSessionID:self.sessionID]; + } else { + // Remove any stale snapshot since the snapshot failed. + [self.snapshotCache removeImageWithSessionID:self.sessionID]; + } +} + #pragma mark - Properties - (SnapshotCache*)snapshotCache { return SnapshotCacheFactory::GetForBrowserState( - ios::ChromeBrowserState::FromBrowserState(_webState->GetBrowserState())); + ios::ChromeBrowserState::FromBrowserState( + self.webState->GetBrowserState())); } #pragma mark - CRWWebStateObserver
diff --git a/ios/chrome/browser/snapshots/snapshot_generator_delegate.h b/ios/chrome/browser/snapshots/snapshot_generator_delegate.h index 8bbe19d..b5e61940 100644 --- a/ios/chrome/browser/snapshots/snapshot_generator_delegate.h +++ b/ios/chrome/browser/snapshots/snapshot_generator_delegate.h
@@ -41,13 +41,6 @@ - (void)snapshotGenerator:(SnapshotGenerator*)snapshotGenerator willUpdateSnapshotForWebState:(web::WebState*)webState; -// Invoked after capturing a snapshot for |webState|. The delegate can insert -// subviews that were removed during -willUpdateSnapshotForWebState: or take -// other actions necessary after a snapshot has been captured. -- (void)snapshotGenerator:(SnapshotGenerator*)snapshotGenerator - didUpdateSnapshotForWebState:(web::WebState*)webState - withImage:(UIImage*)snapshot; - // Returns the base view to be snapshotted. - (UIView*)snapshotGenerator:(SnapshotGenerator*)snapshotGenerator baseViewForWebState:(web::WebState*)webState;
diff --git a/ios/chrome/browser/tabs/tab_model.h b/ios/chrome/browser/tabs/tab_model.h index ff034aa1..4afa40a 100644 --- a/ios/chrome/browser/tabs/tab_model.h +++ b/ios/chrome/browser/tabs/tab_model.h
@@ -150,9 +150,6 @@ // Notifies observers that the given |tab| was changed. - (void)notifyTabChanged:(Tab*)tab; -// Notifies observers that the given tab is loading a new URL. -- (void)notifyTabLoading:(Tab*)tab; - // Notifies observers that the given tab finished loading. - (void)notifyTabFinishedLoading:(Tab*)tab; @@ -160,10 +157,6 @@ // |background| is YES, NO otherwise. - (void)notifyNewTabWillOpen:(Tab*)tab inBackground:(BOOL)background; -// Notifies observers that the snapshot for the given |tab| changed was changed -// to |image|. -- (void)notifyTabSnapshotChanged:(Tab*)tab withImage:(UIImage*)image; - // Notifies observers that |tab| was deselected. - (void)notifyTabWasDeselected:(Tab*)tab;
diff --git a/ios/chrome/browser/tabs/tab_model.mm b/ios/chrome/browser/tabs/tab_model.mm index d11d934..ef1dc830 100644 --- a/ios/chrome/browser/tabs/tab_model.mm +++ b/ios/chrome/browser/tabs/tab_model.mm
@@ -576,11 +576,6 @@ [_observers tabModel:self didChangeTab:tab]; } -- (void)notifyTabLoading:(Tab*)tab { - [_observers tabModel:self willStartLoadingTab:tab]; - [self notifyTabChanged:tab]; -} - - (void)notifyTabFinishedLoading:(Tab*)tab { [self notifyTabChanged:tab]; [_observers tabModel:self didFinishLoadingTab:tab]; @@ -612,11 +607,6 @@ _webStateListMetricsObserver->RecordSessionMetrics(); } -- (void)notifyTabSnapshotChanged:(Tab*)tab withImage:(UIImage*)image { - DCHECK([NSThread isMainThread]); - [_observers tabModel:self didChangeTabSnapshot:tab withImage:image]; -} - - (void)setPrimary:(BOOL)primary { if (_tabUsageRecorder) { _tabUsageRecorder->RecordPrimaryTabModelChange(primary, @@ -861,7 +851,7 @@ didCommitNavigationWithDetails: (const web::LoadCommittedDetails&)load_details { Tab* tab = LegacyTabHelper::GetTabForWebState(webState); - [self notifyTabLoading:tab]; + [self notifyTabChanged:tab]; web::NavigationItem* previousItem = nullptr; if (load_details.previous_item_index >= 0) {
diff --git a/ios/chrome/browser/tabs/tab_model_observer.h b/ios/chrome/browser/tabs/tab_model_observer.h index 4e82e82..daf570f 100644 --- a/ios/chrome/browser/tabs/tab_model_observer.h +++ b/ios/chrome/browser/tabs/tab_model_observer.h
@@ -54,9 +54,6 @@ // The number of Tabs in this TabModel changed. - (void)tabModelDidChangeTabCount:(TabModel*)model; -// |tab| is about to start loading a new URL. -- (void)tabModel:(TabModel*)model willStartLoadingTab:(Tab*)tab; - // Some properties about the given tab changed, such as the URL or title. - (void)tabModel:(TabModel*)model didChangeTab:(Tab*)tab; @@ -72,11 +69,6 @@ // |tab| stopped being the active tab. - (void)tabModel:(TabModel*)model didDeselectTab:(Tab*)tab; -// The |tab|'s snapshot was changed to |image|. -- (void)tabModel:(TabModel*)model - didChangeTabSnapshot:(Tab*)tab - withImage:image; - @end #endif // IOS_CHROME_BROWSER_TABS_TAB_MODEL_OBSERVER_H_
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm index d83b39f..0e3a8c54 100644 --- a/ios/chrome/browser/ui/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -170,6 +170,7 @@ #import "ios/chrome/browser/web/sad_tab_tab_helper.h" #import "ios/chrome/browser/web/web_navigation_util.h" #include "ios/chrome/browser/web/web_state_printer.h" +#include "ios/chrome/browser/web_state_list/all_web_state_observation_forwarder.h" #import "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/chrome/browser/web_state_list/web_usage_enabler/web_state_list_web_usage_enabler.h" #import "ios/chrome/browser/web_state_list/web_usage_enabler/web_state_list_web_usage_enabler_factory.h" @@ -198,6 +199,7 @@ #import "ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h" #import "ios/web/public/web_state/web_state.h" #import "ios/web/public/web_state/web_state_delegate_bridge.h" +#include "ios/web/public/web_state/web_state_observer_bridge.h" #include "ios/web/public/web_thread.h" #import "ios/web/web_state/ui/crw_web_controller.h" #include "services/network/public/cpp/shared_url_loader_factory.h" @@ -360,32 +362,33 @@ #pragma mark - BVC -@interface BrowserViewController ()<ActivityServicePresentation, - BubblePresenterDelegate, - CaptivePortalDetectorTabHelperDelegate, - CRWNativeContentProvider, - CRWWebStateDelegate, - DialogPresenterDelegate, - FullscreenUIElement, - InfobarPositioner, - KeyCommandsPlumbing, - MainContentUI, - ManageAccountsDelegate, - MFMailComposeViewControllerDelegate, - NetExportTabHelperDelegate, - NewTabPageTabHelperDelegate, - OverscrollActionsControllerDelegate, - PasswordControllerDelegate, - PreloadControllerDelegate, - SadTabCoordinatorDelegate, - SideSwipeControllerDelegate, - SnapshotGeneratorDelegate, - TabDialogDelegate, - TabModelObserver, - TabStripPresentation, - ToolbarHeightProviderForFullscreen, - UIGestureRecognizerDelegate, - WebStatePrinter> { +@interface BrowserViewController () <ActivityServicePresentation, + BubblePresenterDelegate, + CaptivePortalDetectorTabHelperDelegate, + CRWNativeContentProvider, + CRWWebStateDelegate, + CRWWebStateObserver, + DialogPresenterDelegate, + FullscreenUIElement, + InfobarPositioner, + KeyCommandsPlumbing, + MainContentUI, + ManageAccountsDelegate, + MFMailComposeViewControllerDelegate, + NetExportTabHelperDelegate, + NewTabPageTabHelperDelegate, + OverscrollActionsControllerDelegate, + PasswordControllerDelegate, + PreloadControllerDelegate, + SadTabCoordinatorDelegate, + SideSwipeControllerDelegate, + SnapshotGeneratorDelegate, + TabDialogDelegate, + TabModelObserver, + TabStripPresentation, + ToolbarHeightProviderForFullscreen, + UIGestureRecognizerDelegate, + WebStatePrinter> { // The dependency factory passed on initialization. Used to vend objects used // by the BVC. BrowserViewControllerDependencyFactory* _dependencyFactory; @@ -502,6 +505,14 @@ // is used to determine whether the pre-rendering animation should be played // or not. BOOL _insertedTabWasPrerenderedTab; + + // Forwards observer methods for all WebStates in the WebStateList to this + // BrowserViewController object. + std::unique_ptr<AllWebStateObservationForwarder> + _allWebStateObservationForwarder; + + // Bridges C++ WebStateObserver methods to this BrowserViewController. + std::unique_ptr<web::WebStateObserverBridge> _webStateObserverBridge; } // Activates/deactivates the object. This will enable/disable the ability for @@ -1416,6 +1427,7 @@ // before self.tabModel is released. _sideSwipeController = nil; [self.tabModel removeObserver:self]; + _allWebStateObservationForwarder = nullptr; if (_voiceSearchController) _voiceSearchController->SetDispatcher(nil); [_paymentRequestManager setActiveWebState:nullptr]; @@ -1863,6 +1875,10 @@ ->SetWebStateList(self.tabModel.webStateList); [self.tabModel addObserver:self]; + _webStateObserverBridge = std::make_unique<web::WebStateObserverBridge>(self); + _allWebStateObservationForwarder = + std::make_unique<AllWebStateObservationForwarder>( + self.tabModel.webStateList, _webStateObserverBridge.get()); if (!_isOffTheRecord) { [DefaultIOSWebViewFactory @@ -2963,15 +2979,6 @@ [tab willUpdateSnapshot]; } -- (void)snapshotGenerator:(SnapshotGenerator*)snapshotGenerator - didUpdateSnapshotForWebState:(web::WebState*)webState - withImage:(UIImage*)snapshot { - DCHECK(webState); - Tab* tab = LegacyTabHelper::GetTabForWebState(webState); - DCHECK([self.tabModel indexOfTab:tab] != NSNotFound); - [self.tabModel notifyTabSnapshotChanged:tab withImage:snapshot]; -} - - (UIView*)snapshotGenerator:(SnapshotGenerator*)snapshotGenerator baseViewForWebState:(web::WebState*)webState { NewTabPageTabHelper* NTPHelper = NewTabPageTabHelper::FromWebState(webState); @@ -3457,6 +3464,19 @@ web::PolicyForNavigation(url, referrer)); } +#pragma mark - CRWWebStateObserver methods. + +// TODO(crbug.com/918934): didCommitNavigationWithDetails is deprecated, and +// this call to closeFindInPage incorrectly triggers for all navigations, not +// just navigations in the active WebState. +- (void)webState:(web::WebState*)webState + didCommitNavigationWithDetails: + (const web::LoadCommittedDetails&)load_details { + // Stop any Find in Page searches and close the find bar when navigating to a + // new page. + [self closeFindInPage]; +} + #pragma mark - OverscrollActionsControllerDelegate methods. - (void)overscrollActionsController:(OverscrollActionsController*)controller @@ -4550,12 +4570,6 @@ [self tabSelected:newTab notifyToolbar:YES]; } -- (void)tabModel:(TabModel*)model willStartLoadingTab:(Tab*)tab { - // Stop any Find in Page searches and close the find bar when navigating to a - // new page. - [self closeFindInPage]; -} - - (void)tabModel:(TabModel*)model didChangeTab:(Tab*)tab { DCHECK(tab && ([self.tabModel indexOfTab:tab] != NSNotFound)); if (tab == self.tabModel.currentTab) {
diff --git a/ios/chrome/browser/ui/qr_scanner/BUILD.gn b/ios/chrome/browser/ui/qr_scanner/BUILD.gn index 90f772a..6c3ed1b9 100644 --- a/ios/chrome/browser/ui/qr_scanner/BUILD.gn +++ b/ios/chrome/browser/ui/qr_scanner/BUILD.gn
@@ -27,6 +27,7 @@ "//ios/chrome/browser/ui/icons", "//ios/chrome/browser/ui/util", "//ios/chrome/common:ios_app_bundle_id_prefix_buildflags", + "//ios/chrome/common/ui_util", "//ios/third_party/material_components_ios", "//ui/base", ]
diff --git a/ios/chrome/browser/ui/qr_scanner/qr_scanner_view.mm b/ios/chrome/browser/ui/qr_scanner/qr_scanner_view.mm index 41cf978..4c35148 100644 --- a/ios/chrome/browser/ui/qr_scanner/qr_scanner_view.mm +++ b/ios/chrome/browser/ui/qr_scanner/qr_scanner_view.mm
@@ -9,8 +9,8 @@ #include "base/numerics/math_constants.h" #include "ios/chrome/browser/ui/icons/chrome_icon.h" #include "ios/chrome/browser/ui/util/ui_util.h" +#import "ios/chrome/common/ui_util/constraints_ui_util.h" #include "ios/chrome/grit/ios_strings.h" -#include "ios/third_party/material_components_ios/src/components/Buttons/src/MaterialButtons.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_mac.h" @@ -20,9 +20,6 @@ namespace { -// Padding for buttons in the QR scanner UI. -const CGFloat kButtonPadding = 16.0; - // Width and height of the QR scanner viewport. const CGFloat kViewportSize_iPhone = 250.0; const CGFloat kViewportSize_iPad = 300.0; @@ -230,7 +227,7 @@ @interface QRScannerView () { // A button to toggle the torch. - MDCFlatButton* _torchButton; + UIBarButtonItem* _torchButton; // A view containing the preview layer for camera input. VideoPreviewView* _previewView; // A transparent overlay on top of the preview layer. @@ -245,36 +242,10 @@ NSLayoutConstraint* _overlayHeightConstraint; } -// Creates an image with template rendering mode for use in icons. -- (UIImage*)templateImageWithName:(NSString*)name; -// Creates an icon for torch turned on. -- (UIImage*)torchOnIcon; -// Creates an icon for torch turned off. -- (UIImage*)torchOffIcon; - -// Sets common configuration properties of a button in the QR scanner UI and -// adds it to self.view. -- (void)configureButton:(MDCFlatButton*)button - withIcon:(UIImage*)icon - action:(SEL)action; -// Adds a close button. -- (void)addCloseButton; -// Adds a torch button and stores it in |_torchButton|. -- (void)addTorchButton; -// Adds a caption to the viewport. -- (void)addViewportCaptionLabel; -// Adds a preview view to |self| and configures its layout constraints. -- (void)setupPreviewView; -// Adds a transparent overlay with a viewport border to |self| and configures -// its layout constraints. -- (void)setupPreviewOverlayView; - @end @implementation QRScannerView -@synthesize delegate = _delegate; - #pragma mark lifecycle - (instancetype)initWithFrame:(CGRect)frame @@ -287,22 +258,10 @@ _delegate = delegate; [self setupPreviewView]; [self setupPreviewOverlayView]; - [self addCloseButton]; - [self addTorchButton]; - [self addViewportCaptionLabel]; + [self addSubviews]; return self; } -- (instancetype)initWithFrame:(CGRect)frame { - NOTREACHED(); - return nil; -} - -- (instancetype)initWithCoder:(NSCoder*)coder { - NOTREACHED(); - return nil; -} - #pragma mark UIView // TODO(crbug.com/633577): Replace the preview overlay with a UIView which is @@ -343,7 +302,7 @@ accessibilityValue = l10n_util::GetNSString( IDS_IOS_QR_SCANNER_TORCH_OFF_ACCESSIBILITY_VALUE); } - [_torchButton setImage:icon forState:UIControlStateNormal]; + [_torchButton setImage:icon]; [_torchButton setAccessibilityValue:accessibilityValue]; } @@ -395,6 +354,7 @@ #pragma mark private methods +// Creates an image with template rendering mode for use in icons. - (UIImage*)templateImageWithName:(NSString*)name { UIImage* image = [[UIImage imageNamed:name] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; @@ -402,80 +362,67 @@ return image; } +// Creates an icon for torch turned on. - (UIImage*)torchOnIcon { UIImage* icon = [self templateImageWithName:@"qr_scanner_torch_on"]; return icon; } +// Creates an icon for torch turned off. - (UIImage*)torchOffIcon { UIImage* icon = [self templateImageWithName:@"qr_scanner_torch_off"]; return icon; } -- (void)configureButton:(MDCFlatButton*)button - withIcon:(UIImage*)icon - action:(SEL)action { - [button setTintColor:[UIColor whiteColor]]; - [button setImage:icon forState:UIControlStateNormal]; - [button setInkStyle:MDCInkStyleUnbounded]; - [button addTarget:_delegate - action:action - forControlEvents:UIControlEventTouchUpInside]; - [self addSubview:button]; -} +// Adds the subviews. +- (void)addSubviews { + UIBarButtonItem* close = + [[UIBarButtonItem alloc] initWithImage:[ChromeIcon closeIcon] + style:UIBarButtonItemStylePlain + target:_delegate + action:@selector(dismissQRScannerView:)]; + close.accessibilityLabel = [[ChromeIcon closeIcon] accessibilityLabel]; + UIBarButtonItem* spacer = [[UIBarButtonItem alloc] + initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace + target:nil + action:nil]; + _torchButton = + [[UIBarButtonItem alloc] initWithImage:[self torchOffIcon] + style:UIBarButtonItemStylePlain + target:_delegate + action:@selector(toggleTorch:)]; + _torchButton.enabled = NO; + _torchButton.accessibilityIdentifier = @"qr_scanner_torch_button"; + _torchButton.accessibilityLabel = l10n_util::GetNSString( + IDS_IOS_QR_SCANNER_TORCH_BUTTON_ACCESSIBILITY_LABEL); + _torchButton.accessibilityValue = + l10n_util::GetNSString(IDS_IOS_QR_SCANNER_TORCH_OFF_ACCESSIBILITY_VALUE); -- (void)addCloseButton { - MDCFlatButton* closeButton = [[MDCFlatButton alloc] initWithFrame:CGRectZero]; - UIImage* closeIcon = [ChromeIcon closeIcon]; - UIImage* closeButtonIcon = - [closeIcon imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; - [closeButton setAccessibilityLabel:[closeIcon accessibilityLabel]]; - [closeButton setAccessibilityIdentifier:[closeIcon accessibilityIdentifier]]; - [self configureButton:closeButton - withIcon:closeButtonIcon - action:@selector(dismissQRScannerView:)]; + UIToolbar* toolbar = [[UIToolbar alloc] init]; + toolbar.items = @[ close, spacer, _torchButton ]; + toolbar.tintColor = UIColor.whiteColor; + [toolbar setBackgroundImage:[[UIImage alloc] init] + forToolbarPosition:UIToolbarPositionAny + barMetrics:UIBarMetricsDefault]; + [toolbar setShadowImage:[[UIImage alloc] init] + forToolbarPosition:UIBarPositionAny]; - // Constraints for closeButton. - [closeButton setTranslatesAutoresizingMaskIntoConstraints:NO]; - [NSLayoutConstraint activateConstraints:@[ - [[closeButton leadingAnchor] constraintEqualToAnchor:[self leadingAnchor] - constant:kButtonPadding], - [[closeButton bottomAnchor] constraintEqualToAnchor:[self bottomAnchor] - constant:-kButtonPadding] - ]]; -} + [toolbar setBackgroundColor:[UIColor clearColor]]; + toolbar.translatesAutoresizingMaskIntoConstraints = NO; + [self addSubview:toolbar]; -- (void)addTorchButton { - DCHECK(!_torchButton); - _torchButton = [[MDCFlatButton alloc] initWithFrame:CGRectZero]; - [_torchButton setEnabled:NO]; - [self configureButton:_torchButton - withIcon:[self torchOffIcon] - action:@selector(toggleTorch:)]; - [_torchButton setAccessibilityIdentifier:@"qr_scanner_torch_button"]; - [_torchButton setAccessibilityLabel: - l10n_util::GetNSString( - IDS_IOS_QR_SCANNER_TORCH_BUTTON_ACCESSIBILITY_LABEL)]; - [_torchButton setAccessibilityValue: - l10n_util::GetNSString( - IDS_IOS_QR_SCANNER_TORCH_OFF_ACCESSIBILITY_VALUE)]; + AddSameConstraintsToSides(self, toolbar, + LayoutSides::kLeading | LayoutSides::kTrailing); + [toolbar.bottomAnchor + constraintEqualToAnchor:self.safeAreaLayoutGuide.bottomAnchor] + .active = YES; - // Constraints for _torchButton. - [_torchButton setTranslatesAutoresizingMaskIntoConstraints:NO]; - [NSLayoutConstraint activateConstraints:@[ - [[_torchButton trailingAnchor] constraintEqualToAnchor:[self trailingAnchor] - constant:-kButtonPadding], - [[_torchButton bottomAnchor] constraintEqualToAnchor:[self bottomAnchor] - constant:-kButtonPadding] - ]]; -} - -- (void)addViewportCaptionLabel { UILabel* viewportCaption = [[UILabel alloc] init]; NSString* label = l10n_util::GetNSString(IDS_IOS_QR_SCANNER_VIEWPORT_CAPTION); [viewportCaption setText:label]; [viewportCaption setFont:[UIFont preferredFontForTextStyle:UIFontTextStyleBody]]; + [viewportCaption setAdjustsFontForContentSizeCategory:YES]; [viewportCaption setNumberOfLines:0]; [viewportCaption setTextAlignment:NSTextAlignmentCenter]; [viewportCaption setAccessibilityLabel:label]; @@ -487,30 +434,47 @@ [viewportCaption.layer setShadowOpacity:kViewportCaptionShadowOpacity]; [viewportCaption.layer setMasksToBounds:NO]; [viewportCaption.layer setShouldRasterize:YES]; - [self addSubview:viewportCaption]; + + UIScrollView* scrollView = [[UIScrollView alloc] init]; + scrollView.showsVerticalScrollIndicator = NO; + [self addSubview:scrollView]; + [scrollView addSubview:viewportCaption]; // Constraints for viewportCaption. - [viewportCaption setTranslatesAutoresizingMaskIntoConstraints:NO]; + scrollView.translatesAutoresizingMaskIntoConstraints = NO; + viewportCaption.translatesAutoresizingMaskIntoConstraints = NO; + [NSLayoutConstraint activateConstraints:@[ - [[viewportCaption topAnchor] - constraintEqualToAnchor:[self centerYAnchor] + [scrollView.topAnchor + constraintEqualToAnchor:self.centerYAnchor constant:GetViewportSize() / 2 + kViewportCaptionVerticalPadding], + [scrollView.bottomAnchor constraintEqualToAnchor:toolbar.topAnchor], + [scrollView.leadingAnchor + constraintEqualToAnchor:self.leadingAnchor + constant:kViewportCaptionHorizontalPadding], [viewportCaption.leadingAnchor constraintEqualToAnchor:self.leadingAnchor constant:kViewportCaptionHorizontalPadding], + [scrollView.trailingAnchor + constraintEqualToAnchor:self.trailingAnchor + constant:-kViewportCaptionHorizontalPadding], [viewportCaption.trailingAnchor constraintEqualToAnchor:self.trailingAnchor constant:-kViewportCaptionHorizontalPadding], ]]; + AddSameConstraints(scrollView, viewportCaption); } +// Adds a preview view to |self| and configures its layout constraints. - (void)setupPreviewView { DCHECK(!_previewView); _previewView = [[VideoPreviewView alloc] initWithFrame:self.frame]; [self insertSubview:_previewView atIndex:0]; } +// Adds a transparent overlay with a viewport border to |self| and configures +// its layout constraints. - (void)setupPreviewOverlayView { DCHECK(!_previewOverlay); _previewOverlay = [[PreviewOverlayView alloc] initWithFrame:CGRectZero];
diff --git a/ios/chrome/browser/ui/settings/cells/BUILD.gn b/ios/chrome/browser/ui/settings/cells/BUILD.gn index 0b34629..1938fe4a 100644 --- a/ios/chrome/browser/ui/settings/cells/BUILD.gn +++ b/ios/chrome/browser/ui/settings/cells/BUILD.gn
@@ -26,6 +26,8 @@ "settings_cells_constants.mm", "settings_detail_item.h", "settings_detail_item.mm", + "settings_image_detail_text_cell.h", + "settings_image_detail_text_cell.mm", "settings_image_detail_text_item.h", "settings_image_detail_text_item.mm", "settings_multiline_detail_item.h",
diff --git a/ios/chrome/browser/ui/settings/cells/settings_image_detail_text_cell.h b/ios/chrome/browser/ui/settings/cells/settings_image_detail_text_cell.h new file mode 100644 index 0000000..275ac3a --- /dev/null +++ b/ios/chrome/browser/ui/settings/cells/settings_image_detail_text_cell.h
@@ -0,0 +1,32 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_SETTINGS_IMAGE_DETAIL_TEXT_CELL_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_SETTINGS_IMAGE_DETAIL_TEXT_CELL_H_ + +#import <Foundation/Foundation.h> + +#import "ios/chrome/browser/ui/table_view/cells/table_view_item.h" + +// Cell representation for SettingsImageDetailTextItem. +// +--------------------------------------------------+ +// | +-------+ | +// | | image | Multiline title | +// | | | Optional multiline detail text | +// | +-------+ | +// +--------------------------------------------------+ +@interface SettingsImageDetailTextCell : UITableViewCell + +// Cell image. +@property(nonatomic, strong) UIImage* image; + +// Cell title. +@property(nonatomic, readonly, strong) UILabel* textLabel; + +// Cell subtitle. +@property(nonatomic, readonly, strong) UILabel* detailTextLabel; + +@end + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_SETTINGS_IMAGE_DETAIL_TEXT_CELL_H_
diff --git a/ios/chrome/browser/ui/settings/cells/settings_image_detail_text_cell.mm b/ios/chrome/browser/ui/settings/cells/settings_image_detail_text_cell.mm new file mode 100644 index 0000000..63effad --- /dev/null +++ b/ios/chrome/browser/ui/settings/cells/settings_image_detail_text_cell.mm
@@ -0,0 +1,134 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/settings/cells/settings_image_detail_text_cell.h" + +#include "base/logging.h" +#include "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h" +#import "ios/chrome/browser/ui/util/uikit_ui_util.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@interface SettingsImageDetailTextCell () + +// Width constraint for the image view. +@property(nonatomic, weak, readonly) NSLayoutConstraint* imageWidthConstraint; +// Height constraint for the image view. +@property(nonatomic, weak, readonly) NSLayoutConstraint* imageHeightConstraint; +// Image view for the cell. +@property(nonatomic, strong) UIImageView* imageView; + +@end + +@implementation SettingsImageDetailTextCell + +@synthesize textLabel = _textLabel; +@synthesize detailTextLabel = _detailTextLabel; +@synthesize imageView = _imageView; + +- (instancetype)initWithStyle:(UITableViewCellStyle)style + reuseIdentifier:(NSString*)reuseIdentifier { + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + self.isAccessibilityElement = YES; + [self addSubviews]; + [self setViewConstraints]; + } + return self; +} + +// Creates and adds subviews. +- (void)addSubviews { + UIView* contentView = self.contentView; + + _imageView = [[UIImageView alloc] init]; + _imageView.translatesAutoresizingMaskIntoConstraints = NO; + [contentView addSubview:_imageView]; + + _textLabel = [[UILabel alloc] init]; + _textLabel.numberOfLines = 0; + _textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; + _textLabel.adjustsFontForContentSizeCategory = YES; + _textLabel.textColor = UIColor.blackColor; + + _detailTextLabel = [[UILabel alloc] init]; + _detailTextLabel.numberOfLines = 0; + _detailTextLabel.font = + [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]; + _detailTextLabel.adjustsFontForContentSizeCategory = YES; + _detailTextLabel.textColor = + UIColorFromRGB(kTableViewSecondaryLabelLightGrayTextColor); +} + +// Sets constraints on subviews. +- (void)setViewConstraints { + UIView* contentView = self.contentView; + + UIStackView* textStackView = [[UIStackView alloc] + initWithArrangedSubviews:@[ _textLabel, _detailTextLabel ]]; + textStackView.axis = UILayoutConstraintAxisVertical; + textStackView.translatesAutoresizingMaskIntoConstraints = NO; + [contentView addSubview:textStackView]; + + _imageWidthConstraint = [_imageView.widthAnchor constraintEqualToConstant:0]; + _imageHeightConstraint = + [_imageView.heightAnchor constraintEqualToConstant:0]; + + [NSLayoutConstraint activateConstraints:@[ + // Horizontal contraints for |_imageView| and |textStackView|. + _imageWidthConstraint, + [_imageView.leadingAnchor + constraintEqualToAnchor:contentView.leadingAnchor + constant:kTableViewHorizontalSpacing], + [textStackView.leadingAnchor + constraintEqualToAnchor:_imageView.trailingAnchor + constant:kTableViewHorizontalSpacing], + [contentView.trailingAnchor + constraintEqualToAnchor:textStackView.trailingAnchor + constant:kTableViewHorizontalSpacing], + // Vertical contraints for |_imageView| and |textStackView|. + _imageHeightConstraint, + [_imageView.centerYAnchor + constraintEqualToAnchor:contentView.centerYAnchor], + [_imageView.topAnchor + constraintGreaterThanOrEqualToAnchor:contentView.topAnchor + constant:kTableViewLargeVerticalSpacing], + [contentView.bottomAnchor + constraintGreaterThanOrEqualToAnchor:_imageView.bottomAnchor + constant:kTableViewLargeVerticalSpacing], + [textStackView.centerYAnchor + constraintEqualToAnchor:contentView.centerYAnchor], + [textStackView.topAnchor + constraintGreaterThanOrEqualToAnchor:contentView.topAnchor + constant:kTableViewLargeVerticalSpacing], + [contentView.bottomAnchor + constraintGreaterThanOrEqualToAnchor:textStackView.bottomAnchor + constant:kTableViewLargeVerticalSpacing], + ]]; +} + +- (void)setImage:(UIImage*)image { + DCHECK(image); + self.imageView.image = image; + self.imageWidthConstraint.constant = image.size.width; + self.imageHeightConstraint.constant = image.size.height; +} + +- (UIImage*)image { + return self.imageView.image; +} + +#pragma mark - UIAccessibility + +- (NSString*)accessibilityLabel { + if (self.detailTextLabel.text) { + return [NSString stringWithFormat:@"%@, %@", self.textLabel.text, + self.detailTextLabel.text]; + } + return self.textLabel.text; +} + +@end
diff --git a/ios/chrome/browser/ui/settings/cells/settings_image_detail_text_item.h b/ios/chrome/browser/ui/settings/cells/settings_image_detail_text_item.h index 79f1783..e77bc0ae 100644 --- a/ios/chrome/browser/ui/settings/cells/settings_image_detail_text_item.h +++ b/ios/chrome/browser/ui/settings/cells/settings_image_detail_text_item.h
@@ -24,24 +24,4 @@ @end -// Cell representation for SettingsImageDetailTextItem. -// +--------------------------------------------------+ -// | +-------+ | -// | | image | Multiline title | -// | | | Optional multiline detail text | -// | +-------+ | -// +--------------------------------------------------+ -@interface SettingsImageDetailTextCell : UITableViewCell - -// Cell image. -@property(nonatomic, readonly, strong) UIImageView* imageView; - -// Cell title. -@property(nonatomic, readonly, strong) UILabel* textLabel; - -// Cell subtitle. -@property(nonatomic, readonly, strong) UILabel* detailTextLabel; - -@end - #endif // IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_SETTINGS_IMAGE_DETAIL_TEXT_ITEM_H_
diff --git a/ios/chrome/browser/ui/settings/cells/settings_image_detail_text_item.mm b/ios/chrome/browser/ui/settings/cells/settings_image_detail_text_item.mm index bf073c1..93cec1b 100644 --- a/ios/chrome/browser/ui/settings/cells/settings_image_detail_text_item.mm +++ b/ios/chrome/browser/ui/settings/cells/settings_image_detail_text_item.mm
@@ -5,6 +5,7 @@ #import "ios/chrome/browser/ui/settings/cells/settings_image_detail_text_item.h" #include "base/logging.h" +#import "ios/chrome/browser/ui/settings/cells/settings_image_detail_text_cell.h" #include "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" @@ -12,15 +13,6 @@ #error "This file requires ARC support." #endif -@interface SettingsImageDetailTextCell () - -@property(nonatomic, weak, readonly) NSLayoutConstraint* imageWidthConstraint; -@property(nonatomic, weak, readonly) NSLayoutConstraint* imageHeightConstraint; - -@end - -#pragma mark - SettingsImageDetailTextItem - @implementation SettingsImageDetailTextItem - (instancetype)initWithType:(NSInteger)type { @@ -37,110 +29,7 @@ cell.textLabel.text = self.text; cell.detailTextLabel.text = self.detailText; DCHECK(self.image); - cell.imageView.image = self.image; - cell.imageWidthConstraint.constant = self.image.size.width; - cell.imageHeightConstraint.constant = self.image.size.height; -} - -@end - -#pragma mark - SettingsImageDetailTextCell - -@implementation SettingsImageDetailTextCell - -@synthesize imageView = _imageView; -@synthesize textLabel = _textLabel; -@synthesize detailTextLabel = _detailTextLabel; - -- (instancetype)initWithStyle:(UITableViewCellStyle)style - reuseIdentifier:(NSString*)reuseIdentifier { - self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; - if (self) { - self.isAccessibilityElement = YES; - [self addSubviews]; - [self setViewConstraints]; - } - return self; -} - -// Creates and adds subviews. -- (void)addSubviews { - UIView* contentView = self.contentView; - - _imageView = [[UIImageView alloc] init]; - _imageView.translatesAutoresizingMaskIntoConstraints = NO; - [contentView addSubview:_imageView]; - - _textLabel = [[UILabel alloc] init]; - _textLabel.numberOfLines = 0; - _textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; - _textLabel.adjustsFontForContentSizeCategory = YES; - _textLabel.textColor = UIColor.blackColor; - - _detailTextLabel = [[UILabel alloc] init]; - _detailTextLabel.numberOfLines = 0; - _detailTextLabel.font = - [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]; - _detailTextLabel.adjustsFontForContentSizeCategory = YES; - _detailTextLabel.textColor = - UIColorFromRGB(kTableViewSecondaryLabelLightGrayTextColor); -} - -// Sets constraints on subviews. -- (void)setViewConstraints { - UIView* contentView = self.contentView; - - UIStackView* textStackView = [[UIStackView alloc] - initWithArrangedSubviews:@[ _textLabel, _detailTextLabel ]]; - textStackView.axis = UILayoutConstraintAxisVertical; - textStackView.translatesAutoresizingMaskIntoConstraints = NO; - [contentView addSubview:textStackView]; - - _imageWidthConstraint = [_imageView.widthAnchor constraintEqualToConstant:0]; - _imageHeightConstraint = - [_imageView.heightAnchor constraintEqualToConstant:0]; - - [NSLayoutConstraint activateConstraints:@[ - // Horizontal contraints for |_imageView| and |textStackView|. - _imageWidthConstraint, - [_imageView.leadingAnchor - constraintEqualToAnchor:contentView.leadingAnchor - constant:kTableViewHorizontalSpacing], - [textStackView.leadingAnchor - constraintEqualToAnchor:_imageView.trailingAnchor - constant:kTableViewHorizontalSpacing], - [contentView.trailingAnchor - constraintEqualToAnchor:textStackView.trailingAnchor - constant:kTableViewHorizontalSpacing], - // Vertical contraints for |_imageView| and |textStackView|. - _imageHeightConstraint, - [_imageView.centerYAnchor - constraintEqualToAnchor:contentView.centerYAnchor], - [_imageView.topAnchor - constraintGreaterThanOrEqualToAnchor:contentView.topAnchor - constant:kTableViewLargeVerticalSpacing], - [contentView.bottomAnchor - constraintGreaterThanOrEqualToAnchor:_imageView.bottomAnchor - constant:kTableViewLargeVerticalSpacing], - [textStackView.centerYAnchor - constraintEqualToAnchor:contentView.centerYAnchor], - [textStackView.topAnchor - constraintGreaterThanOrEqualToAnchor:contentView.topAnchor - constant:kTableViewLargeVerticalSpacing], - [contentView.bottomAnchor - constraintGreaterThanOrEqualToAnchor:textStackView.bottomAnchor - constant:kTableViewLargeVerticalSpacing], - ]]; -} - -#pragma mark - UIAccessibility - -- (NSString*)accessibilityLabel { - if (self.detailTextLabel.text) { - return [NSString stringWithFormat:@"%@, %@", self.textLabel.text, - self.detailTextLabel.text]; - } - return self.textLabel.text; + cell.image = self.image; } @end
diff --git a/ios/chrome/browser/ui/settings/cells/settings_switch_cell.mm b/ios/chrome/browser/ui/settings/cells/settings_switch_cell.mm index 81360d9..ea54139 100644 --- a/ios/chrome/browser/ui/settings/cells/settings_switch_cell.mm +++ b/ios/chrome/browser/ui/settings/cells/settings_switch_cell.mm
@@ -243,7 +243,10 @@ } - (NSString*)accessibilityLabel { - return _textLabel.text; + if (!self.detailTextLabel.text) + return self.textLabel.text; + return [NSString stringWithFormat:@"%@, %@", self.textLabel.text, + self.detailTextLabel.text]; } - (NSString*)accessibilityValue {
diff --git a/ios/chrome/browser/ui/settings/google_services_settings_egtest.mm b/ios/chrome/browser/ui/settings/google_services_settings_egtest.mm index a39a9c2..3956ef6 100644 --- a/ios/chrome/browser/ui/settings/google_services_settings_egtest.mm +++ b/ios/chrome/browser/ui/settings/google_services_settings_egtest.mm
@@ -40,8 +40,7 @@ @synthesize scrollViewMatcher = _scrollViewMatcher; // Opens the Google services settings view, and closes it. -// TODO(crbug.com/918711): Tests failing. -- (void)DISABLED_testOpenGoogleServicesSettings { +- (void)testOpenGoogleServicesSettings { [self openGoogleServicesSettings]; // Assert title and accessibility. @@ -55,8 +54,7 @@ } // Tests the Google Services settings. -// TODO(crbug.com/918711): Tests failing. -- (void)DISABLED_testOpeningServices { +- (void)testOpeningServices { [self openGoogleServicesSettings]; [self assertNonPersonalizedServices]; } @@ -90,7 +88,7 @@ GetNSString(detailTextID)]; } return grey_allOf(grey_accessibilityLabel(accessibilityLabel), - grey_kindOfClass([UICollectionViewCell class]), + grey_kindOfClass([UITableViewCell class]), grey_sufficientlyVisible(), nil); }
diff --git a/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc b/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc index ae451c3..a329436 100644 --- a/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc +++ b/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc
@@ -32,8 +32,11 @@ closure.Run(); } -constexpr VideoCodecProfile kCodecProfiles[] = {H264PROFILE_MIN, VP8PROFILE_MIN, - VP9PROFILE_MIN}; +struct TestParams { + VideoCodecProfile video_codec; + bool decode_using_client_picture_buffers; +}; + constexpr int32_t kBitstreamId = 123; constexpr size_t kInputSize = 256; @@ -66,6 +69,7 @@ MOCK_METHOD4( CreateContextAndSurfaces, bool(unsigned int, const gfx::Size&, size_t, std::vector<VASurfaceID>*)); + MOCK_METHOD2(CreateContext, bool(unsigned int, const gfx::Size&)); MOCK_METHOD0(DestroyContextAndSurfaces, void()); private: @@ -104,6 +108,10 @@ return true; } bool AllowOverlay() const override { return false; } + VASurfaceID va_surface_id() const override { + // Return any number different from VA_INVALID_ID and VaapiPicture specific. + return static_cast<VASurfaceID>(texture_id_); + } }; class MockVaapiPictureFactory : public VaapiPictureFactory { @@ -127,7 +135,7 @@ } }; -class VaapiVideoDecodeAcceleratorTest : public TestWithParam<VideoCodecProfile>, +class VaapiVideoDecodeAcceleratorTest : public TestWithParam<TestParams>, public VideoDecodeAccelerator::Client { public: VaapiVideoDecodeAcceleratorTest() @@ -155,6 +163,11 @@ vda_.vpp_vaapi_wrapper_ = mock_vpp_vaapi_wrapper_; vda_.vaapi_picture_factory_.reset(mock_vaapi_picture_factory_); + vda_.output_mode_ = VideoDecodeAccelerator::Config::OutputMode::ALLOCATE; + + vda_.decode_using_client_picture_buffers_ = + GetParam().decode_using_client_picture_buffers; + vda_.state_ = VaapiVideoDecodeAccelerator::kIdle; } ~VaapiVideoDecodeAcceleratorTest() {} @@ -240,21 +253,29 @@ base::RunLoop run_loop; base::Closure quit_closure = run_loop.QuitClosure(); - // TODO(crbug.com/): We assume that |decode_using_client_picture_buffers_| - // is false, we should also support a pattern when - // |decode_using_client_picture_buffers_|. - EXPECT_CALL(*mock_vaapi_wrapper_, - CreateContextAndSurfaces(_, picture_size, num_pictures, _)) - .WillOnce( - DoAll(WithArg<3>(Invoke( - [num_pictures](std::vector<VASurfaceID>* va_surface_ids) { - va_surface_ids->resize(num_pictures); - })), - Return(true))); - EXPECT_CALL( - *mock_vaapi_picture_factory_, - MockCreateVaapiPicture(mock_vpp_vaapi_wrapper_.get(), picture_size)) - .Times(num_pictures); + // |decode_using_client_picture_buffers| determines the concrete method for + // creation of context, surfaces and VaapiPictures. + if (GetParam().decode_using_client_picture_buffers) { + EXPECT_CALL(*mock_vaapi_wrapper_, CreateContext(_, picture_size)) + .WillOnce(Return(true)); + EXPECT_CALL( + *mock_vaapi_picture_factory_, + MockCreateVaapiPicture(mock_vaapi_wrapper_.get(), picture_size)) + .Times(num_pictures); + } else { + EXPECT_CALL(*mock_vaapi_wrapper_, + CreateContextAndSurfaces(_, picture_size, num_pictures, _)) + .WillOnce(DoAll( + WithArg<3>(Invoke( + [num_pictures](std::vector<VASurfaceID>* va_surface_ids) { + va_surface_ids->resize(num_pictures); + })), + Return(true))); + EXPECT_CALL( + *mock_vaapi_picture_factory_, + MockCreateVaapiPicture(mock_vpp_vaapi_wrapper_.get(), picture_size)) + .Times(num_pictures); + } ::testing::InSequence s; EXPECT_CALL(*mock_decoder_, Decode()) @@ -420,8 +441,14 @@ ResetSequence(); } +constexpr TestParams kTestCases[] = { + {H264PROFILE_MIN, false /* decode_using_client_picture_buffers */}, + {VP8PROFILE_MIN, false /* decode_using_client_picture_buffers */}, + {VP9PROFILE_MIN, false /* decode_using_client_picture_buffers */}, + {VP9PROFILE_MIN, true /* decode_using_client_picture_buffers */}}; + INSTANTIATE_TEST_CASE_P(/* No prefix. */, VaapiVideoDecodeAcceleratorTest, - ValuesIn(kCodecProfiles)); + ValuesIn(kTestCases)); } // namespace media
diff --git a/media/gpu/vaapi/vaapi_wrapper.h b/media/gpu/vaapi/vaapi_wrapper.h index 7b5a239..07bf1a7 100644 --- a/media/gpu/vaapi/vaapi_wrapper.h +++ b/media/gpu/vaapi/vaapi_wrapper.h
@@ -110,7 +110,7 @@ // Creates a VA Context associated with |format| and |size|, and sets // |va_context_id_|. The |va_context_id_| will be destroyed by // DestroyContextAndSurfaces(). - bool CreateContext(unsigned int va_format, const gfx::Size& size); + virtual bool CreateContext(unsigned int va_format, const gfx::Size& size); // Frees all memory allocated in CreateContextAndSurfaces() and destroys // |va_context_id_|.
diff --git a/net/disk_cache/backend_unittest.cc b/net/disk_cache/backend_unittest.cc index 625874c..527d1ac 100644 --- a/net/disk_cache/backend_unittest.cc +++ b/net/disk_cache/backend_unittest.cc
@@ -162,7 +162,8 @@ void BackendDoomRecent(); void BackendDoomBetween(); void BackendCalculateSizeOfAllEntries(); - void BackendCalculateSizeOfEntriesBetween(); + void BackendCalculateSizeOfEntriesBetween( + bool expect_access_time_range_comparisons); void BackendTransaction(const std::string& name, int num_entries, bool load); void BackendRecoverInsert(); void BackendRecoverRemove(); @@ -2185,7 +2186,8 @@ BackendCalculateSizeOfAllEntries(); } -void DiskCacheBackendTest::BackendCalculateSizeOfEntriesBetween() { +void DiskCacheBackendTest::BackendCalculateSizeOfEntriesBetween( + bool expect_access_time_comparisons) { InitCache(); EXPECT_EQ(0, CalculateSizeOfEntriesBetween(base::Time(), base::Time::Max())); @@ -2218,12 +2220,14 @@ ASSERT_EQ(CalculateSizeOfAllEntries(), CalculateSizeOfEntriesBetween(base::Time(), base::Time::Max())); - int start_end = CalculateSizeOfEntriesBetween(start, end); - ASSERT_EQ(CalculateSizeOfAllEntries(), start_end); - ASSERT_EQ(size_1 + size_2 + size_3, start_end); + if (expect_access_time_comparisons) { + int start_end = CalculateSizeOfEntriesBetween(start, end); + ASSERT_EQ(CalculateSizeOfAllEntries(), start_end); + ASSERT_EQ(size_1 + size_2 + size_3, start_end); - ASSERT_EQ(size_1, CalculateSizeOfEntriesBetween(start, middle)); - ASSERT_EQ(size_2 + size_3, CalculateSizeOfEntriesBetween(middle, end)); + ASSERT_EQ(size_1, CalculateSizeOfEntriesBetween(start, middle)); + ASSERT_EQ(size_2 + size_3, CalculateSizeOfEntriesBetween(middle, end)); + } // After dooming the entries, the size should be back to zero. ASSERT_THAT(DoomAllEntries(), IsOk()); @@ -2238,15 +2242,21 @@ TEST_F(DiskCacheBackendTest, MemoryOnlyCalculateSizeOfEntriesBetween) { SetMemoryOnlyMode(); - BackendCalculateSizeOfEntriesBetween(); + BackendCalculateSizeOfEntriesBetween(true); } TEST_F(DiskCacheBackendTest, SimpleCacheCalculateSizeOfEntriesBetween) { - // Use net::APP_CACHE to make size estimations deterministic via - // non-optimistic writes. + // Test normal mode in where access time range comparisons are supported. + SetSimpleCacheMode(); + BackendCalculateSizeOfEntriesBetween(true); +} + +TEST_F(DiskCacheBackendTest, SimpleCacheAppCacheCalculateSizeOfEntriesBetween) { + // Test SimpleCache in APP_CACHE mode separately since it does not support + // access time range comparisons. SetCacheType(net::APP_CACHE); SetSimpleCacheMode(); - BackendCalculateSizeOfEntriesBetween(); + BackendCalculateSizeOfEntriesBetween(false); } void DiskCacheBackendTest::BackendTransaction(const std::string& name, @@ -3850,6 +3860,8 @@ } TEST_F(DiskCacheBackendTest, SimpleCacheShutdownWithPendingCreate) { + // Use net::APP_CACHE to make size estimations deterministic via + // non-optimistic writes. SetCacheType(net::APP_CACHE); SetSimpleCacheMode(); BackendShutdownWithPendingCreate(false);
diff --git a/net/disk_cache/entry_unittest.cc b/net/disk_cache/entry_unittest.cc index fc92b3b..01ffbbb 100644 --- a/net/disk_cache/entry_unittest.cc +++ b/net/disk_cache/entry_unittest.cc
@@ -5022,15 +5022,27 @@ DiskCacheEntryTest::SetUp(); } - void SetupPrefetch(int size) { + void SetupFullAndTrailerPrefetch(int full_size, + bool trailer_hint, + int trailer_speculative_size) { std::map<std::string, std::string> params; - params[disk_cache::kSimplePrefetchBytesParam] = base::IntToString(size); + params[disk_cache::kSimpleCacheFullPrefetchBytesParam] = + base::IntToString(full_size); + params[disk_cache::kSimpleCacheTrailerPrefetchHintParam] = + trailer_hint ? "true" : "false"; + params[disk_cache::kSimpleCacheTrailerPrefetchSpeculativeBytesParam] = + base::IntToString(trailer_speculative_size); scoped_feature_list_.InitAndEnableFeatureWithParameters( disk_cache::kSimpleCachePrefetchExperiment, params); } + void SetupFullPrefetch(int size) { + SetupFullAndTrailerPrefetch(size, false, 0); + } + void InitCacheAndCreateEntry(const std::string& key) { SetSimpleCacheMode(); + SetCacheType(SimpleCacheType()); InitCache(); disk_cache::Entry* entry; @@ -5041,6 +5053,8 @@ entry->Close(); } + virtual net::CacheType SimpleCacheType() const { return net::DISK_CACHE; } + void InitCacheAndCreateEntryWithNoCrc(const std::string& key) { const int kHalfSize = kEntrySize / 2; const int kRemSize = kEntrySize - kHalfSize; @@ -5086,35 +5100,35 @@ TEST_F(DiskCacheSimplePrefetchTest, NoPrefetch) { base::HistogramTester histogram_tester; - SetupPrefetch(0); + SetupFullPrefetch(0); const char kKey[] = "a key"; InitCacheAndCreateEntry(kKey); TryRead(kKey); - histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenDidPrefetch", - false, 1); + histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_NONE, 1); histogram_tester.ExpectUniqueSample( "SimpleCache.Http.ReadStream1FromPrefetched", false, 1); } TEST_F(DiskCacheSimplePrefetchTest, YesPrefetch) { base::HistogramTester histogram_tester; - SetupPrefetch(2 * kEntrySize); + SetupFullPrefetch(2 * kEntrySize); const char kKey[] = "a key"; InitCacheAndCreateEntry(kKey); TryRead(kKey); - histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenDidPrefetch", - true, 1); + histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_FULL, 1); histogram_tester.ExpectUniqueSample( "SimpleCache.Http.ReadStream1FromPrefetched", true, 1); } TEST_F(DiskCacheSimplePrefetchTest, YesPrefetchNoRead) { base::HistogramTester histogram_tester; - SetupPrefetch(2 * kEntrySize); + SetupFullPrefetch(2 * kEntrySize); const char kKey[] = "a key"; InitCacheAndCreateEntry(kKey); @@ -5123,8 +5137,8 @@ ASSERT_THAT(OpenEntry(kKey, &entry), IsOk()); entry->Close(); - histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenDidPrefetch", - true, 1); + histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_FULL, 1); // Have to use GetHistogramSamplesSinceCreation here since it's the only // API that handles the cases where the histogram hasn't even been created. std::unique_ptr<base::HistogramSamples> samples( @@ -5137,7 +5151,7 @@ // prefetched. This is like DiskCacheEntryTest.BadChecksum, but we make sure // to configure prefetch explicitly. TEST_F(DiskCacheSimplePrefetchTest, BadChecksumSmall) { - SetupPrefetch(1024); // bigger than stuff below. + SetupFullPrefetch(1024); // bigger than stuff below. SetSimpleCacheMode(); InitCache(); @@ -5154,7 +5168,7 @@ TEST_F(DiskCacheSimplePrefetchTest, ChecksumNoPrefetch) { base::HistogramTester histogram_tester; - SetupPrefetch(0); + SetupFullPrefetch(0); const char kKey[] = "a key"; InitCacheAndCreateEntry(kKey); TryRead(kKey); @@ -5169,7 +5183,7 @@ TEST_F(DiskCacheSimplePrefetchTest, NoChecksumNoPrefetch) { base::HistogramTester histogram_tester; - SetupPrefetch(0); + SetupFullPrefetch(0); const char kKey[] = "a key"; InitCacheAndCreateEntryWithNoCrc(kKey); TryRead(kKey); @@ -5187,7 +5201,7 @@ TEST_F(DiskCacheSimplePrefetchTest, ChecksumPrefetch) { base::HistogramTester histogram_tester; - SetupPrefetch(2 * kEntrySize); + SetupFullPrefetch(2 * kEntrySize); const char kKey[] = "a key"; InitCacheAndCreateEntry(kKey); TryRead(kKey); @@ -5202,7 +5216,7 @@ TEST_F(DiskCacheSimplePrefetchTest, NoChecksumPrefetch) { base::HistogramTester histogram_tester; - SetupPrefetch(2 * kEntrySize); + SetupFullPrefetch(2 * kEntrySize); const char kKey[] = "a key"; InitCacheAndCreateEntryWithNoCrc(kKey); TryRead(kKey); @@ -5219,7 +5233,7 @@ TEST_F(DiskCacheSimplePrefetchTest, PrefetchReadsSync) { // Make sure we can read things synchronously after prefetch. - SetupPrefetch(32768); // way bigger than kEntrySize + SetupFullPrefetch(32768); // way bigger than kEntrySize const char kKey[] = "a key"; InitCacheAndCreateEntry(kKey); @@ -5236,3 +5250,480 @@ EXPECT_EQ(0, memcmp(read_buf->data(), payload_->data(), kEntrySize)); entry->Close(); } + +TEST_F(DiskCacheSimplePrefetchTest, NoFullNoHintNoSpeculative) { + base::HistogramTester histogram_tester; + SetupFullAndTrailerPrefetch(0, false, 0); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_NONE, 1); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize", + 0); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1); + histogram_tester.ExpectTotalCount( + "SimpleCache.Http.EntryTrailerPrefetchDelta", 0); + histogram_tester.ExpectUniqueSample( + "SimpleCache.Http.ReadStream1FromPrefetched", false, 1); +} + +TEST_F(DiskCacheSimplePrefetchTest, NoFullYesHintNoSpeculative) { + base::HistogramTester histogram_tester; + // Trailer prefetch hint should do nothing outside of APP_CACHE mode. + SetupFullAndTrailerPrefetch(0, true, 0); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_NONE, 1); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize", + 0); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1); + histogram_tester.ExpectTotalCount( + "SimpleCache.Http.EntryTrailerPrefetchDelta", 0); + histogram_tester.ExpectUniqueSample( + "SimpleCache.Http.ReadStream1FromPrefetched", false, 1); +} + +TEST_F(DiskCacheSimplePrefetchTest, NoFullNoHintSmallSpeculative) { + base::HistogramTester histogram_tester; + SetupFullAndTrailerPrefetch(0, false, kEntrySize / 2); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_TRAILER, 1); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize", + 1); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1); + histogram_tester.ExpectTotalCount( + "SimpleCache.Http.EntryTrailerPrefetchDelta", 1); + histogram_tester.ExpectUniqueSample( + "SimpleCache.Http.ReadStream1FromPrefetched", false, 1); +} + +TEST_F(DiskCacheSimplePrefetchTest, NoFullNoHintLargeSpeculative) { + base::HistogramTester histogram_tester; + // A large speculative trailer prefetch that exceeds the entry file + // size should effectively trigger full prefetch behavior. + SetupFullAndTrailerPrefetch(0, false, kEntrySize * 2); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_FULL, 1); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize", + 0); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1); + histogram_tester.ExpectTotalCount( + "SimpleCache.Http.EntryTrailerPrefetchDelta", 0); + histogram_tester.ExpectUniqueSample( + "SimpleCache.Http.ReadStream1FromPrefetched", true, 1); +} + +TEST_F(DiskCacheSimplePrefetchTest, NoFullYesHintSmallSpeculative) { + base::HistogramTester histogram_tester; + // Trailer prefetch hint should do nothing outside of APP_CACHE mode. + SetupFullAndTrailerPrefetch(0, true, kEntrySize / 2); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_TRAILER, 1); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize", + 1); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1); + histogram_tester.ExpectTotalCount( + "SimpleCache.Http.EntryTrailerPrefetchDelta", 1); + histogram_tester.ExpectUniqueSample( + "SimpleCache.Http.ReadStream1FromPrefetched", false, 1); +} + +TEST_F(DiskCacheSimplePrefetchTest, NoFullYesHintLargeSpeculative) { + base::HistogramTester histogram_tester; + // Trailer prefetch hint should do nothing outside of APP_CACHE mode. + SetupFullAndTrailerPrefetch(0, true, kEntrySize * 2); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_FULL, 1); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize", + 0); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1); + histogram_tester.ExpectTotalCount( + "SimpleCache.Http.EntryTrailerPrefetchDelta", 0); + histogram_tester.ExpectUniqueSample( + "SimpleCache.Http.ReadStream1FromPrefetched", true, 1); +} + +TEST_F(DiskCacheSimplePrefetchTest, SmallFullNoHintNoSpeculative) { + base::HistogramTester histogram_tester; + SetupFullAndTrailerPrefetch(kEntrySize / 2, false, 0); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_NONE, 1); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize", + 0); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1); + histogram_tester.ExpectTotalCount( + "SimpleCache.Http.EntryTrailerPrefetchDelta", 0); + histogram_tester.ExpectUniqueSample( + "SimpleCache.Http.ReadStream1FromPrefetched", false, 1); +} + +TEST_F(DiskCacheSimplePrefetchTest, LargeFullNoHintNoSpeculative) { + base::HistogramTester histogram_tester; + SetupFullAndTrailerPrefetch(kEntrySize * 2, false, 0); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_FULL, 1); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize", + 0); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1); + histogram_tester.ExpectTotalCount( + "SimpleCache.Http.EntryTrailerPrefetchDelta", 0); + histogram_tester.ExpectUniqueSample( + "SimpleCache.Http.ReadStream1FromPrefetched", true, 1); +} + +TEST_F(DiskCacheSimplePrefetchTest, SmallFullYesHintNoSpeculative) { + base::HistogramTester histogram_tester; + // Trailer prefetch hint should do nothing outside of APP_CACHE mode. + SetupFullAndTrailerPrefetch(kEntrySize / 2, true, 0); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_NONE, 1); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize", + 0); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1); + histogram_tester.ExpectTotalCount( + "SimpleCache.Http.EntryTrailerPrefetchDelta", 0); + histogram_tester.ExpectUniqueSample( + "SimpleCache.Http.ReadStream1FromPrefetched", false, 1); +} + +TEST_F(DiskCacheSimplePrefetchTest, LargeFullYesHintNoSpeculative) { + base::HistogramTester histogram_tester; + // Trailer prefetch hint should do nothing outside of APP_CACHE mode. + SetupFullAndTrailerPrefetch(kEntrySize * 2, true, 0); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_FULL, 1); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize", + 0); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1); + histogram_tester.ExpectTotalCount( + "SimpleCache.Http.EntryTrailerPrefetchDelta", 0); + histogram_tester.ExpectUniqueSample( + "SimpleCache.Http.ReadStream1FromPrefetched", true, 1); +} + +TEST_F(DiskCacheSimplePrefetchTest, SmallFullNoHintSmallSpeculative) { + base::HistogramTester histogram_tester; + SetupFullAndTrailerPrefetch(kEntrySize / 2, false, kEntrySize / 2); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_TRAILER, 1); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize", + 1); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1); + histogram_tester.ExpectTotalCount( + "SimpleCache.Http.EntryTrailerPrefetchDelta", 1); + histogram_tester.ExpectUniqueSample( + "SimpleCache.Http.ReadStream1FromPrefetched", false, 1); +} + +TEST_F(DiskCacheSimplePrefetchTest, LargeFullNoHintSmallSpeculative) { + base::HistogramTester histogram_tester; + // Full prefetch takes precedence over a trailer speculative prefetch. + SetupFullAndTrailerPrefetch(kEntrySize * 2, false, kEntrySize / 2); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_FULL, 1); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize", + 0); + histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1); + histogram_tester.ExpectTotalCount( + "SimpleCache.Http.EntryTrailerPrefetchDelta", 0); + histogram_tester.ExpectUniqueSample( + "SimpleCache.Http.ReadStream1FromPrefetched", true, 1); +} + +class DiskCacheSimpleAppCachePrefetchTest : public DiskCacheSimplePrefetchTest { + public: + // APP_CACHE mode will enable trailer prefetch hint support. + net::CacheType SimpleCacheType() const override { return net::APP_CACHE; } +}; + +TEST_F(DiskCacheSimpleAppCachePrefetchTest, NoFullNoHintNoSpeculative) { + base::HistogramTester histogram_tester; + SetupFullAndTrailerPrefetch(0, false, 0); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_NONE, 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize", + 0); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchDelta", + 0); + histogram_tester.ExpectUniqueSample( + "SimpleCache.App.ReadStream1FromPrefetched", false, 1); +} + +TEST_F(DiskCacheSimpleAppCachePrefetchTest, NoFullYesHintNoSpeculative) { + base::HistogramTester histogram_tester; + SetupFullAndTrailerPrefetch(0, true, 0); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_TRAILER, 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize", + 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1); + histogram_tester.ExpectUniqueSample( + "SimpleCache.App.EntryTrailerPrefetchDelta", 0, 1); + histogram_tester.ExpectUniqueSample( + "SimpleCache.App.ReadStream1FromPrefetched", false, 1); +} + +TEST_F(DiskCacheSimpleAppCachePrefetchTest, NoFullNoHintSmallSpeculative) { + base::HistogramTester histogram_tester; + SetupFullAndTrailerPrefetch(0, false, kEntrySize / 2); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_TRAILER, 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize", + 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchDelta", + 1); + histogram_tester.ExpectUniqueSample( + "SimpleCache.App.ReadStream1FromPrefetched", false, 1); +} + +TEST_F(DiskCacheSimpleAppCachePrefetchTest, NoFullNoHintLargeSpeculative) { + base::HistogramTester histogram_tester; + // A large speculative trailer prefetch that exceeds the entry file + // size should effectively trigger full prefetch behavior. + SetupFullAndTrailerPrefetch(0, false, kEntrySize * 2); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_FULL, 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize", + 0); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchDelta", + 0); + histogram_tester.ExpectUniqueSample( + "SimpleCache.App.ReadStream1FromPrefetched", true, 1); +} + +TEST_F(DiskCacheSimpleAppCachePrefetchTest, NoFullYesHintSmallSpeculative) { + base::HistogramTester histogram_tester; + SetupFullAndTrailerPrefetch(0, true, kEntrySize / 2); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_TRAILER, 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize", + 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1); + histogram_tester.ExpectUniqueSample( + "SimpleCache.App.EntryTrailerPrefetchDelta", 0, 1); + histogram_tester.ExpectUniqueSample( + "SimpleCache.App.ReadStream1FromPrefetched", false, 1); +} + +TEST_F(DiskCacheSimpleAppCachePrefetchTest, NoFullYesHintLargeSpeculative) { + base::HistogramTester histogram_tester; + // Even though the speculative trailer prefetch size is larger than the + // file size, the hint should take precedence and still perform a limited + // trailer prefetch. + SetupFullAndTrailerPrefetch(0, true, kEntrySize * 2); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_TRAILER, 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize", + 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1); + histogram_tester.ExpectUniqueSample( + "SimpleCache.App.EntryTrailerPrefetchDelta", 0, 1); + histogram_tester.ExpectUniqueSample( + "SimpleCache.App.ReadStream1FromPrefetched", false, 1); +} + +TEST_F(DiskCacheSimpleAppCachePrefetchTest, SmallFullNoHintNoSpeculative) { + base::HistogramTester histogram_tester; + SetupFullAndTrailerPrefetch(kEntrySize / 2, false, 0); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_NONE, 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize", + 0); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchDelta", + 0); + histogram_tester.ExpectUniqueSample( + "SimpleCache.App.ReadStream1FromPrefetched", false, 1); +} + +TEST_F(DiskCacheSimpleAppCachePrefetchTest, LargeFullNoHintNoSpeculative) { + base::HistogramTester histogram_tester; + SetupFullAndTrailerPrefetch(kEntrySize * 2, false, 0); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_FULL, 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize", + 0); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchDelta", + 0); + histogram_tester.ExpectUniqueSample( + "SimpleCache.App.ReadStream1FromPrefetched", true, 1); +} + +TEST_F(DiskCacheSimpleAppCachePrefetchTest, SmallFullYesHintNoSpeculative) { + base::HistogramTester histogram_tester; + SetupFullAndTrailerPrefetch(kEntrySize / 2, true, 0); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_TRAILER, 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize", + 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1); + histogram_tester.ExpectUniqueSample( + "SimpleCache.App.EntryTrailerPrefetchDelta", 0, 1); + histogram_tester.ExpectUniqueSample( + "SimpleCache.App.ReadStream1FromPrefetched", false, 1); +} + +TEST_F(DiskCacheSimpleAppCachePrefetchTest, LargeFullYesHintNoSpeculative) { + base::HistogramTester histogram_tester; + // Full prefetch takes precedence over a trailer hint prefetch. + SetupFullAndTrailerPrefetch(kEntrySize * 2, true, 0); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_FULL, 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize", + 0); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchDelta", + 0); + histogram_tester.ExpectUniqueSample( + "SimpleCache.App.ReadStream1FromPrefetched", true, 1); +} + +TEST_F(DiskCacheSimpleAppCachePrefetchTest, SmallFullNoHintSmallSpeculative) { + base::HistogramTester histogram_tester; + SetupFullAndTrailerPrefetch(kEntrySize / 2, false, kEntrySize / 2); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_TRAILER, 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize", + 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchDelta", + 1); + histogram_tester.ExpectUniqueSample( + "SimpleCache.App.ReadStream1FromPrefetched", false, 1); +} + +TEST_F(DiskCacheSimpleAppCachePrefetchTest, LargeFullNoHintSmallSpeculative) { + base::HistogramTester histogram_tester; + // Full prefetch takes precedence over a trailer speculative prefetch. + SetupFullAndTrailerPrefetch(kEntrySize * 2, false, kEntrySize / 2); + + const char kKey[] = "a key"; + InitCacheAndCreateEntry(kKey); + TryRead(kKey); + + histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode", + disk_cache::OPEN_PREFETCH_FULL, 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize", + 0); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1); + histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchDelta", + 0); + histogram_tester.ExpectUniqueSample( + "SimpleCache.App.ReadStream1FromPrefetched", true, 1); +}
diff --git a/net/disk_cache/simple/simple_backend_version.h b/net/disk_cache/simple/simple_backend_version.h index e7a0ce6..c3d0ba7 100644 --- a/net/disk_cache/simple/simple_backend_version.h +++ b/net/disk_cache/simple/simple_backend_version.h
@@ -19,7 +19,7 @@ // * Dropping cache data on disk or some of its parts can be a valid way to // Upgrade. const uint32_t kLastCompatSparseVersion = 7; -const uint32_t kSimpleVersion = 8; +const uint32_t kSimpleVersion = 9; // The version of the entry file(s) as written to disk. Must be updated iff the // entry format changes with the overall backend version update.
diff --git a/net/disk_cache/simple/simple_entry_impl.cc b/net/disk_cache/simple/simple_entry_impl.cc index be6a90fd..e5096b4 100644 --- a/net/disk_cache/simple/simple_entry_impl.cc +++ b/net/disk_cache/simple/simple_entry_impl.cc
@@ -728,9 +728,15 @@ new SimpleEntryCreationResults(SimpleEntryStat( last_used_, last_modified_, data_size_, sparse_data_size_))); - base::OnceClosure task = base::BindOnce( - &SimpleSynchronousEntry::OpenEntry, cache_type_, path_, key_, entry_hash_, - have_index, start_time, file_tracker_, results.get()); + int32_t trailer_prefetch_size = + cache_type_ == net::APP_CACHE && backend_.get() + ? backend_->index()->GetTrailerPrefetchSize(entry_hash_) + : -1; + + base::OnceClosure task = + base::BindOnce(&SimpleSynchronousEntry::OpenEntry, cache_type_, path_, + key_, entry_hash_, have_index, start_time, file_tracker_, + trailer_prefetch_size, results.get()); base::OnceClosure reply = base::BindOnce( &SimpleEntryImpl::CreationOperationComplete, this, std::move(callback), @@ -810,13 +816,17 @@ DCHECK(STATE_UNINITIALIZED == state_ || STATE_FAILURE == state_); } + std::unique_ptr<SimpleEntryCloseResults> results = + std::make_unique<SimpleEntryCloseResults>(); if (synchronous_entry_) { - Closure task = base::Bind( + OnceClosure task = base::BindOnce( &SimpleSynchronousEntry::Close, base::Unretained(synchronous_entry_), SimpleEntryStat(last_used_, last_modified_, data_size_, sparse_data_size_), - base::Passed(&crc32s_to_write), base::RetainedRef(stream_0_data_)); - Closure reply = base::Bind(&SimpleEntryImpl::CloseOperationComplete, this); + base::Passed(&crc32s_to_write), base::RetainedRef(stream_0_data_), + results.get()); + OnceClosure reply = base::BindOnce(&SimpleEntryImpl::CloseOperationComplete, + this, base::Passed(&results)); synchronous_entry_ = NULL; prioritized_task_runner_->PostTaskAndReply( FROM_HERE, std::move(task), std::move(reply), entry_priority_); @@ -829,7 +839,7 @@ } } } else { - CloseOperationComplete(); + CloseOperationComplete(std::move(results)); } } @@ -1311,6 +1321,10 @@ DCHECK_EQ(key_, synchronous_entry_->key()); } UpdateDataFromEntryStat(in_results->entry_stat); + if (cache_type_ == net::APP_CACHE && backend_.get() && backend_->index()) { + backend_->index()->SetTrailerPrefetchSize( + entry_hash_, in_results->computed_trailer_prefetch_size); + } SIMPLE_CACHE_UMA(TIMES, "EntryCreationTime", cache_type_, (base::TimeTicks::Now() - start_time)); @@ -1492,13 +1506,20 @@ } } -void SimpleEntryImpl::CloseOperationComplete() { +void SimpleEntryImpl::CloseOperationComplete( + std::unique_ptr<SimpleEntryCloseResults> in_results) { DCHECK(!synchronous_entry_); DCHECK_EQ(0, open_count_); DCHECK(STATE_IO_PENDING == state_ || STATE_FAILURE == state_ || STATE_UNINITIALIZED == state_); net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_CLOSE_END); AdjustOpenEntryCountBy(cache_type_, -1); + if (cache_type_ == net::APP_CACHE && + in_results->estimated_trailer_prefetch_size > 0 && backend_.get() && + backend_->index()) { + backend_->index()->SetTrailerPrefetchSize( + entry_hash_, in_results->estimated_trailer_prefetch_size); + } ResetEntry(); RunNextOperationIfNeeded(); }
diff --git a/net/disk_cache/simple/simple_entry_impl.h b/net/disk_cache/simple/simple_entry_impl.h index 21171fc6..a00fb8c 100644 --- a/net/disk_cache/simple/simple_entry_impl.h +++ b/net/disk_cache/simple/simple_entry_impl.h
@@ -275,7 +275,8 @@ // Called after we've closed and written the EOF record to our entry. Until // this point it hasn't been safe to OpenEntry() the same entry, but from this // point it is. - void CloseOperationComplete(); + void CloseOperationComplete( + std::unique_ptr<SimpleEntryCloseResults> in_results); // Internal utility method used by other completion methods. Calls // |completion_callback| after updating state and dooming on errors.
diff --git a/net/disk_cache/simple/simple_file_tracker_unittest.cc b/net/disk_cache/simple/simple_file_tracker_unittest.cc index 5fa8ce3..aa5507d 100644 --- a/net/disk_cache/simple/simple_file_tracker_unittest.cc +++ b/net/disk_cache/simple/simple_file_tracker_unittest.cc
@@ -53,7 +53,8 @@ SyncEntryPointer MakeSyncEntry(uint64_t hash) { return SyncEntryPointer( new SimpleSynchronousEntry(net::DISK_CACHE, cache_path_, "dummy", hash, - /* had_index=*/true, &file_tracker_), + /* had_index=*/true, &file_tracker_, + /*trailer_prefetch_size=*/-1), SyncEntryDeleter(this)); }
diff --git a/net/disk_cache/simple/simple_histogram_enums.h b/net/disk_cache/simple/simple_histogram_enums.h index 8f6d40b..67221b271 100644 --- a/net/disk_cache/simple/simple_histogram_enums.h +++ b/net/disk_cache/simple/simple_histogram_enums.h
@@ -35,6 +35,14 @@ }; // Used in histograms, please only add entries at the end. +enum OpenPrefetchMode { + OPEN_PREFETCH_NONE = 0, + OPEN_PREFETCH_FULL = 1, + OPEN_PREFETCH_TRAILER = 2, + OPEN_PREFETCH_MAX = 3, +}; + +// Used in histograms, please only add entries at the end. enum SyncWriteResult { SYNC_WRITE_RESULT_SUCCESS = 0, SYNC_WRITE_RESULT_PRETRUNCATE_FAILURE = 1,
diff --git a/net/disk_cache/simple/simple_index.cc b/net/disk_cache/simple/simple_index.cc index 6afe87f..57a3c6fc 100644 --- a/net/disk_cache/simple/simple_index.cc +++ b/net/disk_cache/simple/simple_index.cc
@@ -76,6 +76,15 @@ SetLastUsedTime(last_used_time); } +EntryMetadata::EntryMetadata(int32_t trailer_prefetch_size, + base::StrictNumeric<uint32_t> entry_size) + : trailer_prefetch_size_(0), + entry_size_256b_chunks_(0), + in_memory_data_(0) { + SetEntrySize(entry_size); // to round/pack properly + SetTrailerPrefetchSize(trailer_prefetch_size); +} + base::Time EntryMetadata::GetLastUsedTime() const { // Preserve nullity. if (last_used_time_seconds_since_epoch_ == 0) @@ -99,6 +108,16 @@ last_used_time_seconds_since_epoch_ = 1; } +int32_t EntryMetadata::GetTrailerPrefetchSize() const { + return trailer_prefetch_size_; +} + +void EntryMetadata::SetTrailerPrefetchSize(int32_t size) { + if (size <= 0) + return; + trailer_prefetch_size_ = size; +} + uint32_t EntryMetadata::GetEntrySize() const { return entry_size_256b_chunks_ << 8; } @@ -108,25 +127,43 @@ entry_size_256b_chunks_ = (static_cast<uint32_t>(entry_size) + 255) >> 8; } -void EntryMetadata::Serialize(base::Pickle* pickle) const { +void EntryMetadata::Serialize(net::CacheType cache_type, + base::Pickle* pickle) const { DCHECK(pickle); - int64_t internal_last_used_time = GetLastUsedTime().ToInternalValue(); // If you modify the size of the size of the pickle, be sure to update // kOnDiskSizeBytes. uint32_t packed_entry_info = (entry_size_256b_chunks_ << 8) | in_memory_data_; - pickle->WriteInt64(internal_last_used_time); + if (cache_type == net::APP_CACHE) { + pickle->WriteInt64(trailer_prefetch_size_); + } else { + int64_t internal_last_used_time = GetLastUsedTime().ToInternalValue(); + pickle->WriteInt64(internal_last_used_time); + } pickle->WriteUInt64(packed_entry_info); } -bool EntryMetadata::Deserialize(base::PickleIterator* it, - bool has_entry_in_memory_data) { +bool EntryMetadata::Deserialize(net::CacheType cache_type, + base::PickleIterator* it, + bool has_entry_in_memory_data, + bool app_cache_has_trailer_prefetch_size) { DCHECK(it); - int64_t tmp_last_used_time; + int64_t tmp_time_or_prefetch_size; uint64_t tmp_entry_size; - if (!it->ReadInt64(&tmp_last_used_time) || !it->ReadUInt64(&tmp_entry_size) || + if (!it->ReadInt64(&tmp_time_or_prefetch_size) || + !it->ReadUInt64(&tmp_entry_size) || tmp_entry_size > std::numeric_limits<uint32_t>::max()) return false; - SetLastUsedTime(base::Time::FromInternalValue(tmp_last_used_time)); + if (cache_type == net::APP_CACHE) { + if (app_cache_has_trailer_prefetch_size) { + int32_t trailer_prefetch_size = 0; + base::CheckedNumeric<int32_t> numeric_size(tmp_time_or_prefetch_size); + if (numeric_size.AssignIfValid(&trailer_prefetch_size)) { + SetTrailerPrefetchSize(trailer_prefetch_size); + } + } + } else { + SetLastUsedTime(base::Time::FromInternalValue(tmp_time_or_prefetch_size)); + } if (has_entry_in_memory_data) { // tmp_entry_size actually packs entry_size_256b_chunks_ and // in_memory_data_. @@ -302,8 +339,14 @@ // Upon insert we don't know yet the size of the entry. // It will be updated later when the SimpleEntryImpl finishes opening or // creating the new entry, and then UpdateEntrySize will be called. - bool inserted = InsertInEntrySet( - entry_hash, EntryMetadata(base::Time::Now(), 0u), &entries_set_); + bool inserted = false; + if (cache_type_ == net::APP_CACHE) { + inserted = + InsertInEntrySet(entry_hash, EntryMetadata(-1, 0u), &entries_set_); + } else { + inserted = InsertInEntrySet( + entry_hash, EntryMetadata(base::Time::Now(), 0u), &entries_set_); + } if (!initialized_) removed_entries_.erase(entry_hash); if (inserted) @@ -422,6 +465,27 @@ AsWeakPtr())); } +int32_t SimpleIndex::GetTrailerPrefetchSize(uint64_t entry_hash) const { + DCHECK(io_thread_checker_.CalledOnValidThread()); + DCHECK_EQ(cache_type_, net::APP_CACHE); + auto it = entries_set_.find(entry_hash); + if (it == entries_set_.end()) + return -1; + return it->second.GetTrailerPrefetchSize(); +} + +void SimpleIndex::SetTrailerPrefetchSize(uint64_t entry_hash, int32_t size) { + DCHECK(io_thread_checker_.CalledOnValidThread()); + DCHECK_EQ(cache_type_, net::APP_CACHE); + auto it = entries_set_.find(entry_hash); + if (it == entries_set_.end()) + return; + int32_t original_size = it->second.GetTrailerPrefetchSize(); + it->second.SetTrailerPrefetchSize(size); + if (original_size != it->second.GetTrailerPrefetchSize()) + PostponeWritingToDisk(); +} + bool SimpleIndex::UpdateEntrySize(uint64_t entry_hash, base::StrictNumeric<uint32_t> entry_size) { DCHECK(io_thread_checker_.CalledOnValidThread()); @@ -609,8 +673,8 @@ cleanup_tracker_); } - index_file_->WriteToDisk(reason, entries_set_, cache_size_, start, - app_on_background_, after_write); + index_file_->WriteToDisk(cache_type_, reason, entries_set_, cache_size_, + start, app_on_background_, after_write); } } // namespace disk_cache
diff --git a/net/disk_cache/simple/simple_index.h b/net/disk_cache/simple/simple_index.h index 4e06cd1..ad7b017 100644 --- a/net/disk_cache/simple/simple_index.h +++ b/net/disk_cache/simple/simple_index.h
@@ -53,10 +53,15 @@ EntryMetadata(); EntryMetadata(base::Time last_used_time, base::StrictNumeric<uint32_t> entry_size); + EntryMetadata(int32_t trailer_prefetch_size, + base::StrictNumeric<uint32_t> entry_size); base::Time GetLastUsedTime() const; void SetLastUsedTime(const base::Time& last_used_time); + int32_t GetTrailerPrefetchSize() const; + void SetTrailerPrefetchSize(int32_t size); + uint32_t RawTimeForSorting() const { return last_used_time_seconds_since_epoch_; } @@ -68,8 +73,11 @@ void SetInMemoryData(uint8_t val) { in_memory_data_ = val; } // Serialize the data into the provided pickle. - void Serialize(base::Pickle* pickle) const; - bool Deserialize(base::PickleIterator* it, bool has_entry_in_memory_data); + void Serialize(net::CacheType cache_type, base::Pickle* pickle) const; + bool Deserialize(net::CacheType cache_type, + base::PickleIterator* it, + bool has_entry_in_memory_data, + bool app_cache_has_trailer_prefetch_size); static base::TimeDelta GetLowerEpsilonForTimeComparisons() { return base::TimeDelta::FromSeconds(1); @@ -82,12 +90,23 @@ private: friend class SimpleIndexFileTest; + FRIEND_TEST_ALL_PREFIXES(SimpleIndexFileTest, ReadV8Format); + FRIEND_TEST_ALL_PREFIXES(SimpleIndexFileTest, ReadV8FormatAppCache); // There are tens of thousands of instances of EntryMetadata in memory, so the // size of each entry matters. Even when the values used to set these members // are originally calculated as >32-bit types, the actual necessary size for // each shouldn't exceed 32 bits, so we use 32-bit types here. - uint32_t last_used_time_seconds_since_epoch_; + + // In most modes we track the last access time in order to support automatic + // eviction. In APP_CACHE mode, however, eviction is disabled. Instead of + // storing the access time in APP_CACHE mode we instead store a hint about + // how much entry file trailer should be prefetched when its opened. + union { + uint32_t last_used_time_seconds_since_epoch_; + int32_t trailer_prefetch_size_; // in bytes + }; + uint32_t entry_size_256b_chunks_ : 24; // in 256-byte blocks, rounded up. uint32_t in_memory_data_ : 8; }; @@ -143,6 +162,9 @@ void WriteToDisk(IndexWriteToDiskReason reason); + int32_t GetTrailerPrefetchSize(uint64_t entry_hash) const; + void SetTrailerPrefetchSize(uint64_t entry_hash, int32_t size); + // Update the size (in bytes) of an entry, in the metadata stored in the // index. This should be the total disk-file size including all streams of the // entry.
diff --git a/net/disk_cache/simple/simple_index_file.cc b/net/disk_cache/simple/simple_index_file.cc index e1a4192..56551d2 100644 --- a/net/disk_cache/simple/simple_index_file.cc +++ b/net/disk_cache/simple/simple_index_file.cc
@@ -349,11 +349,11 @@ return false; } - static_assert(kSimpleVersion == 8, "index metadata reader out of date"); + static_assert(kSimpleVersion == 9, "index metadata reader out of date"); // No |reason_| is saved in the version 6 file format. if (version_ == 6) return reason_ == SimpleIndex::INDEX_WRITE_REASON_MAX; - return (version_ == 7 || version_ == 8) && + return (version_ == 7 || version_ == 8 || version_ == 9) && reason_ < SimpleIndex::INDEX_WRITE_REASON_MAX; } @@ -383,7 +383,8 @@ worker_pool_->PostTaskAndReply(FROM_HERE, task, callback); } -void SimpleIndexFile::WriteToDisk(SimpleIndex::IndexWriteToDiskReason reason, +void SimpleIndexFile::WriteToDisk(net::CacheType cache_type, + SimpleIndex::IndexWriteToDiskReason reason, const SimpleIndex::EntrySet& entry_set, uint64_t cache_size, const base::TimeTicks& start, @@ -391,7 +392,8 @@ const base::Closure& callback) { UmaRecordIndexWriteReason(reason, cache_type_); IndexMetadata index_metadata(reason, entry_set.size(), cache_size); - std::unique_ptr<base::Pickle> pickle = Serialize(index_metadata, entry_set); + std::unique_ptr<base::Pickle> pickle = + Serialize(cache_type, index_metadata, entry_set); base::Closure task = base::Bind(&SimpleIndexFile::SyncWriteToDisk, cache_type_, cache_directory_, index_file_, temp_index_file_, @@ -411,7 +413,8 @@ SimpleIndexLoadResult* out_result) { // Load the index and find its age. base::Time last_cache_seen_by_index; - SyncLoadFromDisk(index_file_path, &last_cache_seen_by_index, out_result); + SyncLoadFromDisk(cache_type, index_file_path, &last_cache_seen_by_index, + out_result); // Consider the index loaded if it is fresh. const bool index_file_existed = base::PathExists(index_file_path); @@ -474,7 +477,8 @@ } // static -void SimpleIndexFile::SyncLoadFromDisk(const base::FilePath& index_filename, +void SimpleIndexFile::SyncLoadFromDisk(net::CacheType cache_type, + const base::FilePath& index_filename, base::Time* out_last_cache_seen_by_index, SimpleIndexLoadResult* out_result) { out_result->Reset(); @@ -504,8 +508,8 @@ return; } - SimpleIndexFile::Deserialize(buffer.get(), read, out_last_cache_seen_by_index, - out_result); + SimpleIndexFile::Deserialize(cache_type, buffer.get(), read, + out_last_cache_seen_by_index, out_result); if (!out_result->did_load) simple_util::SimpleCacheDeleteFile(index_filename); @@ -513,6 +517,7 @@ // static std::unique_ptr<base::Pickle> SimpleIndexFile::Serialize( + net::CacheType cache_type, const SimpleIndexFile::IndexMetadata& index_metadata, const SimpleIndex::EntrySet& entries) { std::unique_ptr<base::Pickle> pickle = std::make_unique<SimpleIndexPickle>(); @@ -520,13 +525,15 @@ index_metadata.Serialize(pickle.get()); for (auto it = entries.begin(); it != entries.end(); ++it) { pickle->WriteUInt64(it->first); - it->second.Serialize(pickle.get()); + it->second.Serialize(cache_type, pickle.get()); } return pickle; } // static -void SimpleIndexFile::Deserialize(const char* data, int data_len, +void SimpleIndexFile::Deserialize(net::CacheType cache_type, + const char* data, + int data_len, base::Time* out_cache_last_modified, SimpleIndexLoadResult* out_result) { DCHECK(data); @@ -567,7 +574,8 @@ EntryMetadata entry_metadata; if (!pickle_it.ReadUInt64(&hash_key) || !entry_metadata.Deserialize( - &pickle_it, index_metadata.has_entry_in_memory_data())) { + cache_type, &pickle_it, index_metadata.has_entry_in_memory_data(), + index_metadata.app_cache_has_trailer_prefetch_size())) { LOG(WARNING) << "Invalid EntryMetadata in Simple Index file."; entries->clear(); return;
diff --git a/net/disk_cache/simple/simple_index_file.h b/net/disk_cache/simple/simple_index_file.h index abe7a3c..afc00a0c 100644 --- a/net/disk_cache/simple/simple_index_file.h +++ b/net/disk_cache/simple/simple_index_file.h
@@ -68,14 +68,18 @@ SimpleIndex::IndexWriteToDiskReason reason() const { return reason_; } uint64_t entry_count() const { return entry_count_; } bool has_entry_in_memory_data() const { return version_ >= 8; } + bool app_cache_has_trailer_prefetch_size() const { return version_ >= 9; } private: FRIEND_TEST_ALL_PREFIXES(IndexMetadataTest, Basics); FRIEND_TEST_ALL_PREFIXES(IndexMetadataTest, Serialize); FRIEND_TEST_ALL_PREFIXES(IndexMetadataTest, ReadV6Format); FRIEND_TEST_ALL_PREFIXES(SimpleIndexFileTest, ReadV7Format); + FRIEND_TEST_ALL_PREFIXES(SimpleIndexFileTest, ReadV8Format); + FRIEND_TEST_ALL_PREFIXES(SimpleIndexFileTest, ReadV8FormatAppCache); friend class V6IndexMetadataForTest; friend class V7IndexMetadataForTest; + friend class V8IndexMetadataForTest; uint64_t magic_number_; uint32_t version_; @@ -98,7 +102,8 @@ SimpleIndexLoadResult* out_result); // Writes the specified set of entries to disk. - virtual void WriteToDisk(SimpleIndex::IndexWriteToDiskReason reason, + virtual void WriteToDisk(net::CacheType cache_type, + SimpleIndex::IndexWriteToDiskReason reason, const SimpleIndex::EntrySet& entry_set, uint64_t cache_size, const base::TimeTicks& start, @@ -126,7 +131,8 @@ SimpleIndexLoadResult* out_result); // Load the index file from disk returning an EntrySet. - static void SyncLoadFromDisk(const base::FilePath& index_filename, + static void SyncLoadFromDisk(net::CacheType cache_type, + const base::FilePath& index_filename, base::Time* out_last_cache_seen_by_index, SimpleIndexLoadResult* out_result); @@ -136,6 +142,7 @@ // immediately after calling this menthod, one needs to call // SerializeFinalData to make it ready to write to a file. static std::unique_ptr<base::Pickle> Serialize( + net::CacheType cache_type, const SimpleIndexFile::IndexMetadata& index_metadata, const SimpleIndex::EntrySet& entries); @@ -148,7 +155,9 @@ // Given the contents of an index file |data| of length |data_len|, returns // the corresponding EntrySet. Returns NULL on error. - static void Deserialize(const char* data, int data_len, + static void Deserialize(net::CacheType cache_type, + const char* data, + int data_len, base::Time* out_cache_last_modified, SimpleIndexLoadResult* out_result);
diff --git a/net/disk_cache/simple/simple_index_file_unittest.cc b/net/disk_cache/simple/simple_index_file_unittest.cc index 5ce8e41c..fb1d903 100644 --- a/net/disk_cache/simple/simple_index_file_unittest.cc +++ b/net/disk_cache/simple/simple_index_file_unittest.cc
@@ -137,6 +137,16 @@ } }; +class V8IndexMetadataForTest : public SimpleIndexFile::IndexMetadata { + public: + V8IndexMetadataForTest(uint64_t entry_count, uint64_t cache_size) + : SimpleIndexFile::IndexMetadata(SimpleIndex::INDEX_WRITE_REASON_SHUTDOWN, + entry_count, + cache_size) { + version_ = 8; + } +}; + // This friend derived class is able to reexport its ancestors private methods // as public, for use in tests. class WrappedSimpleIndexFile : public SimpleIndexFile { @@ -174,6 +184,13 @@ a.entry_size_256b_chunks_ == b.entry_size_256b_chunks_ && a.in_memory_data_ == b.in_memory_data_; } + + bool CompareTwoAppCacheEntryMetadata(const EntryMetadata& a, + const EntryMetadata& b) { + return a.trailer_prefetch_size_ == b.trailer_prefetch_size_ && + a.entry_size_256b_chunks_ == b.entry_size_256b_chunks_ && + a.in_memory_data_ == b.in_memory_data_; + } }; TEST_F(SimpleIndexFileTest, Serialize) { @@ -194,17 +211,16 @@ SimpleIndex::InsertInEntrySet(hash, metadata_entries[i], &entries); } - std::unique_ptr<base::Pickle> pickle = - WrappedSimpleIndexFile::Serialize(index_metadata, entries); + std::unique_ptr<base::Pickle> pickle = WrappedSimpleIndexFile::Serialize( + net::DISK_CACHE, index_metadata, entries); EXPECT_TRUE(pickle.get() != NULL); base::Time now = base::Time::Now(); WrappedSimpleIndexFile::SerializeFinalData(now, pickle.get()); base::Time when_index_last_saw_cache; SimpleIndexLoadResult deserialize_result; - WrappedSimpleIndexFile::Deserialize(static_cast<const char*>(pickle->data()), - pickle->size(), - &when_index_last_saw_cache, - &deserialize_result); + WrappedSimpleIndexFile::Deserialize( + net::DISK_CACHE, static_cast<const char*>(pickle->data()), pickle->size(), + &when_index_last_saw_cache, &deserialize_result); EXPECT_TRUE(deserialize_result.did_load); EXPECT_EQ(now, when_index_last_saw_cache); const SimpleIndex::EntrySet& new_entries = deserialize_result.entries; @@ -217,6 +233,47 @@ } } +TEST_F(SimpleIndexFileTest, SerializeAppCache) { + SimpleIndex::EntrySet entries; + static const uint64_t kHashes[] = {11, 22, 33}; + static const size_t kNumHashes = base::size(kHashes); + static const int32_t kTrailerPrefetches[] = {123, -1, 987}; + EntryMetadata metadata_entries[kNumHashes]; + + SimpleIndexFile::IndexMetadata index_metadata( + SimpleIndex::INDEX_WRITE_REASON_SHUTDOWN, + static_cast<uint64_t>(kNumHashes), 456); + for (size_t i = 0; i < kNumHashes; ++i) { + uint64_t hash = kHashes[i]; + metadata_entries[i] = + EntryMetadata(kTrailerPrefetches[i], static_cast<uint32_t>(hash)); + metadata_entries[i].SetInMemoryData(static_cast<uint8_t>(i)); + SimpleIndex::InsertInEntrySet(hash, metadata_entries[i], &entries); + } + + std::unique_ptr<base::Pickle> pickle = WrappedSimpleIndexFile::Serialize( + net::APP_CACHE, index_metadata, entries); + EXPECT_TRUE(pickle.get() != NULL); + base::Time now = base::Time::Now(); + WrappedSimpleIndexFile::SerializeFinalData(now, pickle.get()); + base::Time when_index_last_saw_cache; + SimpleIndexLoadResult deserialize_result; + WrappedSimpleIndexFile::Deserialize( + net::APP_CACHE, static_cast<const char*>(pickle->data()), pickle->size(), + &when_index_last_saw_cache, &deserialize_result); + EXPECT_TRUE(deserialize_result.did_load); + EXPECT_EQ(now, when_index_last_saw_cache); + const SimpleIndex::EntrySet& new_entries = deserialize_result.entries; + EXPECT_EQ(entries.size(), new_entries.size()); + + for (size_t i = 0; i < kNumHashes; ++i) { + auto it = new_entries.find(kHashes[i]); + EXPECT_TRUE(new_entries.end() != it); + EXPECT_TRUE( + CompareTwoAppCacheEntryMetadata(it->second, metadata_entries[i])); + } +} + TEST_F(SimpleIndexFileTest, ReadV7Format) { static const uint64_t kHashes[] = {11, 22, 33}; static const uint32_t kSizes[] = {394, 594, 495940}; @@ -237,7 +294,7 @@ SimpleIndex::InsertInEntrySet(kHashes[i], entry, &entries); } std::unique_ptr<base::Pickle> pickle = - WrappedSimpleIndexFile::Serialize(v7_metadata, entries); + WrappedSimpleIndexFile::Serialize(net::DISK_CACHE, v7_metadata, entries); ASSERT_TRUE(pickle.get() != NULL); base::Time now = base::Time::Now(); WrappedSimpleIndexFile::SerializeFinalData(now, pickle.get()); @@ -246,7 +303,7 @@ base::Time when_index_last_saw_cache; SimpleIndexLoadResult deserialize_result; WrappedSimpleIndexFile::Deserialize( - static_cast<const char*>(pickle->data()), pickle->size(), + net::DISK_CACHE, static_cast<const char*>(pickle->data()), pickle->size(), &when_index_last_saw_cache, &deserialize_result); EXPECT_TRUE(deserialize_result.did_load); EXPECT_EQ(now, when_index_last_saw_cache); @@ -260,6 +317,100 @@ } } +TEST_F(SimpleIndexFileTest, ReadV8Format) { + static const uint64_t kHashes[] = {11, 22, 33}; + static const uint32_t kSizes[] = {394, 594, 495940}; + static_assert(base::size(kHashes) == base::size(kSizes), + "Need same number of hashes and sizes"); + static const size_t kNumHashes = base::size(kHashes); + + // V8 to V9 should not make any modifications for non-APP_CACHE modes. + // Verify that the data is preserved through the migration. + V8IndexMetadataForTest v8_metadata(kNumHashes, 100 * 1024 * 1024); + + EntryMetadata metadata_entries[kNumHashes]; + SimpleIndex::EntrySet entries; + for (size_t i = 0; i < kNumHashes; ++i) { + metadata_entries[i] = + EntryMetadata(base::Time::Now(), static_cast<uint32_t>(kHashes[i])); + metadata_entries[i].SetInMemoryData(static_cast<uint8_t>(i)); + SimpleIndex::InsertInEntrySet(kHashes[i], metadata_entries[i], &entries); + } + std::unique_ptr<base::Pickle> pickle = + WrappedSimpleIndexFile::Serialize(net::DISK_CACHE, v8_metadata, entries); + ASSERT_TRUE(pickle.get() != NULL); + base::Time now = base::Time::Now(); + WrappedSimpleIndexFile::SerializeFinalData(now, pickle.get()); + + base::Time when_index_last_saw_cache; + SimpleIndexLoadResult deserialize_result; + WrappedSimpleIndexFile::Deserialize( + net::DISK_CACHE, static_cast<const char*>(pickle->data()), pickle->size(), + &when_index_last_saw_cache, &deserialize_result); + EXPECT_TRUE(deserialize_result.did_load); + EXPECT_EQ(now, when_index_last_saw_cache); + const SimpleIndex::EntrySet& new_entries = deserialize_result.entries; + ASSERT_EQ(entries.size(), new_entries.size()); + for (size_t i = 0; i < kNumHashes; ++i) { + auto it = new_entries.find(kHashes[i]); + ASSERT_TRUE(new_entries.end() != it); + EXPECT_TRUE(CompareTwoEntryMetadata(it->second, metadata_entries[i])); + } +} + +TEST_F(SimpleIndexFileTest, ReadV8FormatAppCache) { + static const uint64_t kHashes[] = {11, 22, 33}; + static const uint32_t kSizes[] = {394, 594, 495940}; + static_assert(base::size(kHashes) == base::size(kSizes), + "Need same number of hashes and sizes"); + static const size_t kNumHashes = base::size(kHashes); + + // To simulate an upgrade from v8 to v9 write out the v8 schema + // using DISK_CACHE mode. The read it back in in APP_CACHE mode. + // The entry access time data should be zeroed to reset it as the + // new trailer prefetch size. + V8IndexMetadataForTest v8_metadata(kNumHashes, 100 * 1024 * 1024); + + EntryMetadata metadata_entries[kNumHashes]; + SimpleIndex::EntrySet entries; + for (size_t i = 0; i < kNumHashes; ++i) { + metadata_entries[i] = + EntryMetadata(base::Time::Now(), static_cast<uint32_t>(kHashes[i])); + metadata_entries[i].SetInMemoryData(static_cast<uint8_t>(i)); + SimpleIndex::InsertInEntrySet(kHashes[i], metadata_entries[i], &entries); + } + std::unique_ptr<base::Pickle> pickle = + WrappedSimpleIndexFile::Serialize(net::DISK_CACHE, v8_metadata, entries); + ASSERT_TRUE(pickle.get() != NULL); + base::Time now = base::Time::Now(); + WrappedSimpleIndexFile::SerializeFinalData(now, pickle.get()); + + // Deserialize using APP_CACHE mode. This should zero out the + // trailer_prefetch_size_ instead of using the time bits written + // out previously. + base::Time when_index_last_saw_cache; + SimpleIndexLoadResult deserialize_result; + WrappedSimpleIndexFile::Deserialize( + net::APP_CACHE, static_cast<const char*>(pickle->data()), pickle->size(), + &when_index_last_saw_cache, &deserialize_result); + EXPECT_TRUE(deserialize_result.did_load); + EXPECT_EQ(now, when_index_last_saw_cache); + const SimpleIndex::EntrySet& new_entries = deserialize_result.entries; + ASSERT_EQ(entries.size(), new_entries.size()); + for (size_t i = 0; i < kNumHashes; ++i) { + auto it = new_entries.find(kHashes[i]); + ASSERT_TRUE(new_entries.end() != it); + // The trailer prefetch size should be zeroed. + EXPECT_NE(metadata_entries[i].trailer_prefetch_size_, + it->second.trailer_prefetch_size_); + EXPECT_EQ(0, it->second.trailer_prefetch_size_); + // Other data should be unaffected. + EXPECT_EQ(metadata_entries[i].entry_size_256b_chunks_, + it->second.entry_size_256b_chunks_); + EXPECT_EQ(metadata_entries[i].in_memory_data_, it->second.in_memory_data_); + } +} + TEST_F(SimpleIndexFileTest, LegacyIsIndexFileStale) { base::ScopedTempDir cache_dir; ASSERT_TRUE(cache_dir.CreateUniqueTempDir()); @@ -311,9 +462,9 @@ net::TestClosure closure; { WrappedSimpleIndexFile simple_index_file(cache_dir.GetPath()); - simple_index_file.WriteToDisk(SimpleIndex::INDEX_WRITE_REASON_SHUTDOWN, - entries, kCacheSize, base::TimeTicks(), false, - closure.closure()); + simple_index_file.WriteToDisk( + net::DISK_CACHE, SimpleIndex::INDEX_WRITE_REASON_SHUTDOWN, entries, + kCacheSize, base::TimeTicks(), false, closure.closure()); closure.WaitForResult(); EXPECT_TRUE(base::PathExists(simple_index_file.GetIndexFilePath())); } @@ -459,10 +610,9 @@ EXPECT_TRUE(base::ReadFileToString(index_file_path, &contents)); base::Time when_index_last_saw_cache; SimpleIndexLoadResult deserialize_result; - WrappedSimpleIndexFile::Deserialize(contents.data(), - contents.size(), - &when_index_last_saw_cache, - &deserialize_result); + WrappedSimpleIndexFile::Deserialize( + net::DISK_CACHE, contents.data(), contents.size(), + &when_index_last_saw_cache, &deserialize_result); EXPECT_TRUE(deserialize_result.did_load); } @@ -486,9 +636,9 @@ SimpleIndex::EntrySet entries; SimpleIndex::InsertInEntrySet(11, EntryMetadata(Time(), 11u), &entries); net::TestClosure closure; - simple_index_file.WriteToDisk(SimpleIndex::INDEX_WRITE_REASON_SHUTDOWN, - entries, 120U, base::TimeTicks(), false, - closure.closure()); + simple_index_file.WriteToDisk( + net::DISK_CACHE, SimpleIndex::INDEX_WRITE_REASON_SHUTDOWN, entries, 120U, + base::TimeTicks(), false, closure.closure()); closure.WaitForResult(); // Check that the temporary file was deleted and the index file was created.
diff --git a/net/disk_cache/simple/simple_index_unittest.cc b/net/disk_cache/simple/simple_index_unittest.cc index 91dbbda..faf323d 100644 --- a/net/disk_cache/simple/simple_index_unittest.cc +++ b/net/disk_cache/simple/simple_index_unittest.cc
@@ -80,7 +80,8 @@ ++load_index_entries_calls_; } - void WriteToDisk(SimpleIndex::IndexWriteToDiskReason reason, + void WriteToDisk(net::CacheType cache_type, + SimpleIndex::IndexWriteToDiskReason reason, const SimpleIndex::EntrySet& entry_set, uint64_t cache_size, const base::TimeTicks& start, @@ -237,11 +238,11 @@ EntryMetadata entry_metadata = NewEntryMetadataWithValues(); base::Pickle pickle; - entry_metadata.Serialize(&pickle); + entry_metadata.Serialize(net::DISK_CACHE, &pickle); base::PickleIterator it(pickle); EntryMetadata new_entry_metadata; - new_entry_metadata.Deserialize(&it, true); + new_entry_metadata.Deserialize(net::DISK_CACHE, &it, true, true); CheckEntryMetadataValues(new_entry_metadata); // Test reading of old format --- the modern serialization of above entry @@ -250,7 +251,7 @@ // rounded again when stored by EntryMetadata. base::PickleIterator it2(pickle); EntryMetadata new_entry_metadata2; - new_entry_metadata2.Deserialize(&it2, false); + new_entry_metadata2.Deserialize(net::DISK_CACHE, &it2, false, false); EXPECT_EQ(RoundSize(RoundSize(kTestEntrySize) | kTestEntryMemoryData), new_entry_metadata2.GetEntrySize()); EXPECT_EQ(0, new_entry_metadata2.GetInMemoryData());
diff --git a/net/disk_cache/simple/simple_synchronous_entry.cc b/net/disk_cache/simple/simple_synchronous_entry.cc index 01b7580..fdb9dee8 100644 --- a/net/disk_cache/simple/simple_synchronous_entry.cc +++ b/net/disk_cache/simple/simple_synchronous_entry.cc
@@ -10,6 +10,7 @@ #include <limits> #include "base/compiler_specific.h" +#include "base/containers/stack_container.h" #include "base/files/file_util.h" #include "base/hash.h" #include "base/location.h" @@ -76,8 +77,9 @@ static_cast<int>(KeySHA256Result::MAX)); } -void RecordWhetherOpenDidPrefetch(net::CacheType cache_type, bool result) { - SIMPLE_CACHE_UMA(BOOLEAN, "SyncOpenDidPrefetch", cache_type, result); +void RecordOpenPrefetchMode(net::CacheType cache_type, OpenPrefetchMode mode) { + SIMPLE_CACHE_UMA(ENUMERATION, "SyncOpenPrefetchMode", cache_type, mode, + OPEN_PREFETCH_MAX); } bool CanOmitEmptyFile(int file_index) { @@ -119,6 +121,85 @@ } // namespace +// Helper class to track a range of data prefetched from a file. +class SimpleSynchronousEntry::PrefetchData final { + public: + explicit PrefetchData(size_t file_size) + : file_size_(file_size), + offset_in_file_(0), + earliest_requested_offset_(file_size) {} + + // Returns true if the specified range within the file has been completely + // prefetched. Returns false if any part of the range has not been + // prefetched. + bool HasData(size_t offset, size_t length) { + size_t end = 0; + if (!base::CheckAdd(offset, length).AssignIfValid(&end)) + return false; + UpdateEarliestOffset(offset); + return offset >= offset_in_file_ && + end <= (offset_in_file_ + buffer_->size()); + } + + // Read the given range out of the prefetch buffer into the target + // destination buffer. If the range is not wholely contained within + // the prefetch buffer than no data will be written to the target + // buffer. Returns true if the range has been copied. + bool ReadData(size_t offset, size_t length, char* dest) { + DCHECK(dest); + if (!length) + return true; + if (!HasData(offset, length)) + return false; + DCHECK(offset >= offset_in_file_); + size_t buffer_offset = offset - offset_in_file_; + memcpy(dest, buffer_->data() + buffer_offset, length); + return true; + } + + // Populate the prefetch buffer from the given file and range. Returns + // true if the data is successfully read. + bool PrefetchFromFile(SimpleFileTracker::FileHandle* file, + size_t offset, + size_t length) { + DCHECK(file); + if (!buffer_->empty()) + return false; + buffer_->resize(length); + if (file->get()->Read(offset, buffer_->data(), length) != + static_cast<int>(length)) { + buffer_->resize(0); + return false; + } + offset_in_file_ = offset; + return true; + } + + // Return how much trailing data has been requested via HasData() or + // ReadData(). The intent is that this value can be used to tune + // future prefetching behavior. + size_t GetDesiredTrailerPrefetchSize() const { + return file_size_ - earliest_requested_offset_; + } + + private: + // Track the earliest offset requested in order to return an optimal trailer + // prefetch amount in GetDesiredTrailerPrefetchSize(). + void UpdateEarliestOffset(size_t offset) { + DCHECK_LE(earliest_requested_offset_, file_size_); + earliest_requested_offset_ = std::min(earliest_requested_offset_, offset); + } + + const size_t file_size_; + + // Prefer to read the prefetch data into a stack buffer to minimize + // memory pressure on the OS disk cache. + base::StackVector<char, 1024> buffer_; + size_t offset_in_file_; + + size_t earliest_requested_offset_; +}; + using simple_util::GetEntryHashKey; using simple_util::GetFilenameFromEntryFileKeyAndFileIndex; using simple_util::GetSparseFilenameFromEntryFileKey; @@ -128,12 +209,31 @@ using simple_util::GetFileIndexFromStreamIndex; const base::Feature kSimpleCachePrefetchExperiment = { - "SimpleCachePrefetchExperiment", base::FEATURE_DISABLED_BY_DEFAULT}; -const char kSimplePrefetchBytesParam[] = "Bytes"; + "SimpleCachePrefetchExperiment2", base::FEATURE_DISABLED_BY_DEFAULT}; -int GetSimpleCachePrefetchSize() { - return base::GetFieldTrialParamByFeatureAsInt(kSimpleCachePrefetchExperiment, - kSimplePrefetchBytesParam, 0); +const char kSimpleCacheFullPrefetchBytesParam[] = "FullPrefetchBytes"; +constexpr base::FeatureParam<int> kSimpleCacheFullPrefetchSize{ + &kSimpleCachePrefetchExperiment, kSimpleCacheFullPrefetchBytesParam, 0}; + +const char kSimpleCacheTrailerPrefetchHintParam[] = "TrailerPrefetchHint"; +constexpr base::FeatureParam<bool> kSimpleCacheTrailerPrefetchHint{ + &kSimpleCachePrefetchExperiment, kSimpleCacheTrailerPrefetchHintParam, + false}; + +const char kSimpleCacheTrailerPrefetchSpeculativeBytesParam[] = + "TrailerPrefetchSpeculativeBytes"; +constexpr base::FeatureParam<int> kSimpleCacheTrailerPrefetchSpeculativeBytes{ + &kSimpleCachePrefetchExperiment, + kSimpleCacheTrailerPrefetchSpeculativeBytesParam, 0}; + +int GetSimpleCacheFullPrefetchSize() { + return kSimpleCacheFullPrefetchSize.Get(); +} + +int GetSimpleCacheTrailerPrefetchSize(int hint_size) { + if (kSimpleCacheTrailerPrefetchHint.Get() && hint_size > 0) + return hint_size; + return kSimpleCacheTrailerPrefetchSpeculativeBytes.Get(); } SimpleEntryStat::SimpleEntryStat(base::Time last_used, @@ -245,13 +345,15 @@ const bool had_index, const base::TimeTicks& time_enqueued, SimpleFileTracker* file_tracker, + int32_t trailer_prefetch_size, SimpleEntryCreationResults* out_results) { base::TimeTicks start_sync_open_entry = base::TimeTicks::Now(); SIMPLE_CACHE_UMA(TIMES, "QueueLatency.OpenEntry", cache_type, (start_sync_open_entry - time_enqueued)); - SimpleSynchronousEntry* sync_entry = new SimpleSynchronousEntry( - cache_type, path, key, entry_hash, had_index, file_tracker); + SimpleSynchronousEntry* sync_entry = + new SimpleSynchronousEntry(cache_type, path, key, entry_hash, had_index, + file_tracker, trailer_prefetch_size); out_results->result = sync_entry->InitializeForOpen( &out_results->entry_stat, out_results->stream_prefetch_data); if (out_results->result != net::OK) { @@ -265,6 +367,8 @@ SIMPLE_CACHE_UMA(TIMES, "DiskOpenLatency", cache_type, base::TimeTicks::Now() - start_sync_open_entry); out_results->sync_entry = sync_entry; + out_results->computed_trailer_prefetch_size = + sync_entry->computed_trailer_prefetch_size(); } // static @@ -283,7 +387,7 @@ (start_sync_create_entry - time_enqueued)); SimpleSynchronousEntry* sync_entry = new SimpleSynchronousEntry( - cache_type, path, key, entry_hash, had_index, file_tracker); + cache_type, path, key, entry_hash, had_index, file_tracker, -1); out_results->result = sync_entry->InitializeForCreate(&out_results->entry_stat); if (out_results->result != net::OK) { @@ -778,8 +882,8 @@ SimpleFileEOF eof_record; int file_offset = entry_stat.GetEOFOffsetInFile(key_.size(), stream_index); int file_index = GetFileIndexFromStreamIndex(stream_index); - int rv = GetEOFRecordData(file, base::StringPiece(), file_index, file_offset, - &eof_record); + int rv = + GetEOFRecordData(file, nullptr, file_index, file_offset, &eof_record); if (rv != net::OK) { Doom(); @@ -798,7 +902,7 @@ int SimpleSynchronousEntry::PreReadStreamPayload( base::File* file, - base::StringPiece file_0_prefetch, + PrefetchData* prefetch_data, int stream_index, int extra_size, const SimpleEntryStat& entry_stat, @@ -811,8 +915,8 @@ out->data = base::MakeRefCounted<net::GrowableIOBuffer>(); out->data->SetCapacity(read_size); int file_offset = entry_stat.GetOffsetInFile(key_.size(), 0, stream_index); - if (!ReadFromFileOrPrefetched(file, file_0_prefetch, 0, file_offset, - read_size, out->data->data())) + if (!ReadFromFileOrPrefetched(file, prefetch_data, 0, file_offset, read_size, + out->data->data())) return net::ERR_FAILED; // Check the CRC32. @@ -831,7 +935,8 @@ void SimpleSynchronousEntry::Close( const SimpleEntryStat& entry_stat, std::unique_ptr<std::vector<CRCRecord>> crc32s_to_write, - net::GrowableIOBuffer* stream_0_data) { + net::GrowableIOBuffer* stream_0_data, + SimpleEntryCloseResults* out_results) { base::ElapsedTimer close_time; DCHECK(stream_0_data); @@ -876,6 +981,9 @@ simple_util::Crc32(stream_0_data->data(), entry_stat.data_size(0)); it->has_crc32 = true; } + + out_results->estimated_trailer_prefetch_size = + entry_stat.data_size(0) + sizeof(hash_value) + sizeof(SimpleFileEOF); } SimpleFileEOF eof_record; @@ -934,7 +1042,8 @@ const std::string& key, const uint64_t entry_hash, const bool had_index, - SimpleFileTracker* file_tracker) + SimpleFileTracker* file_tracker, + int32_t trailer_prefetch_size) : cache_type_(cache_type), path_(path), entry_file_key_(entry_hash), @@ -943,6 +1052,8 @@ have_open_files_(false), initialized_(false), file_tracker_(file_tracker), + trailer_prefetch_size_(trailer_prefetch_size), + computed_trailer_prefetch_size_(-1), sparse_file_open_(false) { for (int i = 0; i < kSimpleEntryNormalFileCount; ++i) empty_file_omitted_[i] = false; @@ -1383,27 +1494,56 @@ if (!file.IsOK()) return net::ERR_FAILED; - // If the file is sufficiently small, we will prefetch everything -- - // in which case |prefetch_buf| will be non-null, and we should look at it - // rather than call ::Read for the bits. - std::unique_ptr<char[]> prefetch_buf; - base::StringPiece file_0_prefetch; + // We may prefetch data from file in a couple cases: + // 1) If the file is small enough we may prefetch it entirely. + // 2) We may also prefetch a block of trailer bytes from the end of + // the file. + // In these cases the PrefetchData object is used to store the + // bytes read from the file. The PrefetchData object also keeps track + // of what range within the file has been prefetched. It will only + // allow reads wholely within this range to be accessed via its + // ReadData() method. + PrefetchData prefetch_data(file_size); - if (file_size > GetSimpleCachePrefetchSize()) { - RecordWhetherOpenDidPrefetch(cache_type_, false); - } else { - RecordWhetherOpenDidPrefetch(cache_type_, true); - prefetch_buf = std::make_unique<char[]>(file_size); - if (file->Read(0, prefetch_buf.get(), file_size) != file_size) + // Determine a threshold for fully prefetching the entire entry file. If + // the entry file is less than or equal to this number of bytes it will + // be fully prefetched. + int full_prefetch_size = GetSimpleCacheFullPrefetchSize(); + + // Determine how much trailer data to prefetch. If the full file prefetch + // does not trigger then this is the number of bytes to read from the end + // of the file in a single file operation. Ideally the trailer prefetch + // will contain at least stream 0 and its EOF record. + int trailer_prefetch_size = + GetSimpleCacheTrailerPrefetchSize(trailer_prefetch_size_); + + OpenPrefetchMode prefetch_mode = OPEN_PREFETCH_NONE; + if (file_size <= full_prefetch_size || file_size <= trailer_prefetch_size) { + // Prefetch the entire file. + prefetch_mode = OPEN_PREFETCH_FULL; + RecordOpenPrefetchMode(cache_type_, prefetch_mode); + if (!prefetch_data.PrefetchFromFile(&file, 0, file_size)) return net::ERR_FAILED; - file_0_prefetch.set(prefetch_buf.get(), file_size); + } else if (trailer_prefetch_size > 0) { + // Prefetch trailer data from the end of the file. + prefetch_mode = OPEN_PREFETCH_TRAILER; + RecordOpenPrefetchMode(cache_type_, prefetch_mode); + size_t length = std::min(trailer_prefetch_size, file_size); + size_t offset = file_size - length; + if (!prefetch_data.PrefetchFromFile(&file, offset, length)) + return net::ERR_FAILED; + SIMPLE_CACHE_UMA(COUNTS_100000, "EntryTrailerPrefetchSize", cache_type_, + trailer_prefetch_size); + } else { + // Do no prefetching. + RecordOpenPrefetchMode(cache_type_, prefetch_mode); } // Read stream 0 footer first --- it has size/feature info required to figure // out file 0's layout. SimpleFileEOF stream_0_eof; int rv = GetEOFRecordData( - file.get(), file_0_prefetch, /* file_index = */ 0, + file.get(), &prefetch_data, /* file_index = */ 0, /* file_offset = */ file_size - sizeof(SimpleFileEOF), &stream_0_eof); if (rv != net::OK) return rv; @@ -1431,24 +1571,45 @@ out_entry_stat->set_data_size(1, stream1_size); // Put stream 0 data in memory --- plus maybe the sha256(key) footer. - rv = PreReadStreamPayload(file.get(), file_0_prefetch, /* stream_index = */ 0, + rv = PreReadStreamPayload(file.get(), &prefetch_data, /* stream_index = */ 0, extra_post_stream_0_read, *out_entry_stat, stream_0_eof, &stream_prefetch_data[0]); if (rv != net::OK) return rv; + // Note the exact range needed in order to read the EOF record and stream 0. + // In APP_CACHE mode this will be stored directly in the index so we can + // know exactly how much to read next time. Its also reported in a histogram + // so we can tune the speculative trailer prefetching experiment. + computed_trailer_prefetch_size_ = + prefetch_data.GetDesiredTrailerPrefetchSize(); + SIMPLE_CACHE_UMA(COUNTS_100000, "EntryTrailerSize", cache_type_, + computed_trailer_prefetch_size_); + + // If we performed a trailer prefetch, record how accurate the prefetch was + // compared to the ideal value. + if (prefetch_mode == OPEN_PREFETCH_TRAILER) { + SIMPLE_CACHE_UMA(COUNTS_100000, "EntryTrailerPrefetchDelta", cache_type_, + (trailer_prefetch_size - computed_trailer_prefetch_size_)); + } + // If prefetch buffer is available, and we have sha256(key) (so we don't need // to look at the header), extract out stream 1 info as well. - if (prefetch_buf && has_key_sha256) { + int stream_1_offset = out_entry_stat->GetOffsetInFile( + key_.size(), /* offset= */ 0, /* stream_index = */ 1); + int stream_1_read_size = + sizeof(SimpleFileEOF) + out_entry_stat->data_size(/* stream_index = */ 1); + if (has_key_sha256 && + prefetch_data.HasData(stream_1_offset, stream_1_read_size)) { SimpleFileEOF stream_1_eof; - rv = GetEOFRecordData( - file.get(), file_0_prefetch, /* file_index = */ 0, - out_entry_stat->GetEOFOffsetInFile(key_.size(), /* stream_index = */ 1), - &stream_1_eof); + int stream_1_eof_offset = + out_entry_stat->GetEOFOffsetInFile(key_.size(), /* stream_index = */ 1); + rv = GetEOFRecordData(file.get(), &prefetch_data, /* file_index = */ 0, + stream_1_eof_offset, &stream_1_eof); if (rv != net::OK) return rv; - rv = PreReadStreamPayload(file.get(), file_0_prefetch, + rv = PreReadStreamPayload(file.get(), &prefetch_data, /* stream_index = */ 1, /* extra_size = */ 0, *out_entry_stat, stream_1_eof, &stream_prefetch_data[1]); @@ -1484,42 +1645,42 @@ bool SimpleSynchronousEntry::ReadFromFileOrPrefetched( base::File* file, - base::StringPiece file_0_prefetch, + PrefetchData* prefetch_data, int file_index, int offset, int size, char* dest) { - if (file_0_prefetch.empty() || file_index != 0) { - return file->Read(offset, dest, size) == size; - } else { - if (offset < 0 || size < 0) - return false; - if (size == 0) - return true; + if (offset < 0 || size < 0) + return false; + if (size == 0) + return true; - base::CheckedNumeric<size_t> start(offset); - size_t start_numeric; - if (!start.AssignIfValid(&start_numeric) || - start_numeric >= file_0_prefetch.size()) - return false; + base::CheckedNumeric<size_t> start(offset); + size_t start_numeric; + if (!start.AssignIfValid(&start_numeric)) + return false; - base::CheckedNumeric<size_t> end = start + size - 1; - size_t end_numeric; - if (!end.AssignIfValid(&end_numeric) || - end_numeric >= file_0_prefetch.size()) - return false; + base::CheckedNumeric<size_t> length(size); + size_t length_numeric; + if (!length.AssignIfValid(&length_numeric)) + return false; - memcpy(dest, file_0_prefetch.data() + offset, size); + // First try to extract the desired range from the PrefetchData. + if (file_index == 0 && prefetch_data && + prefetch_data->ReadData(start_numeric, length_numeric, dest)) { return true; } + + // If we have not prefetched the range then we must read it from disk. + return file->Read(start_numeric, dest, length_numeric) == size; } int SimpleSynchronousEntry::GetEOFRecordData(base::File* file, - base::StringPiece file_0_prefetch, + PrefetchData* prefetch_data, int file_index, int file_offset, SimpleFileEOF* eof_record) { - if (!ReadFromFileOrPrefetched(file, file_0_prefetch, file_index, file_offset, + if (!ReadFromFileOrPrefetched(file, prefetch_data, file_index, file_offset, sizeof(SimpleFileEOF), reinterpret_cast<char*>(eof_record))) { RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_READ_FAILURE);
diff --git a/net/disk_cache/simple/simple_synchronous_entry.h b/net/disk_cache/simple/simple_synchronous_entry.h index 6fbd928..d62e716 100644 --- a/net/disk_cache/simple/simple_synchronous_entry.h +++ b/net/disk_cache/simple/simple_synchronous_entry.h
@@ -36,7 +36,10 @@ namespace disk_cache { NET_EXPORT_PRIVATE extern const base::Feature kSimpleCachePrefetchExperiment; -NET_EXPORT_PRIVATE extern const char kSimplePrefetchBytesParam[]; +NET_EXPORT_PRIVATE extern const char kSimpleCacheFullPrefetchBytesParam[]; +NET_EXPORT_PRIVATE extern const char kSimpleCacheTrailerPrefetchHintParam[]; +NET_EXPORT_PRIVATE extern const char + kSimpleCacheTrailerPrefetchSpeculativeBytesParam[]; // Returns how large a file would get prefetched on reading the entry. // If the experiment is disabled, returns 0. @@ -101,9 +104,14 @@ SimpleStreamPrefetchData stream_prefetch_data[2]; SimpleEntryStat entry_stat; + int32_t computed_trailer_prefetch_size = -1; int result; }; +struct SimpleEntryCloseResults { + int32_t estimated_trailer_prefetch_size = -1; +}; + // Worker thread interface to the very simple cache. This interface is not // thread safe, and callers must ensure that it is only ever accessed from // a single thread between synchronization points. @@ -187,6 +195,7 @@ bool had_index, const base::TimeTicks& time_enqueued, SimpleFileTracker* file_tracker, + int32_t trailer_prefetch_size, SimpleEntryCreationResults* out_results); static void CreateEntry(net::CacheType cache_type, @@ -259,7 +268,8 @@ // CRCRecord entries in |crc32s_to_write|. void Close(const SimpleEntryStat& entry_stat, std::unique_ptr<std::vector<CRCRecord>> crc32s_to_write, - net::GrowableIOBuffer* stream_0_data); + net::GrowableIOBuffer* stream_0_data, + SimpleEntryCloseResults* out_results); const base::FilePath& path() const { return path_; } std::string key() const { return key_; } @@ -270,10 +280,15 @@ NET_EXPORT_PRIVATE base::FilePath GetFilenameForSubfile( SimpleFileTracker::SubFile sub_file) const; + int32_t computed_trailer_prefetch_size() const { + return computed_trailer_prefetch_size_; + } + private: FRIEND_TEST_ALL_PREFIXES(::DiskCacheBackendTest, SimpleCacheEnumerationLongKeys); friend class SimpleFileTrackerTest; + class PrefetchData; enum CreateEntryResult { CREATE_ENTRY_SUCCESS = 0, @@ -310,7 +325,8 @@ const std::string& key, uint64_t entry_hash, bool had_index, - SimpleFileTracker* simple_file_tracker); + SimpleFileTracker* simple_file_tracker, + int32_t stream_0_size); // Like Entry, the SimpleSynchronousEntry self releases when Close() is // called. @@ -364,7 +380,7 @@ // Puts the result into |*eof_record| and sanity-checks it. // Returns net status, and records any failures to UMA. int GetEOFRecordData(base::File* file, - base::StringPiece file_0_prefetch, + PrefetchData* prefetch_data, int file_index, int file_offset, SimpleFileEOF* eof_record); @@ -372,7 +388,7 @@ // Reads either from |file_0_prefetch| or |file|. // Range-checks all the in-memory reads. bool ReadFromFileOrPrefetched(base::File* file, - base::StringPiece file_0_prefetch, + PrefetchData* prefetch_data, int file_index, int offset, int size, @@ -387,7 +403,7 @@ // and |*out_crc32| will get the checksum, which will be verified against // |eof_record|. int PreReadStreamPayload(base::File* file, - base::StringPiece file_0_prefetch, + PrefetchData* prefetch_data, int stream_index, int extra_size, const SimpleEntryStat& entry_stat, @@ -468,6 +484,18 @@ SimpleFileTracker* file_tracker_; + // The number of trailing bytes in file 0 that we believe should be + // prefetched in order to read the EOF record and stream 0. This is + // a hint from the index and may not be exactly right. -1 if we + // don't have a hinted value. + int32_t trailer_prefetch_size_; + + // The exact number of trailing bytes that were needed to read the + // EOF record and stream 0 when the entry was actually opened. This + // may be different from the trailer_prefetch_size_ hint and is + // propagated back to the index in order to optimize the next open. + int32_t computed_trailer_prefetch_size_; + // True if the corresponding stream is empty and therefore no on-disk file // was created to store it. bool empty_file_omitted_[kSimpleEntryNormalFileCount];
diff --git a/net/disk_cache/simple/simple_version_upgrade.cc b/net/disk_cache/simple/simple_version_upgrade.cc index efcd3d7..559edb6 100644 --- a/net/disk_cache/simple/simple_version_upgrade.cc +++ b/net/disk_cache/simple/simple_version_upgrade.cc
@@ -209,6 +209,11 @@ version_from++; } + if (version_from == 8) { + // Likewise, V8 -> V9 is handled entirely by the index reader. + version_from++; + } + DCHECK_EQ(kSimpleVersion, version_from); if (!new_fake_index_needed)
diff --git a/net/quic/quic_test_packet_maker.cc b/net/quic/quic_test_packet_maker.cc index fae7542..65175fe 100644 --- a/net/quic/quic_test_packet_maker.cc +++ b/net/quic/quic_test_packet_maker.cc
@@ -212,9 +212,20 @@ header.packet_number_length = GetPacketNumberLength(); header.packet_number = num; + quic::QuicFrames frames; + quic::QuicRstStreamFrame rst(1, stream_id, error_code, bytes_written); - DVLOG(1) << "Adding frame: " << quic::QuicFrame(&rst); - return MakePacket(header, quic::QuicFrame(&rst)); + frames.push_back(quic::QuicFrame(&rst)); + DVLOG(1) << "Adding frame: " << frames.back(); + + // The STOP_SENDING frame must be outside of the if (version==99) so that it + // stays in scope until the packet is built. + quic::QuicStopSendingFrame stop(1, stream_id, error_code); + if (version_ == quic::QUIC_VERSION_99) { + frames.push_back(quic::QuicFrame(&stop)); + DVLOG(1) << "Adding frame: " << frames.back(); + } + return MakeMultipleFramesPacket(header, frames); } std::unique_ptr<quic::QuicReceivedPacket> @@ -289,6 +300,14 @@ quic::QuicFrames frames; frames.push_back(quic::QuicFrame(&rst_frame)); DVLOG(1) << "Adding frame: " << frames.back(); + + // The STOP_SENDING frame must be outside of the if (version==99) so that it + // stays in scope until the packet is built. + quic::QuicStopSendingFrame stop(1, rst_stream_id, rst_error_code); + if (version_ == quic::QUIC_VERSION_99) { + frames.push_back(quic::QuicFrame(&stop)); + DVLOG(1) << "Adding frame: " << frames.back(); + } frames.push_back(quic::QuicFrame(headers_frame)); DVLOG(1) << "Adding frame: " << frames.back(); @@ -357,6 +376,14 @@ frames.push_back(quic::QuicFrame(&rst)); DVLOG(1) << "Adding frame: " << frames.back(); + // The STOP_SENDING frame must be outside of the if (version==99) so that it + // stays in scope until the packet is built. + quic::QuicStopSendingFrame stop(1, stream_id, error_code); + if (version_ == quic::QUIC_VERSION_99) { + frames.push_back(quic::QuicFrame(&stop)); + DVLOG(1) << "Adding frame: " << frames.back(); + } + return MakeMultipleFramesPacket(header, frames); } @@ -388,6 +415,15 @@ frames.push_back(quic::QuicFrame(&rst)); DVLOG(1) << "Adding frame: " << frames.back(); + // The STOP_SENDING frame must be outside of the if (version==99) so that it + // stays in scope until the packet is built. + quic::QuicStopSendingFrame stop( + 1, stream_id, static_cast<quic::QuicApplicationErrorCode>(error_code)); + if (version_ == quic::QUIC_VERSION_99) { + frames.push_back(quic::QuicFrame(&stop)); + DVLOG(1) << "Adding frame: " << frames.back(); + } + quic::QuicAckFrame ack(MakeAckFrame(largest_received)); ack.ack_delay_time = ack_delay_time; for (quic::QuicPacketNumber i = smallest_received; i <= largest_received; @@ -829,6 +865,14 @@ frames.push_back(quic::QuicFrame(&rst_frame)); DVLOG(1) << "Adding frame: " << frames.back(); + // The STOP_SENDING frame must be outside of the if (version==99) so that it + // stays in scope until the packet is built. + quic::QuicStopSendingFrame stop(1, stream_id, error_code); + if (version_ == quic::QUIC_VERSION_99) { + frames.push_back(quic::QuicFrame(&stop)); + DVLOG(1) << "Adding frame: " << frames.back(); + } + InitializeHeader(packet_number, should_include_version); return MakeMultipleFramesPacket(header_, frames); }
diff --git a/net/third_party/quic/core/frames/quic_stop_sending_frame.h b/net/third_party/quic/core/frames/quic_stop_sending_frame.h index 52c1931b..0ce9393 100644 --- a/net/third_party/quic/core/frames/quic_stop_sending_frame.h +++ b/net/third_party/quic/core/frames/quic_stop_sending_frame.h
@@ -16,7 +16,7 @@ QuicStopSendingFrame(); QuicStopSendingFrame(QuicControlFrameId control_frame_id, QuicStreamId stream_id, - uint16_t application_error_code); + QuicApplicationErrorCode application_error_code); friend QUIC_EXPORT_PRIVATE std::ostream& operator<<( std::ostream& os,
diff --git a/net/third_party/quic/core/http/quic_spdy_session_test.cc b/net/third_party/quic/core/http/quic_spdy_session_test.cc index 0674c3f..a5d2716 100644 --- a/net/third_party/quic/core/http/quic_spdy_session_test.cc +++ b/net/third_party/quic/core/http/quic_spdy_session_test.cc
@@ -342,8 +342,15 @@ } void CloseStream(QuicStreamId id) { - EXPECT_CALL(*connection_, SendControlFrame(_)) - .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame)); + if (transport_version() != QUIC_VERSION_99) { + EXPECT_CALL(*connection_, SendControlFrame(_)) + .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame)); + } else { + // V99 has two frames, RST_STREAM and STOP_SENDING + EXPECT_CALL(*connection_, SendControlFrame(_)) + .Times(2) + .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame)); + } EXPECT_CALL(*connection_, OnStreamReset(id, _)); session_.CloseStream(id); closed_streams_.insert(id); @@ -1207,9 +1214,16 @@ const QuicStreamOffset kByteOffset = 1 + kInitialSessionFlowControlWindowForTest / 2; - EXPECT_CALL(*connection_, SendControlFrame(_)) - .Times(2) - .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame)); + if (transport_version() != QUIC_VERSION_99) { + EXPECT_CALL(*connection_, SendControlFrame(_)) + .Times(2) + .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame)); + } else { + // V99 has an additional, STOP_SENDING, frame. + EXPECT_CALL(*connection_, SendControlFrame(_)) + .Times(3) + .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame)); + } EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _)); QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(), QUIC_STREAM_CANCELLED, kByteOffset); @@ -1415,8 +1429,15 @@ QuicStreamFrame data1(i, false, 0, QuicStringPiece("HT")); session_.OnStreamFrame(data1); // EXPECT_EQ(1u, session_.GetNumOpenStreams()); - EXPECT_CALL(*connection_, SendControlFrame(_)) - .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame)); + if (transport_version() != QUIC_VERSION_99) { + EXPECT_CALL(*connection_, SendControlFrame(_)) + .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame)); + } else { + // V99 has two frames, RST_STREAM and STOP_SENDING + EXPECT_CALL(*connection_, SendControlFrame(_)) + .Times(2) + .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame)); + } // Close the stream only if not version 99. If we are version 99 // then closing the stream opens up the available stream id space, // so we never bump into the limit.
diff --git a/net/third_party/quic/core/quic_control_frame_manager.cc b/net/third_party/quic/core/quic_control_frame_manager.cc index e1fa368b..78481582 100644 --- a/net/third_party/quic/core/quic_control_frame_manager.cc +++ b/net/third_party/quic/core/quic_control_frame_manager.cc
@@ -90,6 +90,25 @@ QuicFrame(QuicMaxStreamIdFrame(++last_control_frame_id_, id))); } +void QuicControlFrameManager::WriteOrBufferRstStreamStopSending( + QuicStreamId stream_id, + QuicRstStreamErrorCode error_code, + QuicStreamOffset bytes_written) { + const bool had_buffered_frames = HasBufferedFrames(); + QUIC_DVLOG(1) << "Queuing RST_STREAM_FRAME"; + control_frames_.emplace_back(QuicFrame(new QuicRstStreamFrame( + ++last_control_frame_id_, stream_id, error_code, bytes_written))); + if (session_->connection()->transport_version() == QUIC_VERSION_99) { + QUIC_DVLOG(1) << "Version 99, Queuing STOP_SENDING"; + control_frames_.emplace_back(QuicFrame(new QuicStopSendingFrame( + ++last_control_frame_id_, stream_id, error_code))); + } + if (had_buffered_frames) { + return; + } + WriteBufferedFrames(); +} + void QuicControlFrameManager::WritePing() { QUIC_DVLOG(1) << "Writing PING_FRAME"; if (HasBufferedFrames()) {
diff --git a/net/third_party/quic/core/quic_control_frame_manager.h b/net/third_party/quic/core/quic_control_frame_manager.h index 725f8ab..cd9d59b1 100644 --- a/net/third_party/quic/core/quic_control_frame_manager.h +++ b/net/third_party/quic/core/quic_control_frame_manager.h
@@ -53,6 +53,13 @@ // immediately. void WriteOrBufferBlocked(QuicStreamId id); + // Tries to send a packet with both a RST_STREAM and, if version 99, an + // IETF-QUIC STOP_SENDING frame. The frames are buffered if they can not + // be sent immediately. + void WriteOrBufferRstStreamStopSending(QuicControlFrameId stream_id, + QuicRstStreamErrorCode error_code, + QuicStreamOffset bytes_written); + // Tries to send an IETF-QUIC STOP_SENDING frame. The frame is buffered if it // can not be sent immediately. void WriteOrBufferStopSending(uint16_t code, QuicStreamId stream_id);
diff --git a/net/third_party/quic/core/quic_session.cc b/net/third_party/quic/core/quic_session.cc index 0b92dcb..1b6ff62 100644 --- a/net/third_party/quic/core/quic_session.cc +++ b/net/third_party/quic/core/quic_session.cc
@@ -568,7 +568,20 @@ if (connection()->connected()) { // Only send a RST_STREAM frame if still connected. - control_frame_manager_.WriteOrBufferRstStream(id, error, bytes_written); + // Send a RST_STREAM frame. If version 99, will include + // an IETF-QUIC STOP_SENDING frame in the packet so that + // the peer also shuts down and sends a RST_STREAM back. + QuicConnection::ScopedPacketFlusher* flusher = + (connection_->transport_version() == QUIC_VERSION_99) + ? new QuicConnection::ScopedPacketFlusher( + connection(), QuicConnection::SEND_ACK_IF_QUEUED) + : nullptr; + control_frame_manager_.WriteOrBufferRstStreamStopSending(id, error, + bytes_written); + if (flusher) { + delete flusher; + flusher = nullptr; + } connection_->OnStreamReset(id, error); } if (error != QUIC_STREAM_NO_ERROR && QuicContainsKey(zombie_streams_, id)) {
diff --git a/net/third_party/quic/core/quic_session_test.cc b/net/third_party/quic/core/quic_session_test.cc index 82c6af1c6..49bad125 100644 --- a/net/third_party/quic/core/quic_session_test.cc +++ b/net/third_party/quic/core/quic_session_test.cc
@@ -341,8 +341,16 @@ EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0); EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(0); } else { - EXPECT_CALL(*connection_, SendControlFrame(_)) - .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame)); + // Verify reset IS sent for BIDIRECTIONAL streams. + if (session_.connection()->transport_version() == QUIC_VERSION_99) { + // Once for the RST_STREAM, Once for the STOP_SENDING + EXPECT_CALL(*connection_, SendControlFrame(_)) + .Times(2) + .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame)); + } else { + EXPECT_CALL(*connection_, SendControlFrame(_)) + .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame)); + } EXPECT_CALL(*connection_, OnStreamReset(id, _)); } session_.CloseStream(id); @@ -1282,9 +1290,15 @@ const QuicStreamOffset kByteOffset = 1 + kInitialSessionFlowControlWindowForTest / 2; - EXPECT_CALL(*connection_, SendControlFrame(_)) - .Times(2) - .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame)); + if (transport_version() == QUIC_VERSION_99) { + EXPECT_CALL(*connection_, SendControlFrame(_)) + .Times(3) + .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame)); + } else { + EXPECT_CALL(*connection_, SendControlFrame(_)) + .Times(2) + .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame)); + } EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _)); QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(), QUIC_STREAM_CANCELLED, kByteOffset); @@ -1465,8 +1479,16 @@ QuicStreamFrame data1(i, false, 0, QuicStringPiece("HT")); session_.OnStreamFrame(data1); // EXPECT_EQ(1u, session_.GetNumOpenStreams()); - EXPECT_CALL(*connection_, SendControlFrame(_)) - .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame)); + if (transport_version() == QUIC_VERSION_99) { + // Expect two control frames, RST STREAM and STOP SENDING + EXPECT_CALL(*connection_, SendControlFrame(_)) + .Times(2) + .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame)); + } else { + // Expect one control frame, just RST STREAM + EXPECT_CALL(*connection_, SendControlFrame(_)) + .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame)); + } // Close stream. Should not make new streams available since // the stream is not finished. EXPECT_CALL(*connection_, OnStreamReset(i, _)); @@ -1707,8 +1729,16 @@ QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream2->id(), QUIC_STREAM_CANCELLED, 1234); - EXPECT_CALL(*connection_, SendControlFrame(_)) - .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame)); + if (transport_version() == QUIC_VERSION_99) { + // Once for the RST_STREAM, once for the STOP_SENDING + EXPECT_CALL(*connection_, SendControlFrame(_)) + .Times(2) + .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame)); + } else { + // Just for the RST_STREAM + EXPECT_CALL(*connection_, SendControlFrame(_)) + .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame)); + } EXPECT_CALL(*connection_, OnStreamReset(stream2->id(), QUIC_RST_ACKNOWLEDGEMENT)); stream2->OnStreamReset(rst_frame); @@ -1717,7 +1747,15 @@ EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id()); TestStream* stream4 = session_.CreateOutgoingBidirectionalStream(); - EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1); + if (transport_version() == QUIC_VERSION_99) { + // Once for the RST_STREAM, once for the STOP_SENDING + EXPECT_CALL(*connection_, SendControlFrame(_)) + .Times(2) + .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame)); + } else { + // Just for the RST_STREAM + EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1); + } EXPECT_CALL(*connection_, OnStreamReset(stream4->id(), QUIC_STREAM_CANCELLED)); stream4->WriteOrBufferData(body, false, nullptr); @@ -1881,8 +1919,16 @@ // yet, so an RST is sent. EXPECT_CALL(*stream, OnCanWrite()) .WillOnce(Invoke(stream, &QuicStream::OnClose)); - EXPECT_CALL(*connection_, SendControlFrame(_)) - .WillOnce(Invoke(&session_, &TestSession::SaveFrame)); + if (transport_version() == QUIC_VERSION_99) { + // Once for the RST_STREAM, once for the STOP_SENDING + EXPECT_CALL(*connection_, SendControlFrame(_)) + .Times(2) + .WillRepeatedly(Invoke(&session_, &TestSession::SaveFrame)); + } else { + // Just for the RST_STREAM + EXPECT_CALL(*connection_, SendControlFrame(_)) + .WillOnce(Invoke(&session_, &TestSession::SaveFrame)); + } EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _)); session_.OnCanWrite(); }
diff --git a/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter b/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter index bd6bb33..9028e3c 100644 --- a/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter +++ b/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter
@@ -2,11 +2,6 @@ # feature X that is already not working), please add it beside the existing # failures. Otherwise please reach out to network-service-dev@. -# services/network/url_loader.cc should handle failure in -# URLLoaderImpl::OnResponseBodyStreamRead(). Note this is flaky, so it will pass -# sometimes. --SRC_ClearKey/EncryptedMediaTest.FrameSizeChangeVideo/0 - # https://crbug.com/846352: CORB/NetworkService: Remove # CrossSiteDocumentResourceHandler while preserving test coverage - the tests # below can be probably removed altogether once NetworkService ships and the
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 53c48ef..e0a5b82 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -4303,7 +4303,7 @@ ] } ], - "SimpleCachePrefetchExperiment": [ + "SimpleCachePrefetchExperiment2": [ { "platforms": [ "android", @@ -4312,12 +4312,14 @@ ], "experiments": [ { - "name": "Prefetch32K", + "name": "PrefetchFull32KTrailer4k", "params": { - "Bytes": "32768" + "FullPrefetchBytes": "32768", + "TrailerPrefetchHint": "true", + "TrailerPrefetchSpeculativeBytes": "4096" }, "enable_features": [ - "SimpleCachePrefetchExperiment" + "SimpleCachePrefetchExperiment2" ] } ]
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn index 6ad4e1f..d4aebc7f 100644 --- a/third_party/blink/public/mojom/BUILD.gn +++ b/third_party/blink/public/mojom/BUILD.gn
@@ -84,6 +84,10 @@ "worker/worker_main_script_load_params.mojom", ] + if (is_win) { + sources += [ "dwrite_font_proxy/dwrite_font_proxy.mojom" ] + } + public_deps = [ ":android_mojo_bindings", ":speech_recognition_error_code",
diff --git a/third_party/blink/public/mojom/dwrite_font_proxy/OWNERS b/third_party/blink/public/mojom/dwrite_font_proxy/OWNERS new file mode 100644 index 0000000..0573276d --- /dev/null +++ b/third_party/blink/public/mojom/dwrite_font_proxy/OWNERS
@@ -0,0 +1,6 @@ +drott@chromium.org + +# COMPONENT: Blink>Fonts + +per-file *.mojom=set noparent +per-file *.mojom=file://ipc/SECURITY_OWNERS \ No newline at end of file
diff --git a/content/common/dwrite_font_proxy.mojom b/third_party/blink/public/mojom/dwrite_font_proxy/dwrite_font_proxy.mojom similarity index 98% rename from content/common/dwrite_font_proxy.mojom rename to third_party/blink/public/mojom/dwrite_font_proxy/dwrite_font_proxy.mojom index 1d04c9b..24fbe49 100644 --- a/content/common/dwrite_font_proxy.mojom +++ b/third_party/blink/public/mojom/dwrite_font_proxy/dwrite_font_proxy.mojom
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -module content.mojom; +module blink.mojom; import "mojo/public/mojom/base/file.mojom"; import "mojo/public/mojom/base/file_path.mojom";
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h index d6dc342..cf6efc5 100644 --- a/third_party/blink/public/platform/web_runtime_features.h +++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -82,8 +82,6 @@ BLINK_PLATFORM_EXPORT static void EnableAllowActivationDelegationAttr(bool); BLINK_PLATFORM_EXPORT static void EnableAudioOutputDevices(bool); BLINK_PLATFORM_EXPORT static void EnableBackgroundFetch(bool); - BLINK_PLATFORM_EXPORT static void EnableBackgroundFetchAccessActiveFetches( - bool); BLINK_PLATFORM_EXPORT static void EnableBackgroundFetchUploads(bool); BLINK_PLATFORM_EXPORT static void EnableBlinkHeapIncrementalMarking(bool); BLINK_PLATFORM_EXPORT static void EnableBlinkHeapUnifiedGarbageCollection(
diff --git a/third_party/blink/renderer/controller/tests/run_all_tests.cc b/third_party/blink/renderer/controller/tests/run_all_tests.cc index b18d74a..df0a6bc63 100644 --- a/third_party/blink/renderer/controller/tests/run_all_tests.cc +++ b/third_party/blink/renderer/controller/tests/run_all_tests.cc
@@ -41,33 +41,43 @@ namespace { -int runHelper(base::TestSuite* testSuite) { - content::SetUpBlinkTestEnvironment(); - blink::SchemeRegistry::Initialize(); +class BlinkUnitTestSuite : public base::TestSuite { + public: + BlinkUnitTestSuite(int argc, char** argv) : base::TestSuite(argc, argv) {} - int result = testSuite->Run(); + private: + void Initialize() override { + base::TestSuite::Initialize(); - // Tickle EndOfTaskRunner which among other things will flush the queue - // of error messages via V8Initializer::reportRejectedPromisesOnMainThread. - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::DoNothing()); - base::RunLoop().RunUntilIdle(); + content::SetUpBlinkTestEnvironment(); + blink::SchemeRegistry::Initialize(); + } + void Shutdown() override { + // Tickle EndOfTaskRunner which among other things will flush the queue + // of error messages via V8Initializer::reportRejectedPromisesOnMainThread. + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::DoNothing()); + base::RunLoop().RunUntilIdle(); - // Collect garbage (including threadspecific persistent handles) in order - // to release mock objects referred from v8 or Oilpan heap. Otherwise false - // mock leaks will be reported. - blink::V8GCController::CollectAllGarbageForTesting( - v8::Isolate::GetCurrent(), - v8::EmbedderHeapTracer::EmbedderStackState::kEmpty); + // Collect garbage (including threadspecific persistent handles) in order + // to release mock objects referred from v8 or Oilpan heap. Otherwise false + // mock leaks will be reported. + blink::V8GCController::CollectAllGarbageForTesting( + v8::Isolate::GetCurrent(), + v8::EmbedderHeapTracer::EmbedderStackState::kEmpty); - content::TearDownBlinkTestEnvironment(); + content::TearDownBlinkTestEnvironment(); - return result; -} + base::TestSuite::Shutdown(); + } + + DISALLOW_COPY_AND_ASSIGN(BlinkUnitTestSuite); +}; } // namespace int main(int argc, char** argv) { - base::TestSuite testSuite(argc, argv); + BlinkUnitTestSuite test_suite(argc, argv); return base::LaunchUnitTests( - argc, argv, base::Bind(&runHelper, base::Unretained(&testSuite))); + argc, argv, + base::BindOnce(&BlinkUnitTestSuite::Run, base::Unretained(&test_suite))); }
diff --git a/third_party/blink/renderer/core/frame/frame_console.cc b/third_party/blink/renderer/core/frame/frame_console.cc index bfe16e6c..948c240 100644 --- a/third_party/blink/renderer/core/frame/frame_console.cc +++ b/third_party/blink/renderer/core/frame/frame_console.cc
@@ -46,12 +46,15 @@ FrameConsole::FrameConsole(LocalFrame& frame) : frame_(&frame) {} void FrameConsole::AddMessage(ConsoleMessage* console_message) { - // PlzNavigate: when trying to commit a navigation, the SourceLocation + // When trying to commit a navigation, the SourceLocation // information for how the request was triggered has been stored in the - // provisional DocumentLoader. Use it instead. + // provisional DocumentLoader. Use it if local SourceLocation + // is not available. + bool is_unknown_location = + !console_message->Location() || console_message->Location()->IsUnknown(); DocumentLoader* provisional_loader = frame_->Loader().GetProvisionalDocumentLoader(); - if (provisional_loader) { + if (provisional_loader && is_unknown_location) { std::unique_ptr<SourceLocation> source_location = provisional_loader->CopySourceLocation(); if (source_location) {
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index c199957..4bc21ee 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -96,7 +96,7 @@ LayoutUnit intrinsic_content_logical_height; LayoutRectOutsets margin_box_outsets; LayoutUnit preferred_logical_width[2]; - void* pointers[3]; + void* pointers[4]; }; static_assert(sizeof(LayoutBox) == sizeof(SameSizeAsLayoutBox), @@ -763,7 +763,7 @@ } LayoutUnit LayoutBox::LogicalHeightWithVisibleOverflow() const { - if (!overflow_ || HasOverflowClip()) + if (!layout_overflow_ || HasOverflowClip()) return LogicalHeight(); LayoutRect overflow = LayoutOverflowRect(); if (StyleRef().IsHorizontalWritingMode()) @@ -5223,8 +5223,8 @@ visual_effect_overflow.Expand(outsets); AddSelfVisualOverflow(visual_effect_overflow); - if (overflow_) { - overflow_->SetHasSubpixelVisualEffectOutsets( + if (visual_overflow_) { + visual_overflow_->SetHasSubpixelVisualEffectOutsets( !IsIntegerValue(outsets.Top()) || !IsIntegerValue(outsets.Right()) || !IsIntegerValue(outsets.Bottom()) || !IsIntegerValue(outsets.Left())); } @@ -5292,12 +5292,13 @@ } void LayoutBox::SetLayoutClientAfterEdge(LayoutUnit client_after_edge) { - if (overflow_) - overflow_->SetLayoutClientAfterEdge(client_after_edge); + if (layout_overflow_) + layout_overflow_->SetLayoutClientAfterEdge(client_after_edge); } LayoutUnit LayoutBox::LayoutClientAfterEdge() const { - return overflow_ ? overflow_->LayoutClientAfterEdge() : ClientLogicalBottom(); + return layout_overflow_ ? layout_overflow_->LayoutClientAfterEdge() + : ClientLogicalBottom(); } LayoutRect LayoutBox::VisualOverflowRectIncludingFilters() const { @@ -5355,11 +5356,11 @@ return; } - if (!overflow_) { - overflow_ = std::make_unique<BoxOverflowModel>(client_box, BorderBoxRect()); + if (!layout_overflow_) { + layout_overflow_ = std::make_unique<BoxLayoutOverflowModel>(client_box); } - overflow_->AddLayoutOverflow(overflow_rect); + layout_overflow_->AddLayoutOverflow(overflow_rect); } void LayoutBox::AddSelfVisualOverflow(const LayoutRect& rect) { @@ -5370,12 +5371,11 @@ if (border_box.Contains(rect)) return; - if (!overflow_) { - overflow_ = - std::make_unique<BoxOverflowModel>(NoOverflowRect(), border_box); + if (!visual_overflow_) { + visual_overflow_ = std::make_unique<BoxVisualOverflowModel>(border_box); } - overflow_->AddSelfVisualOverflow(rect); + visual_overflow_->AddSelfVisualOverflow(rect); } void LayoutBox::AddContentsVisualOverflow(const LayoutRect& rect) { @@ -5391,36 +5391,18 @@ if (!HasOverflowClip() && border_box.Contains(rect)) return; - if (!overflow_) { - overflow_ = - std::make_unique<BoxOverflowModel>(NoOverflowRect(), border_box); + if (!visual_overflow_) { + visual_overflow_ = std::make_unique<BoxVisualOverflowModel>(border_box); } - overflow_->AddContentsVisualOverflow(rect); + visual_overflow_->AddContentsVisualOverflow(rect); } void LayoutBox::ClearLayoutOverflow() { - if (!overflow_) - return; - - if (!HasSelfVisualOverflow() && ContentsVisualOverflowRect().IsEmpty()) { - overflow_.reset(); - return; - } - - overflow_->SetLayoutOverflow(NoOverflowRect()); + layout_overflow_.reset(); } void LayoutBox::ClearVisualOverflow() { - if (!overflow_) - return; - - if (!HasLayoutOverflow()) { - overflow_.reset(); - return; - } - - overflow_->ClearContentsVisualOverflow(); - overflow_->SetSelfVisualOverflow(BorderBoxRect()); + visual_overflow_.reset(); } bool LayoutBox::PercentageLogicalHeightIsResolvable() const { @@ -5605,12 +5587,12 @@ } LayoutRect LayoutBox::VisualOverflowRect() const { - if (!overflow_) + if (!visual_overflow_) return BorderBoxRect(); if (HasOverflowClip() || HasMask()) - return overflow_->SelfVisualOverflowRect(); - return UnionRect(overflow_->SelfVisualOverflowRect(), - overflow_->ContentsVisualOverflowRect()); + return visual_overflow_->SelfVisualOverflowRect(); + return UnionRect(visual_overflow_->SelfVisualOverflowRect(), + visual_overflow_->ContentsVisualOverflowRect()); } LayoutPoint LayoutBox::OffsetPoint(const Element* parent) const { @@ -6062,7 +6044,9 @@ // painted along the pixel-snapped border box, the pixels on the anti-aliased // edge of the effect may overflow the calculated visual rect. Expand visual // rect by one pixel in the case. - return overflow_ && overflow_->HasSubpixelVisualEffectOutsets() ? 1 : 0; + return visual_overflow_ && visual_overflow_->HasSubpixelVisualEffectOutsets() + ? 1 + : 0; } TextDirection LayoutBox::ResolvedDirection() const {
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h index b8f0fea..05feb87d 100644 --- a/third_party/blink/renderer/core/layout/layout_box.h +++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -480,7 +480,8 @@ // in the "physical coordinates in flipped block-flow direction" of the box. LayoutRect NoOverflowRect() const; LayoutRect LayoutOverflowRect() const { - return overflow_ ? overflow_->LayoutOverflowRect() : NoOverflowRect(); + return layout_overflow_ ? layout_overflow_->LayoutOverflowRect() + : NoOverflowRect(); } LayoutRect PhysicalLayoutOverflowRect() const { LayoutRect overflow_rect = LayoutOverflowRect(); @@ -518,10 +519,12 @@ } LayoutRect SelfVisualOverflowRect() const { - return overflow_ ? overflow_->SelfVisualOverflowRect() : BorderBoxRect(); + return visual_overflow_ ? visual_overflow_->SelfVisualOverflowRect() + : BorderBoxRect(); } LayoutRect ContentsVisualOverflowRect() const { - return overflow_ ? overflow_->ContentsVisualOverflowRect() : LayoutRect(); + return visual_overflow_ ? visual_overflow_->ContentsVisualOverflowRect() + : LayoutRect(); } // Returns the visual overflow rect, expanded to the area affected by any @@ -1308,16 +1311,19 @@ LayoutObject* container) const; LayoutRect LayoutOverflowRectForPropagation(LayoutObject* container) const; - bool HasOverflowModel() const { return overflow_.get(); } + // TODO(chrishtr): delete callsites of this. + bool HasOverflowModel() const { + return layout_overflow_.get() || visual_overflow_.get(); + } bool HasSelfVisualOverflow() const { - return overflow_ && - !BorderBoxRect().Contains(overflow_->SelfVisualOverflowRect()); + return visual_overflow_ && !BorderBoxRect().Contains( + visual_overflow_->SelfVisualOverflowRect()); } bool HasVisualOverflow() const { - return overflow_ && !BorderBoxRect().Contains(VisualOverflowRect()); + return visual_overflow_ && !BorderBoxRect().Contains(VisualOverflowRect()); } bool HasLayoutOverflow() const { - return overflow_ && !BorderBoxRect().Contains(LayoutOverflowRect()); + return layout_overflow_ && !BorderBoxRect().Contains(LayoutOverflowRect()); } // Return true if re-laying out the containing block of this object means that @@ -1374,20 +1380,20 @@ bool HasRelativeLogicalHeight() const; bool HasHorizontalLayoutOverflow() const { - if (!overflow_) + if (!layout_overflow_) return false; - LayoutRect layout_overflow_rect = overflow_->LayoutOverflowRect(); + LayoutRect layout_overflow_rect = layout_overflow_->LayoutOverflowRect(); LayoutRect no_overflow_rect = NoOverflowRect(); return layout_overflow_rect.X() < no_overflow_rect.X() || layout_overflow_rect.MaxX() > no_overflow_rect.MaxX(); } bool HasVerticalLayoutOverflow() const { - if (!overflow_) + if (!layout_overflow_) return false; - LayoutRect layout_overflow_rect = overflow_->LayoutOverflowRect(); + LayoutRect layout_overflow_rect = layout_overflow_->LayoutOverflowRect(); LayoutRect no_overflow_rect = NoOverflowRect(); return layout_overflow_rect.Y() < no_overflow_rect.Y() || layout_overflow_rect.MaxY() > no_overflow_rect.MaxY(); @@ -1796,8 +1802,8 @@ &LayoutBox::SetMarginBottom, &LayoutBox::SetMarginLeft); } - // Our overflow information. - std::unique_ptr<BoxOverflowModel> overflow_; + std::unique_ptr<BoxLayoutOverflowModel> layout_overflow_; + std::unique_ptr<BoxVisualOverflowModel> visual_overflow_; union { // The inline box containing this LayoutBox, for atomic inline elements.
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc index 9c92088..82962bd 100644 --- a/third_party/blink/renderer/core/layout/layout_object.cc +++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -949,10 +949,19 @@ DCHECK(!object->IsSetNeedsLayoutForbidden()); #endif + if (object->HasLayer() && + ToLayoutBoxModelObject(object)->Layer()->IsSelfPaintingLayer()) + ToLayoutBoxModelObject(object)->Layer()->SetNeedsVisualOverflowRecalc(); + if (layouter) { layouter->RecordObjectMarkedForLayout(object); - if (object == layouter->Root()) + + if (object == layouter->Root()) { + if (auto* painting_layer = PaintingLayer()) + painting_layer->SetNeedsVisualOverflowRecalc(); + return; + } } last = object;
diff --git a/third_party/blink/renderer/core/layout/layout_object_test.cc b/third_party/blink/renderer/core/layout/layout_object_test.cc index 47450ba5..a17044e 100644 --- a/third_party/blink/renderer/core/layout/layout_object_test.cc +++ b/third_party/blink/renderer/core/layout/layout_object_test.cc
@@ -827,6 +827,31 @@ EXPECT_TRUE(object->HasNonZeroEffectiveOpacity()); } +TEST_F(LayoutObjectTest, UpdateVisualRectAfterAncestorLayout) { + SetBodyInnerHTML(R"HTML( + <style> + #target { + width: 50px; + height: 0; + position: relative; + } + </style> + <div id=ancestor style="width: 100px; height: 100px; position: relative"> + <div> + <div id=target></div> + </div> + </div> + )HTML"); + + auto* target = GetDocument().getElementById("target"); + target->setAttribute(html_names::kStyleAttr, "height: 300px"); + GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); + const auto* container = GetLayoutObjectByElementId("ancestor"); + EXPECT_EQ(LayoutRect(0, 0, 100, 300), + ToLayoutBox(container)->VisualOverflowRect()); +} + class LayoutObjectSimTest : public SimTest { public: bool DocumentHasTouchActionRegion(const EventHandlerRegistry& registry) {
diff --git a/third_party/blink/renderer/core/layout/line/inline_flow_box.cc b/third_party/blink/renderer/core/layout/line/inline_flow_box.cc index 1fa99fb..5d73d13 100644 --- a/third_party/blink/renderer/core/layout/line/inline_flow_box.cc +++ b/third_party/blink/renderer/core/layout/line/inline_flow_box.cc
@@ -44,7 +44,7 @@ namespace blink { struct SameSizeAsInlineFlowBox : public InlineBox { - void* pointers[5]; + void* pointers[6]; uint32_t bitfields : 23; }; @@ -299,11 +299,12 @@ continue; child->Move(delta); } - if (overflow_) { - // FIXME: Rounding error here since overflow was pixel snapped, but nobody - // other than list markers passes non-integral values here. - overflow_->Move(delta.Width(), delta.Height()); - } + // FIXME: Rounding error here since overflow was pixel snapped, but nobody + // other than list markers passes non-integral values here. + if (layout_overflow_) + layout_overflow_->Move(delta.Width(), delta.Height()); + if (visual_overflow_) + visual_overflow_->Move(delta.Width(), delta.Height()); } LineBoxList* InlineFlowBox::LineBoxes() const { @@ -1209,12 +1210,14 @@ GlyphOverflowAndFallbackFontsMap& text_box_data_map) { // If we know we have no overflow, we can just bail. if (KnownToHaveNoOverflow()) { - DCHECK(!overflow_); + DCHECK(!layout_overflow_ && !visual_overflow_); return; } - if (overflow_) - overflow_.reset(); + if (layout_overflow_) + layout_overflow_.reset(); + if (visual_overflow_) + visual_overflow_.reset(); // Visual overflow just includes overflow for stuff we need to issues paint // invalidations for ourselves. Self-painting layers are ignored. @@ -1288,10 +1291,10 @@ if (frame_box.Contains(rect) || rect.IsEmpty()) return; - if (!overflow_) - overflow_ = std::make_unique<SimpleOverflowModel>(frame_box, frame_box); + if (!layout_overflow_) + layout_overflow_ = std::make_unique<SimpleLayoutOverflowModel>(frame_box); - overflow_->SetLayoutOverflow(rect); + layout_overflow_->SetLayoutOverflow(rect); } void InlineFlowBox::SetVisualOverflow(const LayoutRect& rect, @@ -1300,10 +1303,10 @@ if (frame_box.Contains(rect) || rect.IsEmpty()) return; - if (!overflow_) - overflow_ = std::make_unique<SimpleOverflowModel>(frame_box, frame_box); + if (!visual_overflow_) + visual_overflow_ = std::make_unique<SimpleVisualOverflowModel>(frame_box); - overflow_->SetVisualOverflow(rect); + visual_overflow_->SetVisualOverflow(rect); } void InlineFlowBox::SetVisualOverflowFromLogicalRect(
diff --git a/third_party/blink/renderer/core/layout/line/inline_flow_box.h b/third_party/blink/renderer/core/layout/line/inline_flow_box.h index c6b7c33..7fd35e8f 100644 --- a/third_party/blink/renderer/core/layout/line/inline_flow_box.h +++ b/third_party/blink/renderer/core/layout/line/inline_flow_box.h
@@ -286,19 +286,22 @@ // the right in vertical-rl. LayoutRect LayoutOverflowRect(LayoutUnit line_top, LayoutUnit line_bottom) const { - return overflow_ ? overflow_->LayoutOverflowRect() - : FrameRectIncludingLineHeight(line_top, line_bottom); + return layout_overflow_ + ? layout_overflow_->LayoutOverflowRect() + : FrameRectIncludingLineHeight(line_top, line_bottom); } LayoutUnit LogicalTopLayoutOverflow(LayoutUnit line_top) const { - if (overflow_) - return IsHorizontal() ? overflow_->LayoutOverflowRect().Y() - : overflow_->LayoutOverflowRect().X(); + if (layout_overflow_) { + return IsHorizontal() ? layout_overflow_->LayoutOverflowRect().Y() + : layout_overflow_->LayoutOverflowRect().X(); + } return line_top; } LayoutUnit LogicalBottomLayoutOverflow(LayoutUnit line_bottom) const { - if (overflow_) - return IsHorizontal() ? overflow_->LayoutOverflowRect().MaxY() - : overflow_->LayoutOverflowRect().MaxX(); + if (layout_overflow_) { + return IsHorizontal() ? layout_overflow_->LayoutOverflowRect().MaxY() + : layout_overflow_->LayoutOverflowRect().MaxX(); + } return line_bottom; } LayoutRect LogicalLayoutOverflowRect(LayoutUnit line_top, @@ -309,45 +312,51 @@ return result; } LayoutUnit LogicalRightLayoutOverflow() const { - if (overflow_) { - return IsHorizontal() ? overflow_->LayoutOverflowRect().MaxX() - : overflow_->LayoutOverflowRect().MaxY(); + if (layout_overflow_) { + return IsHorizontal() ? layout_overflow_->LayoutOverflowRect().MaxX() + : layout_overflow_->LayoutOverflowRect().MaxY(); } return LogicalRight(); } LayoutUnit LogicalLeftLayoutOverflow() const { - if (overflow_) { - return IsHorizontal() ? overflow_->LayoutOverflowRect().X() - : overflow_->LayoutOverflowRect().Y(); + if (layout_overflow_) { + return IsHorizontal() ? layout_overflow_->LayoutOverflowRect().X() + : layout_overflow_->LayoutOverflowRect().Y(); } return LogicalLeft(); } LayoutRect VisualOverflowRect(LayoutUnit line_top, LayoutUnit line_bottom) const { - return overflow_ ? overflow_->VisualOverflowRect() - : FrameRectIncludingLineHeight(line_top, line_bottom); + return visual_overflow_ + ? visual_overflow_->VisualOverflowRect() + : FrameRectIncludingLineHeight(line_top, line_bottom); } LayoutUnit LogicalLeftVisualOverflow() const { - return overflow_ ? (IsHorizontal() ? overflow_->VisualOverflowRect().X() - : overflow_->VisualOverflowRect().Y()) - : LogicalLeft(); + return visual_overflow_ + ? (IsHorizontal() ? visual_overflow_->VisualOverflowRect().X() + : visual_overflow_->VisualOverflowRect().Y()) + : LogicalLeft(); } LayoutUnit LogicalRightVisualOverflow() const { - return overflow_ ? (IsHorizontal() ? overflow_->VisualOverflowRect().MaxX() - : overflow_->VisualOverflowRect().MaxY()) - : static_cast<LayoutUnit>(LogicalRight().Ceil()); + return visual_overflow_ + ? (IsHorizontal() + ? visual_overflow_->VisualOverflowRect().MaxX() + : visual_overflow_->VisualOverflowRect().MaxY()) + : static_cast<LayoutUnit>(LogicalRight().Ceil()); } LayoutUnit LogicalTopVisualOverflow(LayoutUnit line_top) const { - if (overflow_) - return IsHorizontal() ? overflow_->VisualOverflowRect().Y() - : overflow_->VisualOverflowRect().X(); + if (visual_overflow_) { + return IsHorizontal() ? visual_overflow_->VisualOverflowRect().Y() + : visual_overflow_->VisualOverflowRect().X(); + } return line_top; } LayoutUnit LogicalBottomVisualOverflow(LayoutUnit line_bottom) const { - if (overflow_) - return IsHorizontal() ? overflow_->VisualOverflowRect().MaxY() - : overflow_->VisualOverflowRect().MaxX(); + if (visual_overflow_) { + return IsHorizontal() ? visual_overflow_->VisualOverflowRect().MaxY() + : visual_overflow_->VisualOverflowRect().MaxX(); + } return line_bottom; } LayoutRect LogicalVisualOverflowRect(LayoutUnit line_top, @@ -445,7 +454,8 @@ LayoutUnit line_bottom); protected: - std::unique_ptr<SimpleOverflowModel> overflow_; + std::unique_ptr<SimpleLayoutOverflowModel> layout_overflow_; + std::unique_ptr<SimpleVisualOverflowModel> visual_overflow_; bool IsInlineFlowBox() const final { return true; }
diff --git a/third_party/blink/renderer/core/layout/overflow_model.h b/third_party/blink/renderer/core/layout/overflow_model.h index 74ca3a1..d6d1882 100644 --- a/third_party/blink/renderer/core/layout/overflow_model.h +++ b/third_party/blink/renderer/core/layout/overflow_model.h
@@ -82,13 +82,12 @@ // functions (addLayoutOverflow, addVisualOverflow, etc.) to keep this // invariant. -class SimpleOverflowModel { - USING_FAST_MALLOC(SimpleOverflowModel); +class SimpleLayoutOverflowModel { + USING_FAST_MALLOC(SimpleLayoutOverflowModel); public: - SimpleOverflowModel(const LayoutRect& layout_rect, - const LayoutRect& visual_rect) - : layout_overflow_(layout_rect), visual_overflow_(visual_rect) {} + SimpleLayoutOverflowModel(const LayoutRect& layout_rect) + : layout_overflow_(layout_rect) {} const LayoutRect& LayoutOverflowRect() const { return layout_overflow_; } void SetLayoutOverflow(const LayoutRect& rect) { layout_overflow_ = rect; } @@ -96,6 +95,21 @@ UniteLayoutOverflowRect(layout_overflow_, rect); } + void Move(LayoutUnit dx, LayoutUnit dy) { layout_overflow_.Move(dx, dy); } + + private: + LayoutRect layout_overflow_; + + DISALLOW_COPY_AND_ASSIGN(SimpleLayoutOverflowModel); +}; + +class SimpleVisualOverflowModel { + USING_FAST_MALLOC(SimpleVisualOverflowModel); + + public: + SimpleVisualOverflowModel(const LayoutRect& visual_rect) + : visual_overflow_(visual_rect) {} + const LayoutRect& VisualOverflowRect() const { return visual_overflow_; } void SetVisualOverflow(const LayoutRect& rect) { visual_overflow_ = rect; } void AddVisualOverflow(const LayoutRect& rect) { @@ -103,15 +117,13 @@ } void Move(LayoutUnit dx, LayoutUnit dy) { - layout_overflow_.Move(dx, dy); visual_overflow_.Move(dx, dy); } private: - LayoutRect layout_overflow_; LayoutRect visual_overflow_; - DISALLOW_COPY_AND_ASSIGN(SimpleOverflowModel); + DISALLOW_COPY_AND_ASSIGN(SimpleVisualOverflowModel); }; // BoxModelOverflow tracks overflows of a LayoutBox. It separates visual @@ -141,14 +153,12 @@ // it clips overflow, otherwise union of self visual overflow and contents // visual overflow. -class BoxOverflowModel { - USING_FAST_MALLOC(BoxOverflowModel); +class BoxLayoutOverflowModel { + USING_FAST_MALLOC(BoxLayoutOverflowModel); public: - BoxOverflowModel(const LayoutRect& layout_rect, - const LayoutRect& self_visual_overflow_rect) - : layout_overflow_(layout_rect), - self_visual_overflow_(self_visual_overflow_rect) {} + BoxLayoutOverflowModel(const LayoutRect& layout_rect) + : layout_overflow_(layout_rect) {} const LayoutRect& LayoutOverflowRect() const { return layout_overflow_; } void SetLayoutOverflow(const LayoutRect& rect) { layout_overflow_ = rect; } @@ -156,6 +166,28 @@ UniteLayoutOverflowRect(layout_overflow_, rect); } + void Move(LayoutUnit dx, LayoutUnit dy) { layout_overflow_.Move(dx, dy); } + + LayoutUnit LayoutClientAfterEdge() const { return layout_client_after_edge_; } + void SetLayoutClientAfterEdge(LayoutUnit client_after_edge) { + layout_client_after_edge_ = client_after_edge; + } + + private: + LayoutRect layout_overflow_; + LayoutUnit layout_client_after_edge_; + bool has_subpixel_visual_effect_outsets_ = false; + + DISALLOW_COPY_AND_ASSIGN(BoxLayoutOverflowModel); +}; + +class BoxVisualOverflowModel { + USING_FAST_MALLOC(BoxVisualOverflowModel); + + public: + BoxVisualOverflowModel(const LayoutRect& self_visual_overflow_rect) + : self_visual_overflow_(self_visual_overflow_rect) {} + void SetSelfVisualOverflow(const LayoutRect& rect) { self_visual_overflow_ = rect; } @@ -179,16 +211,10 @@ } void Move(LayoutUnit dx, LayoutUnit dy) { - layout_overflow_.Move(dx, dy); self_visual_overflow_.Move(dx, dy); contents_visual_overflow_.Move(dx, dy); } - LayoutUnit LayoutClientAfterEdge() const { return layout_client_after_edge_; } - void SetLayoutClientAfterEdge(LayoutUnit client_after_edge) { - layout_client_after_edge_ = client_after_edge; - } - void SetHasSubpixelVisualEffectOutsets(bool b) { has_subpixel_visual_effect_outsets_ = b; } @@ -197,13 +223,11 @@ } private: - LayoutRect layout_overflow_; LayoutRect self_visual_overflow_; LayoutRect contents_visual_overflow_; - LayoutUnit layout_client_after_edge_; bool has_subpixel_visual_effect_outsets_ = false; - DISALLOW_COPY_AND_ASSIGN(BoxOverflowModel); + DISALLOW_COPY_AND_ASSIGN(BoxVisualOverflowModel); }; } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/overflow_model_test.cc b/third_party/blink/renderer/core/layout/overflow_model_test.cc index c039f4798..f7d918c7 100644 --- a/third_party/blink/renderer/core/layout/overflow_model_test.cc +++ b/third_party/blink/renderer/core/layout/overflow_model_test.cc
@@ -47,178 +47,164 @@ class SimpleOverflowModelTest : public testing::Test { protected: SimpleOverflowModelTest() - : overflow_(InitialLayoutOverflow(), InitialVisualOverflow()) {} - SimpleOverflowModel overflow_; + : layout_overflow_(InitialLayoutOverflow()), + visual_overflow_(InitialVisualOverflow()) {} + SimpleLayoutOverflowModel layout_overflow_; + SimpleVisualOverflowModel visual_overflow_; }; TEST_F(SimpleOverflowModelTest, InitialOverflowRects) { - EXPECT_EQ(InitialLayoutOverflow(), overflow_.LayoutOverflowRect()); - EXPECT_EQ(InitialVisualOverflow(), overflow_.VisualOverflowRect()); + EXPECT_EQ(InitialLayoutOverflow(), layout_overflow_.LayoutOverflowRect()); + EXPECT_EQ(InitialVisualOverflow(), visual_overflow_.VisualOverflowRect()); } TEST_F(SimpleOverflowModelTest, AddLayoutOverflowOutsideExpandsRect) { - overflow_.AddLayoutOverflow(LayoutRect(0, 10, 30, 10)); - EXPECT_EQ(LayoutRect(0, 10, 90, 80), overflow_.LayoutOverflowRect()); + layout_overflow_.AddLayoutOverflow(LayoutRect(0, 10, 30, 10)); + EXPECT_EQ(LayoutRect(0, 10, 90, 80), layout_overflow_.LayoutOverflowRect()); } TEST_F(SimpleOverflowModelTest, AddLayoutOverflowInsideDoesNotAffectRect) { - overflow_.AddLayoutOverflow(LayoutRect(50, 50, 10, 20)); - EXPECT_EQ(InitialLayoutOverflow(), overflow_.LayoutOverflowRect()); + layout_overflow_.AddLayoutOverflow(LayoutRect(50, 50, 10, 20)); + EXPECT_EQ(InitialLayoutOverflow(), layout_overflow_.LayoutOverflowRect()); } TEST_F(SimpleOverflowModelTest, AddLayoutOverflowEmpty) { // This test documents the existing behavior so that we are aware when/if // it changes. It would also be reasonable for addLayoutOverflow to be // a no-op in this situation. - overflow_.AddLayoutOverflow(LayoutRect(200, 200, 0, 0)); - EXPECT_EQ(LayoutRect(10, 10, 190, 190), overflow_.LayoutOverflowRect()); -} - -TEST_F(SimpleOverflowModelTest, AddLayoutOverflowDoesNotAffectVisualOverflow) { - overflow_.AddLayoutOverflow(LayoutRect(300, 300, 300, 300)); - EXPECT_EQ(InitialVisualOverflow(), overflow_.VisualOverflowRect()); + layout_overflow_.AddLayoutOverflow(LayoutRect(200, 200, 0, 0)); + EXPECT_EQ(LayoutRect(10, 10, 190, 190), + layout_overflow_.LayoutOverflowRect()); } TEST_F(SimpleOverflowModelTest, AddVisualOverflowOutsideExpandsRect) { - overflow_.AddVisualOverflow(LayoutRect(150, -50, 10, 10)); - EXPECT_EQ(LayoutRect(0, -50, 160, 150), overflow_.VisualOverflowRect()); + visual_overflow_.AddVisualOverflow(LayoutRect(150, -50, 10, 10)); + EXPECT_EQ(LayoutRect(0, -50, 160, 150), + visual_overflow_.VisualOverflowRect()); } TEST_F(SimpleOverflowModelTest, AddVisualOverflowInsideDoesNotAffectRect) { - overflow_.AddVisualOverflow(LayoutRect(0, 10, 90, 90)); - EXPECT_EQ(InitialVisualOverflow(), overflow_.VisualOverflowRect()); + visual_overflow_.AddVisualOverflow(LayoutRect(0, 10, 90, 90)); + EXPECT_EQ(InitialVisualOverflow(), visual_overflow_.VisualOverflowRect()); } TEST_F(SimpleOverflowModelTest, AddVisualOverflowEmpty) { - overflow_.SetVisualOverflow(LayoutRect(0, 0, 600, 0)); - overflow_.AddVisualOverflow(LayoutRect(100, -50, 100, 100)); - overflow_.AddVisualOverflow(LayoutRect(300, 300, 0, 10000)); - EXPECT_EQ(LayoutRect(100, -50, 100, 100), overflow_.VisualOverflowRect()); -} - -TEST_F(SimpleOverflowModelTest, AddVisualOverflowDoesNotAffectLayoutOverflow) { - overflow_.AddVisualOverflow(LayoutRect(300, 300, 300, 300)); - EXPECT_EQ(InitialLayoutOverflow(), overflow_.LayoutOverflowRect()); + visual_overflow_.SetVisualOverflow(LayoutRect(0, 0, 600, 0)); + visual_overflow_.AddVisualOverflow(LayoutRect(100, -50, 100, 100)); + visual_overflow_.AddVisualOverflow(LayoutRect(300, 300, 0, 10000)); + EXPECT_EQ(LayoutRect(100, -50, 100, 100), + visual_overflow_.VisualOverflowRect()); } TEST_F(SimpleOverflowModelTest, MoveAffectsLayoutOverflow) { - overflow_.Move(LayoutUnit(500), LayoutUnit(100)); - EXPECT_EQ(LayoutRect(510, 110, 80, 80), overflow_.LayoutOverflowRect()); -} - -TEST_F(SimpleOverflowModelTest, MoveAffectsVisualOverflow) { - overflow_.Move(LayoutUnit(500), LayoutUnit(100)); - EXPECT_EQ(LayoutRect(500, 100, 100, 100), overflow_.VisualOverflowRect()); + layout_overflow_.Move(LayoutUnit(500), LayoutUnit(100)); + EXPECT_EQ(LayoutRect(510, 110, 80, 80), + layout_overflow_.LayoutOverflowRect()); } class BoxOverflowModelTest : public testing::Test { protected: BoxOverflowModelTest() - : overflow_(InitialLayoutOverflow(), InitialVisualOverflow()) {} - BoxOverflowModel overflow_; + : layout_overflow_(InitialLayoutOverflow()), + visual_overflow_(InitialVisualOverflow()) {} + BoxLayoutOverflowModel layout_overflow_; + BoxVisualOverflowModel visual_overflow_; }; TEST_F(BoxOverflowModelTest, InitialOverflowRects) { - EXPECT_EQ(InitialLayoutOverflow(), overflow_.LayoutOverflowRect()); - EXPECT_EQ(InitialVisualOverflow(), overflow_.SelfVisualOverflowRect()); - EXPECT_TRUE(overflow_.ContentsVisualOverflowRect().IsEmpty()); + EXPECT_EQ(InitialLayoutOverflow(), layout_overflow_.LayoutOverflowRect()); + EXPECT_EQ(InitialVisualOverflow(), visual_overflow_.SelfVisualOverflowRect()); + EXPECT_TRUE(visual_overflow_.ContentsVisualOverflowRect().IsEmpty()); } TEST_F(BoxOverflowModelTest, AddLayoutOverflowOutsideExpandsRect) { - overflow_.AddLayoutOverflow(LayoutRect(0, 10, 30, 10)); - EXPECT_EQ(LayoutRect(0, 10, 90, 80), overflow_.LayoutOverflowRect()); + layout_overflow_.AddLayoutOverflow(LayoutRect(0, 10, 30, 10)); + EXPECT_EQ(LayoutRect(0, 10, 90, 80), layout_overflow_.LayoutOverflowRect()); } TEST_F(BoxOverflowModelTest, AddLayoutOverflowInsideDoesNotAffectRect) { - overflow_.AddLayoutOverflow(LayoutRect(50, 50, 10, 20)); - EXPECT_EQ(InitialLayoutOverflow(), overflow_.LayoutOverflowRect()); + layout_overflow_.AddLayoutOverflow(LayoutRect(50, 50, 10, 20)); + EXPECT_EQ(InitialLayoutOverflow(), layout_overflow_.LayoutOverflowRect()); } TEST_F(BoxOverflowModelTest, AddLayoutOverflowEmpty) { // This test documents the existing behavior so that we are aware when/if // it changes. It would also be reasonable for addLayoutOverflow to be // a no-op in this situation. - overflow_.AddLayoutOverflow(LayoutRect(200, 200, 0, 0)); - EXPECT_EQ(LayoutRect(10, 10, 190, 190), overflow_.LayoutOverflowRect()); -} - -TEST_F(BoxOverflowModelTest, AddLayoutOverflowDoesNotAffectSelfVisualOverflow) { - overflow_.AddLayoutOverflow(LayoutRect(300, 300, 300, 300)); - EXPECT_EQ(InitialVisualOverflow(), overflow_.SelfVisualOverflowRect()); -} - -TEST_F(BoxOverflowModelTest, - AddLayoutOverflowDoesNotAffectContentsVisualOverflow) { - overflow_.AddLayoutOverflow(LayoutRect(300, 300, 300, 300)); - EXPECT_TRUE(overflow_.ContentsVisualOverflowRect().IsEmpty()); + layout_overflow_.AddLayoutOverflow(LayoutRect(200, 200, 0, 0)); + EXPECT_EQ(LayoutRect(10, 10, 190, 190), + layout_overflow_.LayoutOverflowRect()); } TEST_F(BoxOverflowModelTest, AddSelfVisualOverflowOutsideExpandsRect) { - overflow_.AddSelfVisualOverflow(LayoutRect(150, -50, 10, 10)); - EXPECT_EQ(LayoutRect(0, -50, 160, 150), overflow_.SelfVisualOverflowRect()); + visual_overflow_.AddSelfVisualOverflow(LayoutRect(150, -50, 10, 10)); + EXPECT_EQ(LayoutRect(0, -50, 160, 150), + visual_overflow_.SelfVisualOverflowRect()); } TEST_F(BoxOverflowModelTest, AddSelfVisualOverflowInsideDoesNotAffectRect) { - overflow_.AddSelfVisualOverflow(LayoutRect(0, 10, 90, 90)); - EXPECT_EQ(InitialVisualOverflow(), overflow_.SelfVisualOverflowRect()); + visual_overflow_.AddSelfVisualOverflow(LayoutRect(0, 10, 90, 90)); + EXPECT_EQ(InitialVisualOverflow(), visual_overflow_.SelfVisualOverflowRect()); } TEST_F(BoxOverflowModelTest, AddSelfVisualOverflowEmpty) { - BoxOverflowModel overflow(LayoutRect(), LayoutRect(0, 0, 600, 0)); - overflow.AddSelfVisualOverflow(LayoutRect(100, -50, 100, 100)); - overflow.AddSelfVisualOverflow(LayoutRect(300, 300, 0, 10000)); - EXPECT_EQ(LayoutRect(100, -50, 100, 100), overflow.SelfVisualOverflowRect()); -} - -TEST_F(BoxOverflowModelTest, AddSelfVisualOverflowDoesNotAffectLayoutOverflow) { - overflow_.AddSelfVisualOverflow(LayoutRect(300, 300, 300, 300)); - EXPECT_EQ(InitialLayoutOverflow(), overflow_.LayoutOverflowRect()); + BoxVisualOverflowModel visual_overflow(LayoutRect(0, 0, 600, 0)); + visual_overflow.AddSelfVisualOverflow(LayoutRect(100, -50, 100, 100)); + visual_overflow.AddSelfVisualOverflow(LayoutRect(300, 300, 0, 10000)); + EXPECT_EQ(LayoutRect(100, -50, 100, 100), + visual_overflow.SelfVisualOverflowRect()); } TEST_F(BoxOverflowModelTest, AddSelfVisualOverflowDoesNotAffectContentsVisualOverflow) { - overflow_.AddSelfVisualOverflow(LayoutRect(300, 300, 300, 300)); - EXPECT_TRUE(overflow_.ContentsVisualOverflowRect().IsEmpty()); + visual_overflow_.AddSelfVisualOverflow(LayoutRect(300, 300, 300, 300)); + EXPECT_TRUE(visual_overflow_.ContentsVisualOverflowRect().IsEmpty()); } TEST_F(BoxOverflowModelTest, AddContentsVisualOverflowFirstCall) { - overflow_.AddContentsVisualOverflow(LayoutRect(0, 0, 10, 10)); - EXPECT_EQ(LayoutRect(0, 0, 10, 10), overflow_.ContentsVisualOverflowRect()); + visual_overflow_.AddContentsVisualOverflow(LayoutRect(0, 0, 10, 10)); + EXPECT_EQ(LayoutRect(0, 0, 10, 10), + visual_overflow_.ContentsVisualOverflowRect()); } TEST_F(BoxOverflowModelTest, AddContentsVisualOverflowUnitesRects) { - overflow_.AddContentsVisualOverflow(LayoutRect(0, 0, 10, 10)); - overflow_.AddContentsVisualOverflow(LayoutRect(80, 80, 10, 10)); - EXPECT_EQ(LayoutRect(0, 0, 90, 90), overflow_.ContentsVisualOverflowRect()); + visual_overflow_.AddContentsVisualOverflow(LayoutRect(0, 0, 10, 10)); + visual_overflow_.AddContentsVisualOverflow(LayoutRect(80, 80, 10, 10)); + EXPECT_EQ(LayoutRect(0, 0, 90, 90), + visual_overflow_.ContentsVisualOverflowRect()); } TEST_F(BoxOverflowModelTest, AddContentsVisualOverflowRectWithinRect) { - overflow_.AddContentsVisualOverflow(LayoutRect(0, 0, 10, 10)); - overflow_.AddContentsVisualOverflow(LayoutRect(2, 2, 5, 5)); - EXPECT_EQ(LayoutRect(0, 0, 10, 10), overflow_.ContentsVisualOverflowRect()); + visual_overflow_.AddContentsVisualOverflow(LayoutRect(0, 0, 10, 10)); + visual_overflow_.AddContentsVisualOverflow(LayoutRect(2, 2, 5, 5)); + EXPECT_EQ(LayoutRect(0, 0, 10, 10), + visual_overflow_.ContentsVisualOverflowRect()); } TEST_F(BoxOverflowModelTest, AddContentsVisualOverflowEmpty) { - overflow_.AddContentsVisualOverflow(LayoutRect(0, 0, 10, 10)); - overflow_.AddContentsVisualOverflow(LayoutRect(20, 20, 0, 0)); - EXPECT_EQ(LayoutRect(0, 0, 10, 10), overflow_.ContentsVisualOverflowRect()); + visual_overflow_.AddContentsVisualOverflow(LayoutRect(0, 0, 10, 10)); + visual_overflow_.AddContentsVisualOverflow(LayoutRect(20, 20, 0, 0)); + EXPECT_EQ(LayoutRect(0, 0, 10, 10), + visual_overflow_.ContentsVisualOverflowRect()); } TEST_F(BoxOverflowModelTest, MoveAffectsLayoutOverflow) { - overflow_.Move(LayoutUnit(500), LayoutUnit(100)); - EXPECT_EQ(LayoutRect(510, 110, 80, 80), overflow_.LayoutOverflowRect()); + layout_overflow_.Move(LayoutUnit(500), LayoutUnit(100)); + EXPECT_EQ(LayoutRect(510, 110, 80, 80), + layout_overflow_.LayoutOverflowRect()); } TEST_F(BoxOverflowModelTest, MoveAffectsSelfVisualOverflow) { - overflow_.Move(LayoutUnit(500), LayoutUnit(100)); - EXPECT_EQ(LayoutRect(500, 100, 100, 100), overflow_.SelfVisualOverflowRect()); + visual_overflow_.Move(LayoutUnit(500), LayoutUnit(100)); + EXPECT_EQ(LayoutRect(500, 100, 100, 100), + visual_overflow_.SelfVisualOverflowRect()); } TEST_F(BoxOverflowModelTest, MoveAffectsContentsVisualOverflow) { - overflow_.AddContentsVisualOverflow(LayoutRect(0, 0, 10, 10)); - overflow_.Move(LayoutUnit(500), LayoutUnit(100)); + visual_overflow_.AddContentsVisualOverflow(LayoutRect(0, 0, 10, 10)); + visual_overflow_.Move(LayoutUnit(500), LayoutUnit(100)); EXPECT_EQ(LayoutRect(500, 100, 10, 10), - overflow_.ContentsVisualOverflowRect()); + visual_overflow_.ContentsVisualOverflowRect()); } } // anonymous namespace
diff --git a/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptAutocomplete.js b/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptAutocomplete.js index 238c19d..7ecef0e 100644 --- a/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptAutocomplete.js +++ b/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptAutocomplete.js
@@ -489,7 +489,9 @@ 'queryObjects', '$', '$$', - '$x' + '$x', + '$0', + '$_' ]; propertyGroups.push({items: commandLineAPI}); }
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc index bae4be2d..c56a9567 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc
@@ -198,18 +198,6 @@ mojom::blink::QueryParamsPtr cache_query_params, ExceptionState& exception_state, bool match_all) { - // TODO(crbug.com/875201): Update this check once we remove the feature flag - // for active fetches. - if (result_ == mojom::BackgroundFetchResult::UNSET && - !RuntimeEnabledFeatures::BackgroundFetchAccessActiveFetchesEnabled()) { - return ScriptPromise::RejectWithDOMException( - script_state, - DOMException::Create( - DOMExceptionCode::kInvalidStateError, - "Access to records for in-progress background fetches is not yet " - "implemented. Please see crbug.com/875201 for more details.")); - } - if (!records_available_) { return ScriptPromise::RejectWithDOMException( script_state,
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth.cc index 2a8fd95..821d760 100644 --- a/third_party/blink/renderer/modules/bluetooth/bluetooth.cc +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
@@ -177,7 +177,14 @@ // If the algorithm is not allowed to show a popup, reject promise with a // SecurityError and abort these steps. auto& doc = *To<Document>(context); - if (!LocalFrame::HasTransientUserActivation(doc.GetFrame())) { + auto* frame = doc.GetFrame(); + if (!frame) { + return ScriptPromise::Reject( + script_state, V8ThrowException::CreateTypeError( + script_state->GetIsolate(), "Document not active")); + } + + if (!LocalFrame::HasTransientUserActivation(frame)) { return ScriptPromise::RejectWithDOMException( script_state, DOMException::Create( @@ -186,18 +193,9 @@ } if (!service_) { - LocalFrame* frame = doc.GetFrame(); - if (frame) { // See https://bit.ly/2S0zRAS for task types. frame->GetInterfaceProvider().GetInterface(mojo::MakeRequest( &service_, context->GetTaskRunner(TaskType::kMiscPlatformAPI))); - } - } - - if (!service_) { - return ScriptPromise::RejectWithDOMException( - script_state, - DOMException::Create(DOMExceptionCode::kNotSupportedError)); } // In order to convert the arguments from service names and aliases to just @@ -261,7 +259,14 @@ // If the algorithm is not allowed to show a popup, reject promise with a // SecurityError and abort these steps. auto& doc = *To<Document>(context); - if (!LocalFrame::HasTransientUserActivation(doc.GetFrame())) { + auto* frame = doc.GetFrame(); + if (!frame) { + return ScriptPromise::Reject( + script_state, V8ThrowException::CreateTypeError( + script_state->GetIsolate(), "Document not active")); + } + + if (!LocalFrame::HasTransientUserActivation(frame)) { return ScriptPromise::RejectWithDOMException( script_state, DOMException::Create( @@ -270,16 +275,9 @@ } if (!service_) { - LocalFrame* frame = doc.GetFrame(); - if (frame) { - frame->GetInterfaceProvider().GetInterface(mojo::MakeRequest(&service_)); - } - } - - if (!service_) { - return ScriptPromise::RejectWithDOMException( - script_state, - DOMException::Create(DOMExceptionCode::kNotSupportedError)); + // See https://bit.ly/2S0zRAS for task types. + frame->GetInterfaceProvider().GetInterface(mojo::MakeRequest( + &service_, context->GetTaskRunner(TaskType::kMiscPlatformAPI))); } // TODO(dougt) deal with |options| here. @@ -345,10 +343,6 @@ client_bindings_.CloseAllBindings(); } -void Bluetooth::Dispose() { - DCHECK(client_bindings_.empty()); -} - void Bluetooth::Trace(blink::Visitor* visitor) { visitor->Trace(device_instance_map_); EventTargetWithInlineData::Trace(visitor); @@ -358,6 +352,10 @@ Bluetooth::Bluetooth(ExecutionContext* context) : ContextLifecycleObserver(context) {} +Bluetooth::~Bluetooth() { + DCHECK(client_bindings_.empty()); +} + BluetoothDevice* Bluetooth::GetBluetoothDeviceRepresentingDevice( mojom::blink::WebBluetoothDevicePtr device_ptr, ExecutionContext* context) {
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth.h b/third_party/blink/renderer/modules/bluetooth/bluetooth.h index da428583..526f43d 100644 --- a/third_party/blink/renderer/modules/bluetooth/bluetooth.h +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth.h
@@ -22,7 +22,6 @@ class Bluetooth final : public EventTargetWithInlineData, public ContextLifecycleObserver, public mojom::blink::WebBluetoothScanClient { - USING_PRE_FINALIZER(Bluetooth, Dispose); DEFINE_WRAPPERTYPEINFO(); USING_GARBAGE_COLLECTED_MIXIN(Bluetooth); @@ -32,6 +31,7 @@ } explicit Bluetooth(ExecutionContext*); + ~Bluetooth() override; // IDL exposed interface: ScriptPromise requestDevice(ScriptState*, @@ -57,10 +57,6 @@ // ContextLifecycleObserver interface. void ContextDestroyed(ExecutionContext*) override; - // USING_PRE_FINALIZER interface. - // Called before the object gets garbage collected. - void Dispose(); - DEFINE_ATTRIBUTE_EVENT_LISTENER(advertisementreceived, kAdvertisementreceived);
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc index 5424377..0e7d1bb7 100644 --- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc +++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -598,10 +598,6 @@ RuntimeEnabledFeatures::SetBackgroundFetchEnabled(enable); } -void WebRuntimeFeatures::EnableBackgroundFetchAccessActiveFetches(bool enable) { - RuntimeEnabledFeatures::SetBackgroundFetchAccessActiveFetchesEnabled(enable); -} - void WebRuntimeFeatures::EnableBackgroundFetchUploads(bool enable) { RuntimeEnabledFeatures::SetBackgroundFetchUploadsEnabled(enable); }
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index b746e09..5b94d2f 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -118,10 +118,6 @@ status: "experimental", }, { - name: "BackgroundFetchAccessActiveFetches", - status: "experimental", - }, - { name: "BackgroundFetchUploads", status: "experimental", },
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index e4a88ba..08e021f 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -3222,14 +3222,11 @@ crbug.com/893480 external/wpt/infrastructure/testdriver/actions/elementTiming.html [ Timeout ] crbug.com/893480 external/wpt/infrastructure/testdriver/actions/multiDevice.html [ Failure Timeout ] -# wpt-importer has trouble rebaselining these tests. They might be flaky? -crbug.com/832501 external/wpt/webrtc/RTCPeerConnection-track-stats.https.html [ Failure ] -crbug.com/832501 virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCPeerConnection-track-stats.https.html [ Failure ] - # Hit a DCHECK crbug.com/918664 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/sizing/block-size-with-min-or-max-content-table-1a.html [ Failure Pass ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 external/wpt/css/css-backgrounds/border-image-calc.html [ Failure ] crbug.com/626703 external/wpt/css/css-text/boundary-shaping/boundary-shaping-005.html [ Failure ] crbug.com/626703 external/wpt/css/CSS2/text/white-space-nowrap-attribute-001.xht [ Failure ] crbug.com/626703 external/wpt/css/css-text/boundary-shaping/boundary-shaping-010.html [ Failure ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json index 4d94a9d2..c3ffc6a 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
@@ -5695,12 +5695,6 @@ {} ] ], - "pointerevents/pointerevent_boundary_events_at_implicit_release_hoverable_pointers-manual.html": [ - [ - "/pointerevents/pointerevent_boundary_events_at_implicit_release_hoverable_pointers-manual.html", - {} - ] - ], "pointerevents/pointerevent_boundary_events_in_capturing-manual.html": [ [ "/pointerevents/pointerevent_boundary_events_in_capturing-manual.html", @@ -5743,54 +5737,18 @@ {} ] ], - "pointerevents/pointerevent_lostpointercapture_for_disconnected_node-manual.html": [ - [ - "/pointerevents/pointerevent_lostpointercapture_for_disconnected_node-manual.html", - {} - ] - ], - "pointerevents/pointerevent_lostpointercapture_is_first-manual.html": [ - [ - "/pointerevents/pointerevent_lostpointercapture_is_first-manual.html", - {} - ] - ], "pointerevents/pointerevent_pointercancel_touch-manual.html": [ [ "/pointerevents/pointerevent_pointercancel_touch-manual.html", {} ] ], - "pointerevents/pointerevent_pointerenter_does_not_bubble-manual.html": [ - [ - "/pointerevents/pointerevent_pointerenter_does_not_bubble-manual.html", - {} - ] - ], "pointerevents/pointerevent_pointerleave_after_pointercancel_touch-manual.html": [ [ "/pointerevents/pointerevent_pointerleave_after_pointercancel_touch-manual.html", {} ] ], - "pointerevents/pointerevent_pointerleave_descendant_over-manual.html": [ - [ - "/pointerevents/pointerevent_pointerleave_descendant_over-manual.html", - {} - ] - ], - "pointerevents/pointerevent_pointerleave_descendants-manual.html": [ - [ - "/pointerevents/pointerevent_pointerleave_descendants-manual.html", - {} - ] - ], - "pointerevents/pointerevent_pointerleave_does_not_bubble-manual.html": [ - [ - "/pointerevents/pointerevent_pointerleave_does_not_bubble-manual.html", - {} - ] - ], "pointerevents/pointerevent_pointerleave_pen-manual.html": [ [ "/pointerevents/pointerevent_pointerleave_pen-manual.html", @@ -5803,36 +5761,18 @@ {} ] ], - "pointerevents/pointerevent_pointerout_received_once-manual.html": [ - [ - "/pointerevents/pointerevent_pointerout_received_once-manual.html", - {} - ] - ], "pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html": [ [ "/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html", {} ] ], - "pointerevents/pointerevent_releasepointercapture_invalid_pointerid-manual.html": [ - [ - "/pointerevents/pointerevent_releasepointercapture_invalid_pointerid-manual.html", - {} - ] - ], "pointerevents/pointerevent_releasepointercapture_onpointercancel_touch-manual.html": [ [ "/pointerevents/pointerevent_releasepointercapture_onpointercancel_touch-manual.html", {} ] ], - "pointerevents/pointerevent_releasepointercapture_onpointerup_mouse-manual.html": [ - [ - "/pointerevents/pointerevent_releasepointercapture_onpointerup_mouse-manual.html", - {} - ] - ], "pointerevents/pointerevent_sequence_at_implicit_release_on_click-manual.html": [ [ "/pointerevents/pointerevent_sequence_at_implicit_release_on_click-manual.html", @@ -5845,36 +5785,6 @@ {} ] ], - "pointerevents/pointerevent_setpointercapture_disconnected-manual.html": [ - [ - "/pointerevents/pointerevent_setpointercapture_disconnected-manual.html", - {} - ] - ], - "pointerevents/pointerevent_setpointercapture_invalid_pointerid-manual.html": [ - [ - "/pointerevents/pointerevent_setpointercapture_invalid_pointerid-manual.html", - {} - ] - ], - "pointerevents/pointerevent_setpointercapture_relatedtarget-manual.html": [ - [ - "/pointerevents/pointerevent_setpointercapture_relatedtarget-manual.html", - {} - ] - ], - "pointerevents/pointerevent_suppress_compat_events_on_click-manual.html": [ - [ - "/pointerevents/pointerevent_suppress_compat_events_on_click-manual.html", - {} - ] - ], - "pointerevents/pointerevent_suppress_compat_events_on_drag_mouse-manual.html": [ - [ - "/pointerevents/pointerevent_suppress_compat_events_on_drag_mouse-manual.html", - {} - ] - ], "pointerevents/pointerevent_touch-action-auto-css_touch-manual.html": [ [ "/pointerevents/pointerevent_touch-action-auto-css_touch-manual.html", @@ -34199,6 +34109,18 @@ {} ] ], + "css/css-backgrounds/border-image-calc.html": [ + [ + "/css/css-backgrounds/border-image-calc.html", + [ + [ + "/css/css-backgrounds/border-image-calc-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-backgrounds/border-image-outset-003.html": [ [ "/css/css-backgrounds/border-image-outset-003.html", @@ -71403,6 +71325,18 @@ {} ] ], + "css/css-transforms/size-change-under-backface-visibility-hidden.html": [ + [ + "/css/css-transforms/size-change-under-backface-visibility-hidden.html", + [ + [ + "/css/css-transforms/size-change-under-backface-visibility-hidden-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-transforms/skew-test1.html": [ [ "/css/css-transforms/skew-test1.html", @@ -125011,6 +124945,11 @@ {} ] ], + "css/css-backgrounds/border-image-calc-ref.html": [ + [ + {} + ] + ], "css/css-backgrounds/border-image-outset-003-ref.html": [ [ {} @@ -143866,6 +143805,11 @@ {} ] ], + "css/css-transforms/size-change-under-backface-visibility-hidden-ref.html": [ + [ + {} + ] + ], "css/css-transforms/skewX/reference/svg-skewx-ref.html": [ [ {} @@ -159171,6 +159115,11 @@ {} ] ], + "fonts/Ahem.ttf.headers": [ + [ + {} + ] + ], "fonts/CSSTest/LICENSE": [ [ {} @@ -179116,6 +179065,11 @@ {} ] ], + "resource-timing/no-entries-for-cross-origin-css-fetched.sub-expected.txt": [ + [ + {} + ] + ], "resource-timing/resource-timing-level1.js": [ [ {} @@ -260887,6 +260841,14 @@ {} ] ], + "pointerevents/pointerevent_boundary_events_at_implicit_release_hoverable_pointers.html": [ + [ + "/pointerevents/pointerevent_boundary_events_at_implicit_release_hoverable_pointers.html", + { + "testdriver": true + } + ] + ], "pointerevents/pointerevent_capture_mouse.html": [ [ "/pointerevents/pointerevent_capture_mouse.html", @@ -260901,12 +260863,60 @@ {} ] ], + "pointerevents/pointerevent_lostpointercapture_for_disconnected_node.html": [ + [ + "/pointerevents/pointerevent_lostpointercapture_for_disconnected_node.html", + { + "testdriver": true + } + ] + ], + "pointerevents/pointerevent_lostpointercapture_is_first.html": [ + [ + "/pointerevents/pointerevent_lostpointercapture_is_first.html", + { + "testdriver": true + } + ] + ], "pointerevents/pointerevent_on_event_handlers.html": [ [ "/pointerevents/pointerevent_on_event_handlers.html", {} ] ], + "pointerevents/pointerevent_pointerenter_does_not_bubble.html": [ + [ + "/pointerevents/pointerevent_pointerenter_does_not_bubble.html", + { + "testdriver": true + } + ] + ], + "pointerevents/pointerevent_pointerleave_descendant_over.html": [ + [ + "/pointerevents/pointerevent_pointerleave_descendant_over.html", + { + "testdriver": true + } + ] + ], + "pointerevents/pointerevent_pointerleave_descendants.html": [ + [ + "/pointerevents/pointerevent_pointerleave_descendants.html", + { + "testdriver": true + } + ] + ], + "pointerevents/pointerevent_pointerleave_does_not_bubble.html": [ + [ + "/pointerevents/pointerevent_pointerleave_does_not_bubble.html", + { + "testdriver": true + } + ] + ], "pointerevents/pointerevent_pointermove.html": [ [ "/pointerevents/pointerevent_pointermove.html", @@ -260939,6 +260949,30 @@ } ] ], + "pointerevents/pointerevent_pointerout_received_once.html": [ + [ + "/pointerevents/pointerevent_pointerout_received_once.html", + { + "testdriver": true + } + ] + ], + "pointerevents/pointerevent_releasepointercapture_invalid_pointerid.html": [ + [ + "/pointerevents/pointerevent_releasepointercapture_invalid_pointerid.html", + { + "testdriver": true + } + ] + ], + "pointerevents/pointerevent_releasepointercapture_onpointerup_mouse.html": [ + [ + "/pointerevents/pointerevent_releasepointercapture_onpointerup_mouse.html", + { + "testdriver": true + } + ] + ], "pointerevents/pointerevent_root_computed_style.html": [ [ "/pointerevents/pointerevent_root_computed_style.html", @@ -260951,6 +260985,14 @@ {} ] ], + "pointerevents/pointerevent_setpointercapture_disconnected.html": [ + [ + "/pointerevents/pointerevent_setpointercapture_disconnected.html", + { + "testdriver": true + } + ] + ], "pointerevents/pointerevent_setpointercapture_inactive_button_mouse.html": [ [ "/pointerevents/pointerevent_setpointercapture_inactive_button_mouse.html", @@ -260959,6 +261001,38 @@ } ] ], + "pointerevents/pointerevent_setpointercapture_invalid_pointerid.html": [ + [ + "/pointerevents/pointerevent_setpointercapture_invalid_pointerid.html", + { + "testdriver": true + } + ] + ], + "pointerevents/pointerevent_setpointercapture_relatedtarget.html": [ + [ + "/pointerevents/pointerevent_setpointercapture_relatedtarget.html", + { + "testdriver": true + } + ] + ], + "pointerevents/pointerevent_suppress_compat_events_on_click.html": [ + [ + "/pointerevents/pointerevent_suppress_compat_events_on_click.html", + { + "testdriver": true + } + ] + ], + "pointerevents/pointerevent_suppress_compat_events_on_drag_mouse.html": [ + [ + "/pointerevents/pointerevent_suppress_compat_events_on_drag_mouse.html", + { + "testdriver": true + } + ] + ], "pointerevents/pointerevent_touch-action-illegal.html": [ [ "/pointerevents/pointerevent_touch-action-illegal.html", @@ -260983,6 +261057,12 @@ {} ] ], + "portals/portals-host-null.html": [ + [ + "/portals/portals-host-null.html", + {} + ] + ], "portals/portals-no-referrer.html": [ [ "/portals/portals-no-referrer.html", @@ -271659,6 +271739,12 @@ {} ] ], + "resource-timing/no-entries-for-cross-origin-css-fetched.sub.html": [ + [ + "/resource-timing/no-entries-for-cross-origin-css-fetched.sub.html", + {} + ] + ], "resource-timing/resource-timing-level1.sub.html": [ [ "/resource-timing/resource-timing-level1.sub.html", @@ -300955,7 +301041,7 @@ "testharness" ], "IndexedDB/keypath-special-identifiers.htm": [ - "cb64d0b708eb3f97d99b0b754fcdf9bd12394821", + "0692bed32ce54b4dc666fd76d5fa06c523a06a5a", "testharness" ], "IndexedDB/keypath.htm": [ @@ -321191,7 +321277,7 @@ "support" ], "css/CSS2/stacking-context/opacity-change-parent-stacking-context.html": [ - "36033e926bc5663ba9bb72d2f9fbe1ce8244ba07", + "94587c5f6e21b92ab7ab1d5ca3b447eb2bdab15b", "reftest" ], "css/CSS2/support/100x100-lime.png": [ @@ -327106,6 +327192,14 @@ "5d805ec7527111006a0a6b24a71ef85606d1a91e", "visual" ], + "css/css-backgrounds/border-image-calc-ref.html": [ + "f827ca7fd0b9f4e1e06334fcb475e38938a29237", + "support" + ], + "css/css-backgrounds/border-image-calc.html": [ + "c8bc4c7c9a092b57a5119ebf02f9972b9386b965", + "reftest" + ], "css/css-backgrounds/border-image-image-type-001.htm": [ "ebc152fe74bd165b68cda0953ce3ef5545aa998d", "visual" @@ -360282,6 +360376,14 @@ "b1e0e8b14b6df8df2d135a0032822b1489b73b1e", "reftest" ], + "css/css-transforms/size-change-under-backface-visibility-hidden-ref.html": [ + "e9362c35745416a4ca19a9ab0bf92dd69afb8634", + "support" + ], + "css/css-transforms/size-change-under-backface-visibility-hidden.html": [ + "1543eeb3da3e0efb58239097fe486f1ca85d7c63", + "reftest" + ], "css/css-transforms/skew-test1.html": [ "1f366673488b1a1a4cc2f95096f57a9ef358a23e", "reftest" @@ -392822,6 +392924,10 @@ "4d4785a4123287a5ca08439a6230514de91df0e7", "support" ], + "fonts/Ahem.ttf.headers": [ + "cb762eff806849df46dc758ef7b98b63f27f54c9", + "support" + ], "fonts/CSSTest/LICENSE": [ "9b3c1a6df54771041e357b1ed65aee572dc97bed", "support" @@ -426538,9 +426644,9 @@ "0fd7904ef0041cb555d291ee60b8288bb5df7925", "manual" ], - "pointerevents/pointerevent_boundary_events_at_implicit_release_hoverable_pointers-manual.html": [ - "62a0a6d5a4a253a337aa9d130ee4a943df3bebd3", - "manual" + "pointerevents/pointerevent_boundary_events_at_implicit_release_hoverable_pointers.html": [ + "e860cd082bede68aa014fe36ceff011e8227e2ad", + "testharness" ], "pointerevents/pointerevent_boundary_events_in_capturing-manual.html": [ "0de4d55ed13ed67229cc4a6a0f77635fad815d01", @@ -426578,13 +426684,13 @@ "e0e2fdcd62175c325e43744e43addc5f45486159", "manual" ], - "pointerevents/pointerevent_lostpointercapture_for_disconnected_node-manual.html": [ - "f4fe2b424e6e837a1e0e1ea625ede17619e797b4", - "manual" + "pointerevents/pointerevent_lostpointercapture_for_disconnected_node.html": [ + "de22b2b5a552cce0bfc988d1754943c568feed72", + "testharness" ], - "pointerevents/pointerevent_lostpointercapture_is_first-manual.html": [ - "9e460b872e22474f7aa897b9295299d405c2931f", - "manual" + "pointerevents/pointerevent_lostpointercapture_is_first.html": [ + "6ce0f3e59a04db4ecf23d9fd60b57164ceb67f85", + "testharness" ], "pointerevents/pointerevent_on_event_handlers.html": [ "d8cfa7a0f4c482be606e4e98f9a7900a0340a477", @@ -426594,25 +426700,25 @@ "70a65eeb5ca4a340aff4a74873e12e869a07ac48", "manual" ], - "pointerevents/pointerevent_pointerenter_does_not_bubble-manual.html": [ - "3f0583364a22edfc07ae6643c0934a5cbb8f2e92", - "manual" + "pointerevents/pointerevent_pointerenter_does_not_bubble.html": [ + "7d38de7446938de3715b19f4585d747a18912d77", + "testharness" ], "pointerevents/pointerevent_pointerleave_after_pointercancel_touch-manual.html": [ "56be26549f8fc9bed9836114569261f7252b3799", "manual" ], - "pointerevents/pointerevent_pointerleave_descendant_over-manual.html": [ - "8f4f4bfc7a13116507b9241dcaab4519dab88ea6", - "manual" + "pointerevents/pointerevent_pointerleave_descendant_over.html": [ + "ccc5f37477cc8eabc3effa75d45f2f45d7ea31f5", + "testharness" ], - "pointerevents/pointerevent_pointerleave_descendants-manual.html": [ - "ac9edcff38a79814d9041b093205790e9beabd41", - "manual" + "pointerevents/pointerevent_pointerleave_descendants.html": [ + "fe121a8409d802f26e97bd6c5f788397d7267aa2", + "testharness" ], - "pointerevents/pointerevent_pointerleave_does_not_bubble-manual.html": [ - "c0e551cd658101035d3ac9f7b1511ebfdcc93b33", - "manual" + "pointerevents/pointerevent_pointerleave_does_not_bubble.html": [ + "b19820ebd3df673846710887f5c13fdf01b60de7", + "testharness" ], "pointerevents/pointerevent_pointerleave_pen-manual.html": [ "bb6dcc4236b0cc5183855275d85208db6460a5cb", @@ -426638,25 +426744,25 @@ "972f99d95080ab702da79f8125119a2b27778a84", "testharness" ], - "pointerevents/pointerevent_pointerout_received_once-manual.html": [ - "4827ae91de1ba6307465ce3938ec95cead1c3c5c", - "manual" + "pointerevents/pointerevent_pointerout_received_once.html": [ + "c76e1c57456111fb78cc230c27b34d2511fe3083", + "testharness" ], "pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html": [ "89f3d839f46d9982130d6aec3c9c0ed75862bfa4", "manual" ], - "pointerevents/pointerevent_releasepointercapture_invalid_pointerid-manual.html": [ - "d0cf3671743a85e6b76015c1baab4864253148be", - "manual" + "pointerevents/pointerevent_releasepointercapture_invalid_pointerid.html": [ + "75351dfb0689418537e6b20d92ac60feae0da2fb", + "testharness" ], "pointerevents/pointerevent_releasepointercapture_onpointercancel_touch-manual.html": [ "497840041f6b6f67326bede1fbfef442f403f7b7", "manual" ], - "pointerevents/pointerevent_releasepointercapture_onpointerup_mouse-manual.html": [ - "24fe40d5834b71247d19ce9aa0d35ceb74ca52fa", - "manual" + "pointerevents/pointerevent_releasepointercapture_onpointerup_mouse.html": [ + "23c28b4bf755e493d747f7814a21aa598f4f0d8c", + "testharness" ], "pointerevents/pointerevent_root_computed_style.html": [ "c3034d475eee8c58ed1b079fce9466925c5d0379", @@ -426674,21 +426780,21 @@ "982167dc5014d06c0babd3222696c8ba556d882e", "manual" ], - "pointerevents/pointerevent_setpointercapture_disconnected-manual.html": [ - "9e9646525fad99c841fee7233fd1989682fd131d", - "manual" + "pointerevents/pointerevent_setpointercapture_disconnected.html": [ + "a7cc3e00e23f1544cdb81762025929a194df0f75", + "testharness" ], "pointerevents/pointerevent_setpointercapture_inactive_button_mouse.html": [ "7d0b00d47bc276dbba5ae3076bfbed0a912ea327", "testharness" ], - "pointerevents/pointerevent_setpointercapture_invalid_pointerid-manual.html": [ - "e2b143fe4a57c1585d96ec4ee29aa82ed0ae4dba", - "manual" + "pointerevents/pointerevent_setpointercapture_invalid_pointerid.html": [ + "3180ca53f5582b78514d94ccadfdbc1a7c6d84bc", + "testharness" ], - "pointerevents/pointerevent_setpointercapture_relatedtarget-manual.html": [ - "bc1bb93c7168764dd8d1ae7ea96fdc1cf3c0add7", - "manual" + "pointerevents/pointerevent_setpointercapture_relatedtarget.html": [ + "acbd7f6a5c50722e06bed529d67ab83c4f7844c3", + "testharness" ], "pointerevents/pointerevent_styles.css": [ "1ee3b0b3965ff9fb3c5960f606cca6477ce145a8", @@ -426698,13 +426804,13 @@ "5c35e016a0ed51353868e0307af0896c62db64de", "support" ], - "pointerevents/pointerevent_suppress_compat_events_on_click-manual.html": [ - "71b8a08289ada60d91884356919eb2e6ebab63b8", - "manual" + "pointerevents/pointerevent_suppress_compat_events_on_click.html": [ + "77b5daaed41ad29d3dce34cfde57edb4667d5ea7", + "testharness" ], - "pointerevents/pointerevent_suppress_compat_events_on_drag_mouse-manual.html": [ - "8afa04634bbddd9561172bcb6997b44c994014f3", - "manual" + "pointerevents/pointerevent_suppress_compat_events_on_drag_mouse.html": [ + "5bab6e66121cebc47213914fb07f7995d8b0722d", + "testharness" ], "pointerevents/pointerevent_touch-action-auto-css_touch-manual.html": [ "f5e9d12c353902852670524181df5bbdf48425df", @@ -426910,6 +427016,10 @@ "29134d490f7bdfb09255e190fe91576629057c78", "support" ], + "portals/portals-host-null.html": [ + "e0f1d63743c54c687d62f86abe278873fa823430", + "testharness" + ], "portals/portals-no-referrer.html": [ "0386272f441a0c2e19452821968a624d3ab16700", "testharness" @@ -436907,7 +437017,7 @@ "support" ], "resource-timing/buffer-full-add-after-full-event.html": [ - "07897b5d28dfb281463dc49dc5481d2a1de187b5", + "73ad841e92fddff1e05395241d69a0079e7a84da", "testharness" ], "resource-timing/buffer-full-add-entries-during-callback-that-drop.html": [ @@ -436958,6 +437068,14 @@ "a7542f191c10ea7b42110b5fc80e7abf43174bb5", "testharness" ], + "resource-timing/no-entries-for-cross-origin-css-fetched.sub-expected.txt": [ + "a256bb2dc766a40f21115049572246bf003499ba", + "support" + ], + "resource-timing/no-entries-for-cross-origin-css-fetched.sub.html": [ + "92d94a17ec0df642b0a500dbd9fb5aa06eaacb64", + "testharness" + ], "resource-timing/resource-timing-level1.js": [ "6c63eff7b297c8ec05b917b6bca55e3e622d3448", "support" @@ -437231,7 +437349,7 @@ "support" ], "resource-timing/resources/webperftestharnessextension.js": [ - "230f2ac6769d745a7647b16b13d8c6e96fc982b1", + "901cb1db8284a967e87e93afb9da8752fa7a2a7f", "support" ], "resource-timing/resources/worker_with_images.js": [ @@ -454287,7 +454405,7 @@ "support" ], "webxr/idlharness.https.window-expected.txt": [ - "27484b4ad784a35100c15fb14836ede5896d1f58", + "4eb2240f492e8e4d3dab067941de1ff72716ca52", "support" ], "webxr/idlharness.https.window.js": [ @@ -454375,15 +454493,15 @@ "testharness" ], "webxr/xrSession_requestAnimationFrame_data_valid.https.html": [ - "4093d7afdb3ad08533521ffb096a92a461c13747", + "5f825fa3d58314479c08716616558666b6eac211", "testharness" ], "webxr/xrSession_requestAnimationFrame_getViewerPose.https.html": [ - "c6d5c1024fbadfa95af7a70216b2338fc43aef1b", + "17b5307f019dc7ec4696dbceef5eb3d5cd21d361", "testharness" ], "webxr/xrSession_requestReferenceSpace.https.html": [ - "ea758761e59de144a742019cc386b083639db6c9", + "d97852c917bc8f42f4999e5b0d1c13a7fef364ab", "testharness" ], "workers/META.yml": [
diff --git a/third_party/blink/web_tests/external/wpt/IndexedDB/keypath-special-identifiers.htm b/third_party/blink/web_tests/external/wpt/IndexedDB/keypath-special-identifiers.htm index cb64d0b..0692bed 100644 --- a/third_party/blink/web_tests/external/wpt/IndexedDB/keypath-special-identifiers.htm +++ b/third_party/blink/web_tests/external/wpt/IndexedDB/keypath-special-identifiers.htm
@@ -54,6 +54,8 @@ const result = request.result; assert_key_equals(result[testcase.property], key, 'Property should be used as key'); + }); + tx.oncomplete = t.step_func(function() { t.done(); }); },
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-calc-ref.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-calc-ref.html new file mode 100644 index 0000000..f827ca7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-calc-ref.html
@@ -0,0 +1,13 @@ +<!doctype html> +<title>CSS Test Reference</title> +<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io"> +<link rel="author" title="Mozilla" href="https://mozilla.org"> +<style> + #test { + background-color: green; + width: 200px; + height: 200px; + } +</style> +<p>Test passes if there is a green 200px times 200px square.</p> +<div id="test"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-calc.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-calc.html new file mode 100644 index 0000000..c8bc4c7c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-calc.html
@@ -0,0 +1,20 @@ +<!doctype html> +<title>CSS Test: border-image honors calc() lengths / percentages</title> +<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io"> +<link rel="author" title="Mozilla" href="https://mozilla.org"> +<link rel="help" href="https://bugzil.la/1517521"> +<link rel="help" href="https://drafts.csswg.org/css-backgrounds/#border-image-width"> +<link rel="match" href="border-image-calc-ref.html"> +<style> + #test { + background-color: red; + border: 100px solid red; + border-image-slice: 10; + border-image-source: url("support/green_color.png"); + border-image-width: 100px calc(100px) calc(100%) calc(50% + 50px); + height: 0; + width: 0; + } +</style> +<p>Test passes if there is a green 200px times 200px square.</p> +<div id="test"></div>
diff --git a/third_party/blink/web_tests/external/wpt/fonts/Ahem.ttf.headers b/third_party/blink/web_tests/external/wpt/fonts/Ahem.ttf.headers new file mode 100644 index 0000000..cb762eff --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fonts/Ahem.ttf.headers
@@ -0,0 +1 @@ +Access-Control-Allow-Origin: *
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-add-after-full-event.html b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-add-after-full-event.html index 07897b5d2..73ad841 100644 --- a/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-add-after-full-event.html +++ b/third_party/blink/web_tests/external/wpt/resource-timing/buffer-full-add-after-full-event.html
@@ -72,6 +72,9 @@ await loadRandomResource(); await waitForEventToFire(); await clearAndAddAnotherEntryToBuffer(); + // Since we have no strict guarantees when an entry will be added to the + // buffer, waiting till next task to try to avoid flakiness. + await waitForNextTask(); await testThatEntryWasAdded(); }, "Test that entry was added to the buffer after a buffer full event"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/no-entries-for-cross-origin-css-fetched.sub-expected.txt b/third_party/blink/web_tests/external/wpt/resource-timing/no-entries-for-cross-origin-css-fetched.sub-expected.txt new file mode 100644 index 0000000..a256bb2 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/resource-timing/no-entries-for-cross-origin-css-fetched.sub-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Make sure that resources fetched by cross origin CSS are not in the timeline. assert_equals: Import should not be in timeline expected 0 but got 1 +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/no-entries-for-cross-origin-css-fetched.sub.html b/third_party/blink/web_tests/external/wpt/resource-timing/no-entries-for-cross-origin-css-fetched.sub.html new file mode 100644 index 0000000..92d94a1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/resource-timing/no-entries-for-cross-origin-css-fetched.sub.html
@@ -0,0 +1,25 @@ +<!DOCTYPE HTML> +<meta charset=utf-8> +<title>Make sure that resources fetched by cross origin CSS are not in the timeline.</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<body> +<!-- The stylesheet is fetched from http://www1.web–platform.test:64941/resource-timing/resources/nested.css --> +<link rel=stylesheet id=cross_origin_style href="//{{domains[www1]}}:{{ports[http][1]}}{{location[path]}}/../resources/nested.css"> +<script> + const t = async_test("Make sure that resources fetched by cross origin CSS are not in the timeline."); + window.addEventListener("load", function() { + // A timeout is needed as entries are not guaranteed to be in the timeline before onload triggers. + t.step_timeout(function() { + const url = (new URL(document.getElementById("cross_origin_style").href)); + const prefix = url.protocol + "//" + url.host; + assert_equals(performance.getEntriesByName(prefix + "/resource-timing/resources/resource_timing_test0.css?id=n1").length, 0, "Import should not be in timeline"); + assert_equals(performance.getEntriesByName(prefix + "/fonts/Ahem.ttf?id=n1").length, 0, "Font should not be in timeline"); + assert_equals(performance.getEntriesByName(prefix + "/resource-timing/resources/blue.png?id=n1").length, 0, "Image should not be in timeline"); + t.done(); + },100); + }); +</script> +<ol>Some content</ol> +</body> +
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/resources/webperftestharnessextension.js b/third_party/blink/web_tests/external/wpt/resource-timing/resources/webperftestharnessextension.js index 230f2ac6..901cb1db 100644 --- a/third_party/blink/web_tests/external/wpt/resource-timing/resources/webperftestharnessextension.js +++ b/third_party/blink/web_tests/external/wpt/resource-timing/resources/webperftestharnessextension.js
@@ -49,45 +49,48 @@ function test_resource_entries(entries, expected_entries) { - // This is slightly convoluted so that we can sort the output. - var actual_entries = {}; - var origin = window.location.protocol + "//" + window.location.host; + test(function() { + // This is slightly convoluted so that we can sort the output. + var actual_entries = {}; + var origin = window.location.protocol + "//" + window.location.host; - for (var i = 0; i < entries.length; ++i) { - var entry = entries[i]; - var found = false; - for (var expected_entry in expected_entries) { - if (entry.name == origin + expected_entry) { - found = true; - if (expected_entry in actual_entries) { - test_fail(expected_entry + ' is not expected to have duplicate entries'); + for (var i = 0; i < entries.length; ++i) { + var entry = entries[i]; + var found = false; + for (var expected_entry in expected_entries) { + if (entry.name == origin + expected_entry) { + found = true; + if (expected_entry in actual_entries) { + assert_unreached(expected_entry + ' is not expected to have duplicate entries'); + } + actual_entries[expected_entry] = entry; + break; } - actual_entries[expected_entry] = entry; - break; + } + if (!found) { + assert_unreached(entries[i].name + ' is not expected to be in the Resource Timing buffer'); } } - if (!found) { - test_fail(entries[i].name + ' is not expected to be in the Resource Timing buffer'); - } - } - sorted_urls = []; - for (var i in actual_entries) { - sorted_urls.push(i); - } - sorted_urls.sort(); - for (var i in sorted_urls) { - var url = sorted_urls[i]; - test_equals(actual_entries[url].initiatorType, - expected_entries[url], - origin + url + ' is expected to have initiatorType ' + expected_entries[url]); - } - for (var j in expected_entries) { - if (!(j in actual_entries)) { - test_fail(origin + j + ' is expected to be in the Resource Timing buffer'); + sorted_urls = []; + for (var i in actual_entries) { + sorted_urls.push(i); } - } + sorted_urls.sort(); + for (var i in sorted_urls) { + var url = sorted_urls[i]; + assert_equals(actual_entries[url].initiatorType, + expected_entries[url], + origin + url + ' is expected to have initiatorType ' + expected_entries[url]); + } + for (var j in expected_entries) { + if (!(j in actual_entries)) { + assert_unreached(origin + j + ' is expected to be in the Resource Timing buffer'); + } + } + }, "Testing resource entries"); } + function performance_entrylist_checker(type) { var entryType = type;
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-remote-track-mute.https.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-remote-track-mute.https.html index 56fe7614..095fe50 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-remote-track-mute.https.html +++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-remote-track-mute.https.html
@@ -39,7 +39,7 @@ }); }); await exchangeOfferAnswer(pc1, pc2); - await unmuteResolver.promise; + await unmuteResolver; }, 'ontrack: track goes from muted to unmuted'); promise_test(async t => {
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https-expected.txt index c220136..4eb476d 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https-expected.txt
@@ -2,7 +2,7 @@ FAIL addTrack() with a track and no stream makes ontrack fire with a track and no stream. assert_equals: No remote stream created. expected 0 but got 1 PASS addTrack() with a track and a stream makes ontrack fire with a track and a stream. PASS ontrack fires before setRemoteDescription resolves. -FAIL addTrack() with two tracks and one stream makes ontrack fire twice with the tracks and shared stream. promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'track' of undefined" +PASS addTrack() with two tracks and one stream makes ontrack fire twice with the tracks and shared stream. PASS addTrack() for an existing stream makes stream.onaddtrack fire. PASS stream.onaddtrack fires before setRemoteDescription resolves. FAIL addTrack() with a track and two streams makes ontrack fire with a track and two streams. promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'addTrack' on 'RTCPeerConnection': Adding a track to multiple streams is not supported."
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html index aa3f93e..7c565dd 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html +++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html
@@ -95,7 +95,7 @@ ontrackEventResolvers[ontrackEventsFired++].resolve(e); }); await exchangeOffer(caller, callee); - let firstTrackEvent = await ontrackEventResolvers[0].promise; + let firstTrackEvent = await ontrackEventResolvers[0]; assert_equals(firstTrackEvent.track.id, localStreams[0].getTracks()[0].id, 'First ontrack\'s track ID matches first local track.'); @@ -104,7 +104,7 @@ assert_equals(firstTrackEvent.streams[0].id, localStreams[0].id, 'First ontrack\'s stream ID matches local stream.'); - let secondTrackEvent = await ontrackEventResolvers[1].promise; + let secondTrackEvent = await ontrackEventResolvers[1]; assert_equals(secondTrackEvent.track.id, localStreams[1].getTracks()[0].id, 'Second ontrack\'s track ID matches second local track.');
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-track-stats.https-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-track-stats.https-expected.txt new file mode 100644 index 0000000..bd8e844 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-track-stats.https-expected.txt
@@ -0,0 +1,21 @@ +This is a testharness.js-based test. +PASS addTrack() without setLocalDescription() yields track stats +PASS addTrack() without setLocalDescription() yields media stream stats +PASS addTrack() with setLocalDescription() yields track stats +PASS addTrack() with setLocalDescription() yields media stream stats +PASS addTrack(): Media stream stats references track stats +PASS Media stream stats references track stats +PASS O/A exchange yields outbound RTP stream stats for sending track +PASS O/A exchange yields inbound RTP stream stats for receiving track +PASS replaceTrack() before offer: new track attachment stats present +PASS replaceTrack() after offer, before answer: new track attachment stats present +PASS replaceTrack() after answer: new track attachment stats present +FAIL replaceTrack(): original track attachment stats present after replacing assert_true: Has stats for original track expected true got false +PASS RTCRtpSender.getStats() contains only outbound-rtp and related stats +PASS RTCRtpReceiver.getStats() contains only inbound-rtp and related stats +PASS RTCPeerConnection.getStats(sendingTrack) is the same as RTCRtpSender.getStats() +PASS RTCPeerConnection.getStats(receivingTrack) is the same as RTCRtpReceiver.getStats() +PASS RTCPeerConnection.getStats(track) throws InvalidAccessError when there are zero senders or receivers for the track +PASS RTCPeerConnection.getStats(track) throws InvalidAccessError when there are multiple senders for the track +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-track-stats.https.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-track-stats.https.html index 30c368f..2d45c34 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-track-stats.https.html +++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-track-stats.https.html
@@ -618,7 +618,7 @@ resolver.resolve(); } }; - return resolver.promise; + return resolver; } // Explores the stats graph starting from |stat|, validating each stat
diff --git a/third_party/blink/web_tests/virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https-expected.txt b/third_party/blink/web_tests/virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https-expected.txt index f84b73061..0505a96f 100644 --- a/third_party/blink/web_tests/virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https-expected.txt +++ b/third_party/blink/web_tests/virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https-expected.txt
@@ -2,7 +2,7 @@ PASS addTrack() with a track and no stream makes ontrack fire with a track and no stream. PASS addTrack() with a track and a stream makes ontrack fire with a track and a stream. PASS ontrack fires before setRemoteDescription resolves. -FAIL addTrack() with two tracks and one stream makes ontrack fire twice with the tracks and shared stream. promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'track' of undefined" +PASS addTrack() with two tracks and one stream makes ontrack fire twice with the tracks and shared stream. PASS addTrack() for an existing stream makes stream.onaddtrack fire. PASS stream.onaddtrack fires before setRemoteDescription resolves. PASS addTrack() with a track and two streams makes ontrack fire with a track and two streams.
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 75851ae..f2d34736 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -40767,6 +40767,44 @@ <int value="1" label="From Android"/> </enum> +<enum name="PasswordManagerFirstRendererFillingResult"> + <int value="0" label="Success"/> + <int value="1" label="No password element"> + Filling only happens in iframes, if all parent frames PSL match the security + origin of the iframe containing the password field. + </int> + <int value="2" label="Blocked by frame hierarchy"> + Passwords are not filled into fields that are not editable. + </int> + <int value="3" label="Password element is not autocompleteable"> + The username field contains a string that does not match the username of any + available credential + </int> + <int value="4" label="Username prefilled with incompatible value"> + The site had no password for the presented username (e.g. username field is + empty and readonly). + </int> + <int value="5" label="Found no password for username"> + No credential was filled due to mismatches with the username. This can + happen in a number of cases: In case the username field is empty and + readonly. In case of a username-first-flow where a user's credentials do + contain a username but the form contains only a password field and no + username field. In case of change password forms that contain no username + field. In case the user name is given on a page but only PSL matched + credentials exist for this username. There may be further cases. + </int> + <int value="6" label="Wait for username"> + Renderer was instructed to wait until user has manually picked a credential. + This happens for example if the session is an incognito session, the + credendial's URL matches the mainframe only via the PSL, the site is on + HTTP, or the form has no current password field. TODO(crbug.com/918846): + Record root causes in a separate histogram. + </int> + <int value="7" label="No fillable elements found"> + No fillable elements were found, only possible for the old form parser. + </int> +</enum> + <enum name="PasswordManagerHttpCredentialType"> <summary> This enum records the type of a given HTTP credential. Depending on its @@ -47976,6 +48014,12 @@ <int value="2" label="Miss"/> </enum> +<enum name="SimpleCachePrefetchMode"> + <int value="0" label="None"/> + <int value="1" label="Full"/> + <int value="2" label="Trailer"/> +</enum> + <enum name="SimpleCacheReadParallelizable"> <int value="0" label="Standalone Read (obsolete)"/> <int value="1" label="Follows read"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index c1bf82249..fc00713 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -2027,7 +2027,7 @@ </histogram> <histogram name="Android.Intent.LaunchExternalAppFormSubmitHasUserGesture" - enum="Boolean" expires_after="M73"> + enum="Boolean" expires_after="M74"> <owner>tedchoc@chromium.org</owner> <owner>thildebr@chromium.org</owner> <summary> @@ -16725,6 +16725,18 @@ </summary> </histogram> +<histogram name="ContentSuggestions.Feed.Scheduler.TimeSinceLastFetchOnClear" + units="ms" expires_after="2019-10-01"> + <owner>skym@chromium.org</owner> + <owner>fgorski@chromium.org</owner> + <summary> + When the previous last fetch attempt time is cleared, log the time since the + last fetch attempt. This typically occurs when suggestions are cleared. A + client that has never made a successful fetch (at least since it was last + cleared) will report the time since epoch. + </summary> +</histogram> + <histogram name="ContentSuggestions.Feed.TokenFetchStatus" enum="GoogleServiceAuthError"> <obsolete> @@ -78448,6 +78460,17 @@ </summary> </histogram> +<histogram name="PasswordManager.FirstRendererFillingResult" + enum="PasswordManagerFirstRendererFillingResult" expires_after="M76"> + <owner>battre@chromium.org</owner> + <owner>dvadym@chromium.org</owner> + <summary> + Records whether the PasswordAutofillAgent in the renderer manages to fill + credentials as instructed by the browser or records a failure reason + otherwise. Only the outcome of the first attempt to fill is recorded. + </summary> +</histogram> + <histogram name="PasswordManager.FormDataDeserializationStatus" enum="FormDataDeserializationStatus"> <owner>gcasto@chromium.org</owner> @@ -105411,6 +105434,36 @@ </summary> </histogram> +<histogram base="true" name="SimpleCache.EntryTrailerPrefetchDelta" + units="bytes"> + <owner>wanderview@chromium.org</owner> + <summary> + The difference between EntryTrailerPrefetchSize and EntryTrailerSize in + bytes within a single ReadAndValidateStream0AndMaybe1() method call. If the + prefetch read too many bytes then this will be a positive value. If the + prefetch did not read enough bytes, then this will be a negative value. + </summary> +</histogram> + +<histogram base="true" name="SimpleCache.EntryTrailerPrefetchSize" + units="bytes"> + <owner>wanderview@chromium.org</owner> + <summary> + The number of bytes prefetched from the end of the entry file in an attempt + read the EOF footer and the stream 0 data in a single file operation. + Ideally this value should match the EntryTrailerSize histogram indicating + the actual trailer size on disk was. + </summary> +</histogram> + +<histogram base="true" name="SimpleCache.EntryTrailerSize" units="bytes"> + <owner>wanderview@chromium.org</owner> + <summary> + The number of bytes read at the end of the entry file in order to process + the EOF footer and the stream 0 data. + </summary> +</histogram> + <histogram name="SimpleCache.Eviction.CacheSizeOnStart" units="bytes"> <obsolete> Deprecated 2013 in favour of SimpleCache.Eviction.CacheSizeOnStart2 @@ -105959,6 +106012,11 @@ </histogram> <histogram base="true" name="SimpleCache.SyncOpenDidPrefetch" enum="Boolean"> + <obsolete> + Replaced Dec, 2018 by SimpleCache.SyncOpenPrefetchMode. The new histogram is + an enumeration that can distinguish between full file prefetching from + trailer prefetching. + </obsolete> <owner>morlovich@chromium.org</owner> <summary> Whether an attempt was made to prefetch the entire file when executing @@ -105983,6 +106041,15 @@ </summary> </histogram> +<histogram base="true" name="SimpleCache.SyncOpenPrefetchMode" + enum="SimpleCachePrefetchMode"> + <owner>wanderview@chromium.org</owner> + <summary> + The kind of prefetching performed, if any, when executing + SimpleSynchronousEntry::ReadAndValidateStream0AndMaybe1(). + </summary> +</histogram> + <histogram base="true" name="SimpleCache.SyncOpenResult" enum="SimpleCacheSyncOpenResult"> <owner>morlovich@chromium.org</owner> @@ -129660,6 +129727,9 @@ <affected-histogram name="SimpleCache.EntryCreationTime"/> <affected-histogram name="SimpleCache.EntryOpenedAndStream2Removed"/> <affected-histogram name="SimpleCache.EntryOperationsPending"/> + <affected-histogram name="SimpleCache.EntryTrailerPrefetchDelta"/> + <affected-histogram name="SimpleCache.EntryTrailerPrefetchSize"/> + <affected-histogram name="SimpleCache.EntryTrailerSize"/> <affected-histogram name="SimpleCache.Eviction.CacheSizeOnStart"/> <affected-histogram name="SimpleCache.Eviction.CacheSizeOnStart2"/> <affected-histogram name="SimpleCache.Eviction.EntryCount"/> @@ -129744,6 +129814,7 @@ <affected-histogram name="SimpleCache.SyncOpenPlatformFileError_WithIndex"/> <affected-histogram name="SimpleCache.SyncOpenPlatformFileError_WithoutIndex"/> + <affected-histogram name="SimpleCache.SyncOpenPrefetchMode"/> <affected-histogram name="SimpleCache.SyncOpenResult"/> <affected-histogram name="SimpleCache.SyncOpenResult_WithIndex"/> <affected-histogram name="SimpleCache.SyncOpenResult_WithoutIndex"/>
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn index aedd969f..ab96092 100644 --- a/ui/android/BUILD.gn +++ b/ui/android/BUILD.gn
@@ -311,6 +311,7 @@ "java/src/org/chromium/ui/widget/AnchoredPopupWindow.java", "java/src/org/chromium/ui/widget/ButtonCompat.java", "java/src/org/chromium/ui/widget/CheckableImageView.java", + "java/src/org/chromium/ui/widget/ChipView.java", "java/src/org/chromium/ui/widget/ChromeBulletSpan.java", "java/src/org/chromium/ui/widget/ChromeImageView.java", "java/src/org/chromium/ui/widget/ChromeImageButton.java",
diff --git a/chrome/android/java/res/color/chip_background_color.xml b/ui/android/java/res/color/chip_background_color.xml similarity index 100% rename from chrome/android/java/res/color/chip_background_color.xml rename to ui/android/java/res/color/chip_background_color.xml
diff --git a/ui/android/java/res/color/chip_ripple_color.xml b/ui/android/java/res/color/chip_ripple_color.xml new file mode 100644 index 0000000..7e3cf6f3 --- /dev/null +++ b/ui/android/java/res/color/chip_ripple_color.xml
@@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2019 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> + +<selector + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + tools:ignore="UnusedResources"> + <item android:alpha="@dimen/default_pressed_alpha" + android:color="@color/modern_grey_600" android:state_pressed="true"/> + <item android:alpha="@dimen/default_focused_hovered_alpha" + android:color="@color/modern_grey_600" android:state_focused="true" android:state_hovered="true"/> + <item android:alpha="@dimen/default_focused_alpha" + android:color="@color/modern_grey_600" android:state_focused="true"/> + <item android:alpha="@dimen/default_hovered_alpha" + android:color="@color/modern_grey_600" android:state_hovered="true"/> + <item android:color="@android:color/transparent" /> +</selector>
diff --git a/chrome/android/java/res/color/chip_stroke_color.xml b/ui/android/java/res/color/chip_stroke_color.xml similarity index 100% rename from chrome/android/java/res/color/chip_stroke_color.xml rename to ui/android/java/res/color/chip_stroke_color.xml
diff --git a/chrome/android/java/res/color/chip_text_color.xml b/ui/android/java/res/color/chip_text_color.xml similarity index 100% rename from chrome/android/java/res/color/chip_text_color.xml rename to ui/android/java/res/color/chip_text_color.xml
diff --git a/ui/android/java/res/layout/dropdown_item.xml b/ui/android/java/res/layout/dropdown_item.xml index c689ee6c..c934aee 100644 --- a/ui/android/java/res/layout/dropdown_item.xml +++ b/ui/android/java/res/layout/dropdown_item.xml
@@ -39,7 +39,7 @@ android:includeFontPadding="false" android:singleLine="true" android:textAlignment="viewStart" - android:textAppearance="@style/BlackTitle1" /> + android:textAppearance="@style/TextAppearance.BlackTitle1" /> <TextView android:id="@+id/dropdown_sublabel" @@ -51,7 +51,7 @@ android:includeFontPadding="false" android:singleLine="true" android:textAlignment="viewStart" - android:textAppearance="@style/BlackCaption" /> + android:textAppearance="@style/TextAppearance.BlackCaption" /> </LinearLayout> <ImageView
diff --git a/ui/android/java/res/values-v17/styles.xml b/ui/android/java/res/values-v17/styles.xml index 97955ed..4743f2ee8 100644 --- a/ui/android/java/res/values-v17/styles.xml +++ b/ui/android/java/res/values-v17/styles.xml
@@ -37,7 +37,7 @@ <style name="FilledButton" parent="ButtonCompatBase" tools:ignore="UnusedResources"> <item name="android:paddingStart">24dp</item> <item name="android:paddingEnd">24dp</item> - <item name="android:textAppearance">@style/WhiteButtonText</item> + <item name="android:textAppearance">@style/TextAppearance.WhiteButtonText</item> <item name="buttonColor">@color/blue_when_enabled</item> <item name="rippleColor">@color/filled_button_ripple_color</item> <item name="buttonRaised">true</item> @@ -48,131 +48,164 @@ <style name="TextButton" parent="ButtonCompatBase" tools:ignore="UnusedResources"> <item name="android:paddingStart">8dp</item> <item name="android:paddingEnd">8dp</item> - <item name="android:textAppearance">@style/BlueButtonText2</item> + <item name="android:textAppearance">@style/TextAppearance.BlueButtonText2</item> <item name="buttonColor">@android:color/transparent</item> <item name="rippleColor">@color/text_button_ripple_color</item> <item name="buttonRaised">false</item> </style> + <!-- Chips --> + <style name="SuggestionChipThemeOverlay" tools:ignore="UnusedResources"> + <item name="chipStyle">@style/SuggestionChip</item> + </style> + + <style name="Chip"> + <item name="android:minHeight">@dimen/chip_default_height</item> + <item name="android:gravity">center_vertical</item> + <item name="android:orientation">horizontal</item> + <item name="chipColor">@color/chip_background_color</item> + <item name="rippleColor">@color/chip_ripple_color</item> + </style> + <style name="SuggestionChip" parent="Chip" tools:ignore="UnusedResources"> + <item name="cornerRadius">@dimen/chip_corner_radius</item> + </style> + <style name="InputChip" parent="Chip" tools:ignore="UnusedResources"> + <item name="cornerRadius">@dimen/chip_default_height</item> + </style> + + <style name="ChipTextView" tools:ignore="UnusedResources"> + <item name="android:gravity">center</item> + <item name="android:maxLines">1</item> + <item name="android:paddingStart">@dimen/chip_icon_padding</item> + <item name="android:paddingEnd">@dimen/chip_no_icon_padding</item> + <item name="android:textAlignment">center</item> + </style> + <!-- Used by Chrome and Content --> <!-- TODO(huayinz): Update prefixes for text appearance styles in ui/android. --> <style name="TextAppearance" parent="android:TextAppearance" tools:ignore="UnusedResources" /> - <style name="RobotoMediumStyle"> + <style name="TextAppearance.RobotoMediumStyle"> <item name="android:fontFamily">sans-serif</item> <item name="android:textStyle">bold</item> </style> <!-- Black Text Styles --> <!-- TODO(huayinz): remove tools:ignore once these text styles are all used in ui/android --> - <style name="BlackHeadline" tools:ignore="UnusedResources"> + <style name="TextAppearance.BlackHeadline" tools:ignore="UnusedResources"> <item name="android:textColor">@color/default_text_color_list</item> <item name="android:textSize">@dimen/headline_size</item> </style> - <style name="BlackTitle1" tools:ignore="UnusedResources"> + <style name="TextAppearance.BlackTitle1" tools:ignore="UnusedResources"> <item name="android:textColor">@color/default_text_color_list</item> <item name="android:textSize">@dimen/text_size_large</item> </style> - <style name="BlackTitle2" parent="RobotoMediumStyle" tools:ignore="UnusedResources"> + <style name="TextAppearance.BlackTitle2" parent="TextAppearance.RobotoMediumStyle" tools:ignore="UnusedResources"> <item name="android:textColor">@color/default_text_color_list</item> <item name="android:textSize">@dimen/text_size_medium</item> </style> - <style name="BlackHint1" tools:ignore="UnusedResources"> + <style name="TextAppearance.BlackHint1" tools:ignore="UnusedResources"> <item name="android:textColor">@color/default_text_color_secondary_list</item> <item name="android:textSize">@dimen/text_size_large</item> </style> - <style name="BlackHint2" tools:ignore="UnusedResources"> + <style name="TextAppearance.BlackHint2" tools:ignore="UnusedResources"> <item name="android:textColor">@color/default_text_color_secondary_list</item> <item name="android:textSize">@dimen/text_size_medium</item> </style> - <style name="BlackDisabledText1" tools:ignore="UnusedResources"> + <style name="TextAppearance.BlackDisabledText1" tools:ignore="UnusedResources"> <item name="android:textColor">@color/disabled_text_color</item> <item name="android:textSize">@dimen/text_size_large</item> </style> - <style name="BlackDisabledText2" tools:ignore="UnusedResources"> + <style name="TextAppearance.BlackDisabledText2" tools:ignore="UnusedResources"> <item name="android:textColor">@color/disabled_text_color</item> <item name="android:textSize">@dimen/text_size_small</item> </style> - <style name="BlackDisabledText3" tools:ignore="UnusedResources"> + <style name="TextAppearance.BlackDisabledText3" tools:ignore="UnusedResources"> <item name="android:textColor">@color/disabled_text_color</item> <item name="android:textSize">@dimen/text_size_medium</item> </style> - <style name="BlackBodyDefault" tools:ignore="UnusedResources"> + <style name="TextAppearance.BlackBodyDefault" tools:ignore="UnusedResources"> <item name="android:textColor">@color/default_text_color_list</item> <item name="android:textSize">@dimen/text_size_medium</item> </style> - <style name="BlackBody" tools:ignore="UnusedResources"> + <style name="TextAppearance.BlackBody" tools:ignore="UnusedResources"> <item name="android:textColor">@color/default_text_color_secondary_list</item> <item name="android:textSize">@dimen/text_size_medium</item> </style> - <style name="BlackCaptionDefault" tools:ignore="UnusedResources"> + <style name="TextAppearance.BlackCaptionDefault" tools:ignore="UnusedResources"> <item name="android:textColor">@color/default_text_color_list</item> <item name="android:textSize">@dimen/text_size_small</item> </style> - <style name="BlackCaption" tools:ignore="UnusedResources"> + <style name="TextAppearance.BlackCaption" tools:ignore="UnusedResources"> <item name="android:textColor">@color/default_text_color_secondary_list</item> <item name="android:textSize">@dimen/text_size_small</item> </style> - <style name="BlackButtonText" parent="RobotoMediumStyle" tools:ignore="UnusedResources"> + <style name="TextAppearance.BlackButtonText" parent="TextAppearance.RobotoMediumStyle" tools:ignore="UnusedResources"> <item name="android:textColor">@color/default_text_color_secondary_list</item> <item name="android:textSize">@dimen/text_size_medium</item> </style> - <style name="BlackLink" tools:ignore="UnusedResources"> + <style name="TextAppearance.BlackLink" tools:ignore="UnusedResources"> <item name="android:textColor">@color/default_text_color_secondary_list</item> <item name="android:textSize">@dimen/text_size_medium</item> <item name="android:textStyle">bold</item> </style> <!-- White Text Styles --> - <style name="WhiteHeadline" tools:ignore="UnusedResources"> + <style name="TextAppearance.WhiteHeadline" tools:ignore="UnusedResources"> <item name="android:textColor">@android:color/white</item> <item name="android:textSize">@dimen/headline_size</item> </style> - <style name="WhiteBodyIncognito" tools:ignore="UnusedResources"> + <style name="TextAppearance.WhiteBodyIncognito" tools:ignore="UnusedResources"> <item name="android:textColor">@color/white_alpha_70</item> <item name="android:textSize">@dimen/text_size_medium</item> </style> - <style name="WhiteBody" tools:ignore="UnusedResources"> + <style name="TextAppearance.WhiteBody" tools:ignore="UnusedResources"> <item name="android:textColor">@android:color/white</item> <item name="android:textSize">@dimen/text_size_medium</item> </style> - <style name="WhiteTitle1" tools:ignore="UnusedResources"> + <style name="TextAppearance.WhiteTitle1" tools:ignore="UnusedResources"> <item name="android:textColor">@android:color/white</item> <item name="android:textSize">@dimen/text_size_large</item> </style> - <style name="WhiteTitle2" parent="RobotoMediumStyle" tools:ignore="UnusedResources"> + <style name="TextAppearance.WhiteTitle2" parent="TextAppearance.RobotoMediumStyle" tools:ignore="UnusedResources"> <item name="android:textColor">@android:color/white</item> <item name="android:textSize">@dimen/text_size_medium</item> </style> - <style name="WhiteButtonText" parent="WhiteTitle2" /> - <style name="WhiteLink" tools:ignore="UnusedResources"> + <style name="TextAppearance.WhiteButtonText" parent="TextAppearance.WhiteTitle2" /> + <style name="TextAppearance.WhiteLink" tools:ignore="UnusedResources"> <item name="android:textColor">@android:color/white</item> <item name="android:textSize">@dimen/text_size_medium</item> <item name="android:textStyle">bold</item> </style> <!-- Blue Text Styles --> - <style name="BlueTitle2" parent="RobotoMediumStyle"> + <style name="TextAppearance.BlueTitle2" parent="TextAppearance.RobotoMediumStyle"> <item name="android:textColor">@color/blue_when_enabled</item> <item name="android:textSize">@dimen/text_size_medium</item> </style> - <style name="BlueButtonText1" parent="RobotoMediumStyle" tools:ignore="UnusedResources"> + <style name="TextAppearance.BlueButtonText1" parent="TextAppearance.RobotoMediumStyle" tools:ignore="UnusedResources"> <item name="android:textColor">@color/modern_blue_300</item> <item name="android:textSize">@dimen/text_size_medium</item> </style> - <style name="BlueButtonText2" parent="BlueTitle2" /> - <style name="BlueLink1" tools:ignore="UnusedResources"> + <style name="TextAppearance.BlueButtonText2" parent="TextAppearance.BlueTitle2" /> + <style name="TextAppearance.BlueLink1" tools:ignore="UnusedResources"> <item name="android:textColor">@color/blue_when_enabled</item> <item name="android:textSize">@dimen/text_size_large</item> </style> - <style name="BlueLink2" tools:ignore="UnusedResources"> + <style name="TextAppearance.BlueLink2" tools:ignore="UnusedResources"> <item name="android:textColor">@color/blue_when_enabled</item> <item name="android:textSize">@dimen/text_size_medium</item> </style> - <style name="BlueLink3" tools:ignore="UnusedResources"> + <style name="TextAppearance.BlueLink3" tools:ignore="UnusedResources"> <item name="android:textColor">@color/blue_when_enabled</item> <item name="android:textSize">@dimen/text_size_small</item> </style> + <!-- Chip Text Styles --> + <style name="TextAppearance.ChipText" parent="TextAppearance.RobotoMediumStyle"> + <item name="android:textColor">@color/chip_text_color</item> + <item name="android:textSize">@dimen/text_size_medium</item> + </style> + <!-- Dividers --> <style name="HorizontalDivider" tools:ignore="UnusedResources">
diff --git a/ui/android/java/res/values-v21/styles.xml b/ui/android/java/res/values-v21/styles.xml index 3f99004..a00d47df 100644 --- a/ui/android/java/res/values-v21/styles.xml +++ b/ui/android/java/res/values-v21/styles.xml
@@ -4,7 +4,7 @@ found in the LICENSE file. --> <resources xmlns:tools="http://schemas.android.com/tools"> <!-- Used by Chrome and Content --> - <style name="RobotoMediumStyle" tools:ignore="UnusedResources"> + <style name="TextAppearance.RobotoMediumStyle" tools:ignore="UnusedResources"> <item name="android:fontFamily">sans-serif-medium</item> </style> </resources>
diff --git a/ui/android/java/res/values/attrs.xml b/ui/android/java/res/values/attrs.xml index 798b7b7d..d6f53cee 100644 --- a/ui/android/java/res/values/attrs.xml +++ b/ui/android/java/res/values/attrs.xml
@@ -20,6 +20,15 @@ <attr name="buttonRaised" format="boolean"/> </declare-styleable> + <declare-styleable name="ChipView"> + <attr name="chipColor" format="color"/> + <attr name="chipStyle" format="reference"/> + <attr name="cornerRadius" format="reference|dimension"/> + <attr name="iconWidth" format="reference|dimension"/> + <attr name="iconHeight" format="reference|dimension"/> + <attr name="rippleColor" format="color"/> + </declare-styleable> + <declare-styleable name="TextViewWithLeading"> <attr name="leading" format="reference|dimension"/> </declare-styleable>
diff --git a/ui/android/java/res/values/dimens.xml b/ui/android/java/res/values/dimens.xml index 2003b51..6b3c7ac2 100644 --- a/ui/android/java/res/values/dimens.xml +++ b/ui/android/java/res/values/dimens.xml
@@ -23,6 +23,17 @@ <item name="default_focused_alpha" format="float" type="dimen">0.06</item> <item name="default_hovered_alpha" format="float" type="dimen">0.04</item> + <!-- Chips default measures --> + <dimen name="chip_border_width">1dp</dimen> + <dimen name="chip_corner_radius">8dp</dimen> + <dimen name="chip_default_height">32dp</dimen> + <dimen name="chip_no_icon_padding">16dp</dimen> + <dimen name="chip_icon_padding">8dp</dimen> + <item name="chip_background_selected_focused_alpha" format="float" type="dimen">0.12</item> + <item name="chip_background_selected_alpha" format="float" type="dimen">0.06</item> + <dimen name="chip_icon_size">20dp</dimen> + + <!-- Dropdown default measures --> <dimen name="dropdown_item_height">50dp</dimen> <dimen name="dropdown_item_divider_height">1px</dimen> <dimen name="dropdown_item_label_margin">10dp</dimen> @@ -38,6 +49,9 @@ <!-- Divider Dimensions --> <dimen name="divider_height">1dp</dimen> + <!-- Misc --> + <dimen name="default_ripple_background_border_size">0dp</dimen> + <!-- Fallback values if the corresponding com.android.internal.R dimensions cannot be retrieved by name.
diff --git a/ui/android/java/src/org/chromium/ui/widget/ButtonCompat.java b/ui/android/java/src/org/chromium/ui/widget/ButtonCompat.java index e5cc718..f83ca7c 100644 --- a/ui/android/java/src/org/chromium/ui/widget/ButtonCompat.java +++ b/ui/android/java/src/org/chromium/ui/widget/ButtonCompat.java
@@ -68,7 +68,8 @@ boolean buttonRaised = a.getBoolean(R.styleable.ButtonCompat_buttonRaised, true); a.recycle(); - mRippleBackgroundHelper = new RippleBackgroundHelper(this, buttonColorId, rippleColorId); + mRippleBackgroundHelper = new RippleBackgroundHelper(this, buttonColorId, rippleColorId, + getResources().getDimensionPixelSize(R.dimen.button_compat_corner_radius)); setRaised(buttonRaised); }
diff --git a/ui/android/java/src/org/chromium/ui/widget/ChipView.java b/ui/android/java/src/org/chromium/ui/widget/ChipView.java new file mode 100644 index 0000000..c2a0529c --- /dev/null +++ b/ui/android/java/src/org/chromium/ui/widget/ChipView.java
@@ -0,0 +1,122 @@ +// 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.ui.widget; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.content.res.TypedArray; +import android.support.annotation.DrawableRes; +import android.support.annotation.StyleRes; +import android.support.v4.view.MarginLayoutParamsCompat; +import android.support.v4.view.ViewCompat; +import android.util.AttributeSet; +import android.view.ContextThemeWrapper; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.ui.R; + +/** The view responsible for displaying a material chip. */ +public class ChipView extends LinearLayout { + /** An id to use for {@link #setIcon(int)} when there is no icon on the chip. */ + public static final int INVALID_ICON_ID = -1; + private final int mTextStartPaddingWithIconPx; + private final int mTextStartPaddingWithNoIconPx; + + private final RippleBackgroundHelper mRippleBackgroundHelper; + private final TextView mText; + private final ChromeImageView mIcon; + + /** + * Constructor for inflating from XML. + */ + public ChipView(Context context, @StyleRes int chipStyle) { + this(context, null, chipStyle); + } + + /** + * Constructor for inflating from XML. + */ + public ChipView(Context context, AttributeSet attrs) { + this(context, attrs, R.style.SuggestionChipThemeOverlay); + } + + private ChipView(Context context, AttributeSet attrs, @StyleRes int themeOverlay) { + super(new ContextThemeWrapper(context, themeOverlay), attrs, R.attr.chipStyle); + + mTextStartPaddingWithIconPx = + getResources().getDimensionPixelSize(R.dimen.chip_icon_padding); + mTextStartPaddingWithNoIconPx = + getResources().getDimensionPixelSize(R.dimen.chip_no_icon_padding); + + TypedArray a = getContext().obtainStyledAttributes( + attrs, R.styleable.ChipView, R.attr.chipStyle, 0); + int chipColorId = + a.getResourceId(R.styleable.ChipView_chipColor, R.color.chip_background_color); + int rippleColorId = + a.getResourceId(R.styleable.ChipView_rippleColor, R.color.chip_ripple_color); + int cornerRadius = a.getDimensionPixelSize(R.styleable.ChipView_cornerRadius, + getContext().getResources().getDimensionPixelSize(R.dimen.chip_corner_radius)); + int iconWidth = a.getDimensionPixelSize(R.styleable.ChipView_iconWidth, + getResources().getDimensionPixelSize(R.dimen.chip_icon_size)); + int iconHeight = a.getDimensionPixelSize(R.styleable.ChipView_iconHeight, + getResources().getDimensionPixelSize(R.dimen.chip_icon_size)); + a.recycle(); + + mIcon = new ChromeImageView(getContext()); + LayoutParams lp = new LayoutParams(iconWidth, iconHeight); + MarginLayoutParamsCompat.setMarginStart(lp, mTextStartPaddingWithIconPx); + mIcon.setLayoutParams(lp); + addView(mIcon); + + mText = new TextView(new ContextThemeWrapper(getContext(), R.style.ChipTextView)); + ApiCompatibilityUtils.setTextAppearance(mText, R.style.TextAppearance_ChipText); + addView(mText); + + // Reset icon and background: + mRippleBackgroundHelper = new RippleBackgroundHelper(this, chipColorId, rippleColorId, + cornerRadius, R.color.chip_stroke_color, R.dimen.chip_border_width); + setIcon(INVALID_ICON_ID); + + ColorStateList textColors = mText.getTextColors(); + if (textColors != null) ApiCompatibilityUtils.setImageTintList(mIcon, textColors); + } + + @Override + protected void drawableStateChanged() { + super.drawableStateChanged(); + if (mRippleBackgroundHelper != null) { + mRippleBackgroundHelper.onDrawableStateChanged(); + } + } + + /** + * Sets the icon at the start of the chip view. + * @param icon The resource id pointing to the icon. + */ + public void setIcon(@DrawableRes int icon) { + final int textStartPadding; + if (icon == INVALID_ICON_ID) { + mIcon.setVisibility(ViewGroup.GONE); + textStartPadding = mTextStartPaddingWithNoIconPx; + } else { + textStartPadding = mTextStartPaddingWithIconPx; + mIcon.setVisibility(ViewGroup.VISIBLE); + mIcon.setImageResource(icon); + } + + ViewCompat.setPaddingRelative(mText, textStartPadding, mText.getPaddingTop(), + ViewCompat.getPaddingEnd(mText), mText.getPaddingBottom()); + } + + /** + * Returns the {@link TextView} that contains the label of the chip. + * @return A {@link TextView}. + */ + public TextView getInnerTextView() { + return mText; + } +}
diff --git a/ui/android/java/src/org/chromium/ui/widget/RippleBackgroundHelper.java b/ui/android/java/src/org/chromium/ui/widget/RippleBackgroundHelper.java index d2c068c..8780438 100644 --- a/ui/android/java/src/org/chromium/ui/widget/RippleBackgroundHelper.java +++ b/ui/android/java/src/org/chromium/ui/widget/RippleBackgroundHelper.java
@@ -14,7 +14,9 @@ import android.os.Build; import android.support.annotation.ColorInt; import android.support.annotation.ColorRes; +import android.support.annotation.DimenRes; import android.support.annotation.Nullable; +import android.support.annotation.Px; import android.support.v4.graphics.ColorUtils; import android.support.v4.graphics.drawable.DrawableCompat; import android.support.v7.content.res.AppCompatResources; @@ -42,49 +44,43 @@ // Used for applying tint on pre-L versions. private Drawable mBackgroundDrawablePreL; private Drawable mRippleDrawablePreL; + private Drawable mBorderDrawablePreL; /** * @param view The {@link View} on which background will be applied. * @param backgroundColorResId The resource id of the background color. * @param rippleColorResId The resource id of the ripple color. + * @param cornerRadius The corner radius in pixels of the background drawable. */ - RippleBackgroundHelper( - View view, @ColorRes int backgroundColorResId, @ColorRes int rippleColorResId) { + RippleBackgroundHelper(View view, @ColorRes int backgroundColorResId, + @ColorRes int rippleColorResId, @Px int cornerRadius) { + this(view, backgroundColorResId, rippleColorResId, cornerRadius, + android.R.color.transparent, R.dimen.default_ripple_background_border_size); + } + + /** + * @param view The {@link View} on which background will be applied. + * @param backgroundColorResId The resource id of the background color. + * @param rippleColorResId The resource id of the ripple color. + * @param cornerRadius The corner radius in pixels of the background drawable. + * @param borderColorResId The resource id of the border color. + * @param borderSizeDimenId The resource id of the border size. + */ + RippleBackgroundHelper(View view, @ColorRes int backgroundColorResId, + @ColorRes int rippleColorResId, @Px int cornerRadius, @ColorRes int borderColorResId, + @DimenRes int borderSizeDimenId) { mView = view; - ColorStateList rippleColorList = - AppCompatResources.getColorStateList(view.getContext(), rippleColorResId); - - int cornerRadius = - view.getResources().getDimensionPixelSize(R.dimen.button_compat_corner_radius); - ColorStateList backgroundColorList = - AppCompatResources.getColorStateList(view.getContext(), backgroundColorResId); - - mBackgroundGradient = new GradientDrawable(); - mBackgroundGradient.setCornerRadius(cornerRadius); - - Drawable wrappedDrawable; - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { - mBackgroundDrawablePreL = DrawableCompat.wrap(mBackgroundGradient); - GradientDrawable rippleGradient = new GradientDrawable(); - rippleGradient.setCornerRadius(cornerRadius); - mRippleDrawablePreL = DrawableCompat.wrap(rippleGradient); - DrawableCompat.setTintList(mRippleDrawablePreL, rippleColorList); - wrappedDrawable = new LayerDrawable( - new Drawable[] {mBackgroundDrawablePreL, mRippleDrawablePreL}); - } else { - GradientDrawable mask = new GradientDrawable(); - mask.setCornerRadius(cornerRadius); - mask.setColor(Color.WHITE); - wrappedDrawable = new RippleDrawable( - convertToRippleDrawableColorList(rippleColorList), mBackgroundGradient, mask); - } int paddingLeft = mView.getPaddingLeft(); int paddingTop = mView.getPaddingTop(); int paddingRight = mView.getPaddingRight(); int paddingBottom = mView.getPaddingBottom(); - mView.setBackground(wrappedDrawable); - setBackgroundColor(backgroundColorList); + mView.setBackground(createBackgroundDrawable( + AppCompatResources.getColorStateList(view.getContext(), rippleColorResId), + AppCompatResources.getColorStateList(view.getContext(), borderColorResId), + view.getResources().getDimensionPixelSize(borderSizeDimenId), cornerRadius)); + setBackgroundColor( + AppCompatResources.getColorStateList(view.getContext(), backgroundColorResId)); // On KitKat, setting the background on the view can cause padding reset. Save the padding // and re-apply after background is set. @@ -94,6 +90,51 @@ } /** + * This initializes all members with new drawables needed to display/update a ripple effect. + * @param rippleColorList A {@link ColorStateList} that is used for the ripple effect. + * @param borderColorList A {@link ColorStateList} that is used for the border. + * @param borderSize The border width in pixels. + * @param cornerRadius The corner radius in pixels. + * @return The {@link GradientDrawable}/{@link LayerDrawable} to be used as ripple background. + */ + private Drawable createBackgroundDrawable(ColorStateList rippleColorList, + ColorStateList borderColorList, @Px int borderSize, @Px int cornerRadius) { + mBackgroundGradient = new GradientDrawable(); + mBackgroundGradient.setCornerRadius(cornerRadius); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + if (borderSize > 0) mBackgroundGradient.setStroke(borderSize, borderColorList); + GradientDrawable mask = new GradientDrawable(); + mask.setCornerRadius(cornerRadius); + mask.setColor(Color.WHITE); + return new RippleDrawable( + convertToRippleDrawableColorList(rippleColorList), mBackgroundGradient, mask); + } + + // Pre-L, create a background drawable and overlay it by a ripple drawable. + GradientDrawable rippleGradient = new GradientDrawable(); + rippleGradient.setCornerRadius(cornerRadius); + mBackgroundDrawablePreL = DrawableCompat.wrap(mBackgroundGradient); + mRippleDrawablePreL = DrawableCompat.wrap(rippleGradient); + DrawableCompat.setTintList(mRippleDrawablePreL, rippleColorList); + if (borderSize == 0) { + return new LayerDrawable(new Drawable[] {mBackgroundDrawablePreL, mRippleDrawablePreL}); + } + + // If the background is overlaid by a border. The border is in a separate GradientDrawable + // to apply ColorStateLists independently from ripple and background. + GradientDrawable borderGradient = new GradientDrawable(); + borderGradient.setCornerRadius(cornerRadius); + borderGradient.setColor(mView.getResources().getColor(android.R.color.transparent)); + borderGradient.setStroke(borderSize, + borderColorList.getColorForState( + mView.getDrawableState(), borderColorList.getDefaultColor())); + mBorderDrawablePreL = DrawableCompat.wrap(borderGradient); + DrawableCompat.setTintList(mBorderDrawablePreL, borderColorList); + return new LayerDrawable( + new Drawable[] {mBackgroundDrawablePreL, mBorderDrawablePreL, mRippleDrawablePreL}); + } + + /** * @param color The {@link ColorStateList} to be set as the background color on the background * drawable. */ @@ -118,6 +159,7 @@ int[] state = mView.getDrawableState(); mBackgroundDrawablePreL.setState(state); mRippleDrawablePreL.setState(state); + if (mBorderDrawablePreL != null) mBorderDrawablePreL.setState(state); } /**
diff --git a/ui/base/emoji/emoji_panel_helper_chromeos.cc b/ui/base/emoji/emoji_panel_helper_chromeos.cc index 09ee96f4..9789028e 100644 --- a/ui/base/emoji/emoji_panel_helper_chromeos.cc +++ b/ui/base/emoji/emoji_panel_helper_chromeos.cc
@@ -19,7 +19,9 @@ } // namespace bool IsEmojiPanelSupported() { - return true; + // TODO(https://crbug.com/887649): Emoji callback is null in Mojo apps because + // they are in a different process. Fix it and remove the null check. + return !GetShowEmojiKeyboardCallback().is_null(); } void ShowEmojiPanel() {
diff --git a/ui/base/ime/input_method_chromeos.cc b/ui/base/ime/input_method_chromeos.cc index 79a9f5a6f..cb583c9 100644 --- a/ui/base/ime/input_method_chromeos.cc +++ b/ui/base/ime/input_method_chromeos.cc
@@ -199,11 +199,13 @@ engine->FocusIn(context); } + OnCaretBoundsChanged(client); + InputMethodBase::OnTextInputTypeChanged(client); } void InputMethodChromeOS::OnCaretBoundsChanged(const TextInputClient* client) { - if (!IsInputFieldFocused() || !IsTextInputClientFocused(client)) + if (IsTextInputTypeNone() || !IsTextInputClientFocused(client)) return; NotifyTextInputCaretBoundsChanged(client); @@ -315,6 +317,8 @@ GetClientFocusReason(), GetClientShouldDoLearning()); GetEngine()->FocusIn(context); } + + OnCaretBoundsChanged(GetTextInputClient()); } void InputMethodChromeOS::ConfirmCompositionText() { @@ -359,9 +363,6 @@ GetTextInputType(), GetTextInputMode(), GetTextInputFlags(), GetClientFocusReason(), GetClientShouldDoLearning()); ui::IMEBridge::Get()->SetCurrentInputContext(context); - - if (!IsTextInputTypeNone()) - OnCaretBoundsChanged(GetTextInputClient()); } ui::EventDispatchDetails InputMethodChromeOS::ProcessKeyEventPostIME(
diff --git a/ui/base/ime/input_method_chromeos.h b/ui/base/ime/input_method_chromeos.h index 893ac113..52942a6 100644 --- a/ui/base/ime/input_method_chromeos.h +++ b/ui/base/ime/input_method_chromeos.h
@@ -41,6 +41,12 @@ bool IsCandidatePopupOpen() const override; InputMethodKeyboardController* GetInputMethodKeyboardController() override; + // Overridden from InputMethodBase: + void OnWillChangeFocusedClient(TextInputClient* focused_before, + TextInputClient* focused) override; + void OnDidChangeFocusedClient(TextInputClient* focused_before, + TextInputClient* focused) override; + protected: // Converts |text| into CompositionText. void ExtractCompositionText(const CompositionText& text, @@ -60,12 +66,6 @@ private: class PendingKeyEvent; - // Overridden from InputMethodBase: - void OnWillChangeFocusedClient(TextInputClient* focused_before, - TextInputClient* focused) override; - void OnDidChangeFocusedClient(TextInputClient* focused_before, - TextInputClient* focused) override; - // Asks the client to confirm current composition text. void ConfirmCompositionText();
diff --git a/ui/base/ime/input_method_chromeos_unittest.cc b/ui/base/ime/input_method_chromeos_unittest.cc index 3ab3975..559f34d 100644 --- a/ui/base/ime/input_method_chromeos_unittest.cc +++ b/ui/base/ime/input_method_chromeos_unittest.cc
@@ -13,6 +13,7 @@ #include "base/i18n/char_iterator.h" #include "base/macros.h" #include "base/strings/utf_string_conversions.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/ime/chromeos/mock_ime_candidate_window_handler.h" #include "ui/base/ime/chromeos/mock_ime_engine_handler.h" @@ -187,6 +188,14 @@ DISALLOW_COPY_AND_ASSIGN(TestInputMethodManager); }; +class NiceMockIMEEngine : public chromeos::MockIMEEngineHandler { + public: + MOCK_METHOD1(FocusIn, void(const InputContext&)); + MOCK_METHOD0(FocusOut, void()); + MOCK_METHOD4(SetSurroundingText, + void(const std::string&, uint32_t, uint32_t, uint32_t)); +}; + class InputMethodChromeOSTest : public internal::InputMethodDelegate, public testing::Test, public DummyTextInputClient { @@ -826,6 +835,43 @@ mock_ime_engine_handler_->set_surrounding_text_call_count()); } +TEST_F(InputMethodChromeOSTest, SurroundingText_EventOrder) { + ::testing::NiceMock<NiceMockIMEEngine> mock_engine; + IMEBridge::Get()->SetCurrentEngineHandler(&mock_engine); + + { + // Switches the text input client. + ::testing::InSequence seq; + EXPECT_CALL(mock_engine, FocusOut); + EXPECT_CALL(mock_engine, FocusIn); + EXPECT_CALL(mock_engine, SetSurroundingText); + + surrounding_text_ = UTF8ToUTF16("a"); + text_range_ = gfx::Range(0, 1); + selection_range_ = gfx::Range(0, 0); + + input_type_ = TEXT_INPUT_TYPE_TEXT; + ime_->OnWillChangeFocusedClient(nullptr, this); + ime_->OnDidChangeFocusedClient(nullptr, this); + } + + { + // Changes text input type. + ::testing::InSequence seq; + EXPECT_CALL(mock_engine, FocusOut); + EXPECT_CALL(mock_engine, FocusIn); + EXPECT_CALL(mock_engine, SetSurroundingText); + + surrounding_text_ = UTF8ToUTF16("b"); + text_range_ = gfx::Range(0, 1); + selection_range_ = gfx::Range(0, 0); + + input_type_ = TEXT_INPUT_TYPE_EMAIL; + ime_->OnTextInputTypeChanged(this); + } + IMEBridge::Get()->SetCurrentEngineHandler(nullptr); +} + class InputMethodChromeOSKeyEventTest : public InputMethodChromeOSTest { public: InputMethodChromeOSKeyEventTest() {}
diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py index 6d5edc9..a3841e7f7 100755 --- a/ui/gl/generate_bindings.py +++ b/ui/gl/generate_bindings.py
@@ -925,7 +925,7 @@ 'names': ['glGetProgramPipelineiv'], 'arguments': 'GLuint pipeline, GLenum pname, GLint* params', }, -{ 'return_type': 'void', +{ 'return_type': 'GLuint', 'names': ['glGetProgramResourceIndex'], 'arguments': 'GLuint program, GLenum programInterface, const GLchar* name', },
diff --git a/ui/gl/gl_bindings_api_autogen_gl.h b/ui/gl/gl_bindings_api_autogen_gl.h index b36d9e8..1595656 100644 --- a/ui/gl/gl_bindings_api_autogen_gl.h +++ b/ui/gl/gl_bindings_api_autogen_gl.h
@@ -607,9 +607,9 @@ void glGetProgramPipelineivFn(GLuint pipeline, GLenum pname, GLint* params) override; -void glGetProgramResourceIndexFn(GLuint program, - GLenum programInterface, - const GLchar* name) override; +GLuint glGetProgramResourceIndexFn(GLuint program, + GLenum programInterface, + const GLchar* name) override; void glGetProgramResourceivFn(GLuint program, GLenum programInterface, GLuint index,
diff --git a/ui/gl/gl_bindings_autogen_gl.cc b/ui/gl/gl_bindings_autogen_gl.cc index d9780a4a..552fdcf 100644 --- a/ui/gl/gl_bindings_autogen_gl.cc +++ b/ui/gl/gl_bindings_autogen_gl.cc
@@ -3935,10 +3935,11 @@ driver_->fn.glGetProgramPipelineivFn(pipeline, pname, params); } -void GLApiBase::glGetProgramResourceIndexFn(GLuint program, - GLenum programInterface, - const GLchar* name) { - driver_->fn.glGetProgramResourceIndexFn(program, programInterface, name); +GLuint GLApiBase::glGetProgramResourceIndexFn(GLuint program, + GLenum programInterface, + const GLchar* name) { + return driver_->fn.glGetProgramResourceIndexFn(program, programInterface, + name); } void GLApiBase::glGetProgramResourceivFn(GLuint program, @@ -7220,11 +7221,11 @@ gl_api_->glGetProgramPipelineivFn(pipeline, pname, params); } -void TraceGLApi::glGetProgramResourceIndexFn(GLuint program, - GLenum programInterface, - const GLchar* name) { +GLuint TraceGLApi::glGetProgramResourceIndexFn(GLuint program, + GLenum programInterface, + const GLchar* name) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glGetProgramResourceIndex") - gl_api_->glGetProgramResourceIndexFn(program, programInterface, name); + return gl_api_->glGetProgramResourceIndexFn(program, programInterface, name); } void TraceGLApi::glGetProgramResourceivFn(GLuint program, @@ -11291,14 +11292,17 @@ gl_api_->glGetProgramPipelineivFn(pipeline, pname, params); } -void DebugGLApi::glGetProgramResourceIndexFn(GLuint program, - GLenum programInterface, - const GLchar* name) { +GLuint DebugGLApi::glGetProgramResourceIndexFn(GLuint program, + GLenum programInterface, + const GLchar* name) { GL_SERVICE_LOG("glGetProgramResourceIndex" << "(" << program << ", " << GLEnums::GetStringEnum(programInterface) << ", " << static_cast<const void*>(name) << ")"); - gl_api_->glGetProgramResourceIndexFn(program, programInterface, name); + GLuint result = + gl_api_->glGetProgramResourceIndexFn(program, programInterface, name); + GL_SERVICE_LOG("GL_RESULT: " << result); + return result; } void DebugGLApi::glGetProgramResourceivFn(GLuint program, @@ -15331,10 +15335,11 @@ NoContextHelper("glGetProgramPipelineiv"); } -void NoContextGLApi::glGetProgramResourceIndexFn(GLuint program, - GLenum programInterface, - const GLchar* name) { +GLuint NoContextGLApi::glGetProgramResourceIndexFn(GLuint program, + GLenum programInterface, + const GLchar* name) { NoContextHelper("glGetProgramResourceIndex"); + return 0U; } void NoContextGLApi::glGetProgramResourceivFn(GLuint program,
diff --git a/ui/gl/gl_bindings_autogen_gl.h b/ui/gl/gl_bindings_autogen_gl.h index 8b83c70..a91d0c9 100644 --- a/ui/gl/gl_bindings_autogen_gl.h +++ b/ui/gl/gl_bindings_autogen_gl.h
@@ -703,7 +703,7 @@ typedef void(GL_BINDING_CALL* glGetProgramPipelineivProc)(GLuint pipeline, GLenum pname, GLint* params); -typedef void(GL_BINDING_CALL* glGetProgramResourceIndexProc)( +typedef GLuint(GL_BINDING_CALL* glGetProgramResourceIndexProc)( GLuint program, GLenum programInterface, const GLchar* name); @@ -2943,9 +2943,9 @@ virtual void glGetProgramPipelineivFn(GLuint pipeline, GLenum pname, GLint* params) = 0; - virtual void glGetProgramResourceIndexFn(GLuint program, - GLenum programInterface, - const GLchar* name) = 0; + virtual GLuint glGetProgramResourceIndexFn(GLuint program, + GLenum programInterface, + const GLchar* name) = 0; virtual void glGetProgramResourceivFn(GLuint program, GLenum programInterface, GLuint index,
diff --git a/ui/gl/gl_bindings_autogen_mock.cc b/ui/gl/gl_bindings_autogen_mock.cc index 33dc1aa7..7bc4154 100644 --- a/ui/gl/gl_bindings_autogen_mock.cc +++ b/ui/gl/gl_bindings_autogen_mock.cc
@@ -2029,12 +2029,12 @@ interface_->GetProgramPipelineiv(pipeline, pname, params); } -void GL_BINDING_CALL +GLuint GL_BINDING_CALL MockGLInterface::Mock_glGetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar* name) { MakeGlMockFunctionUnique("glGetProgramResourceIndex"); - interface_->GetProgramResourceIndex(program, programInterface, name); + return interface_->GetProgramResourceIndex(program, programInterface, name); } GLint GL_BINDING_CALL
diff --git a/ui/gl/gl_bindings_autogen_mock.h b/ui/gl/gl_bindings_autogen_mock.h index d3a5c646..eaab468 100644 --- a/ui/gl/gl_bindings_autogen_mock.h +++ b/ui/gl/gl_bindings_autogen_mock.h
@@ -850,7 +850,7 @@ static void GL_BINDING_CALL Mock_glGetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint* params); -static void GL_BINDING_CALL +static GLuint GL_BINDING_CALL Mock_glGetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar* name);
diff --git a/ui/gl/gl_mock_autogen_gl.h b/ui/gl/gl_mock_autogen_gl.h index 40ffe99..534700d 100644 --- a/ui/gl/gl_mock_autogen_gl.h +++ b/ui/gl/gl_mock_autogen_gl.h
@@ -586,7 +586,9 @@ MOCK_METHOD3(GetProgramPipelineiv, void(GLuint pipeline, GLenum pname, GLint* params)); MOCK_METHOD3(GetProgramResourceIndex, - void(GLuint program, GLenum programInterface, const GLchar* name)); + GLuint(GLuint program, + GLenum programInterface, + const GLchar* name)); MOCK_METHOD8(GetProgramResourceiv, void(GLuint program, GLenum programInterface,
diff --git a/ui/gl/gl_stub_autogen_gl.cc b/ui/gl/gl_stub_autogen_gl.cc index cf0fc52..33f7dff4 100644 --- a/ui/gl/gl_stub_autogen_gl.cc +++ b/ui/gl/gl_stub_autogen_gl.cc
@@ -79,6 +79,12 @@ return 0; } +GLuint GLStubApiBase::glGetProgramResourceIndexFn(GLuint program, + GLenum programInterface, + const GLchar* name) { + return 0; +} + GLint GLStubApiBase::glGetProgramResourceLocationFn(GLuint program, GLenum programInterface, const char* name) {
diff --git a/ui/gl/gl_stub_autogen_gl.h b/ui/gl/gl_stub_autogen_gl.h index 64a6a67..32cf931 100644 --- a/ui/gl/gl_stub_autogen_gl.h +++ b/ui/gl/gl_stub_autogen_gl.h
@@ -608,9 +608,9 @@ void glGetProgramPipelineivFn(GLuint pipeline, GLenum pname, GLint* params) override {} -void glGetProgramResourceIndexFn(GLuint program, - GLenum programInterface, - const GLchar* name) override {} +GLuint glGetProgramResourceIndexFn(GLuint program, + GLenum programInterface, + const GLchar* name) override; void glGetProgramResourceivFn(GLuint program, GLenum programInterface, GLuint index,
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc index 0fa90ff..dfc6699 100644 --- a/ui/views/controls/textfield/textfield.cc +++ b/ui/views/controls/textfield/textfield.cc
@@ -354,9 +354,9 @@ void Textfield::SetTextInputType(ui::TextInputType type) { GetRenderText()->SetObscured(type == ui::TEXT_INPUT_TYPE_PASSWORD); text_input_type_ = type; - OnCaretBoundsChanged(); if (GetInputMethod()) GetInputMethod()->OnTextInputTypeChanged(this); + OnCaretBoundsChanged(); SchedulePaint(); }
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_ip_config.html b/ui/webui/resources/cr_components/chromeos/network/network_ip_config.html index f3a3ca1..abca58c9 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_ip_config.html +++ b/ui/webui/resources/cr_components/chromeos/network/network_ip_config.html
@@ -2,18 +2,28 @@ <link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html"> +<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator.html"> +<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_behavior.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="network_property_list.html"> <link rel="import" href="network_shared_css.html"> <dom-module id="network-ip-config"> <template> - <style include="network-shared iron-flex"></style> + <style include="network-shared iron-flex"> + cr-toggle { + margin-inline-start: var(--settings-control-label-spacing); + } + </style> <div class="property-box"> <div id="autoIPConfigLabel" class="start"> [[i18n('networkIPConfigAuto')]] </div> - <cr-toggle checked="{{automatic_}}" disabled="[[!editable]]" + <cr-policy-indicator indicator-type="[[getPolicyIndicatorType_( + networkProperties, 'IPAddressConfigType')]]"> + </cr-policy-indicator> + <cr-toggle checked="{{automatic_}}" + disabled="[[!canChangeIPConfigType_(editable, networkProperties)]]" on-change="onAutomaticChange_" aria-labelledby="autoIPConfigLabel"> </cr-toggle>
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_ip_config.js b/ui/webui/resources/cr_components/chromeos/network/network_ip_config.js index 4fba8ad..dea3b18 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_ip_config.js +++ b/ui/webui/resources/cr_components/chromeos/network/network_ip_config.js
@@ -10,7 +10,7 @@ Polymer({ is: 'network-ip-config', - behaviors: [I18nBehavior], + behaviors: [I18nBehavior, CrPolicyNetworkBehavior], properties: { /** @@ -110,6 +110,28 @@ } }, + /** + * Checks whether IP address config type can be changed. + * @param {boolean} editable + * @param {!CrOnc.NetworkProperties} networkProperties + * @return {boolean} true only if 'IPAddressConfigType' as well as all other + * IP address config related fields are editable. + * @private + */ + canChangeIPConfigType_: function(editable, networkProperties) { + if (!editable) { + return false; + } + const controlledProps = [ + 'IPAddressConfigType', 'StaticIPConfig.IPAddress', + 'StaticIPConfig.RoutingPrefix', 'StaticIPConfig.Gateway' + ]; + + return controlledProps.every( + setting => + !this.isNetworkPolicyPathEnforced(networkProperties, setting)); + }, + /** @private */ onAutomaticChange_: function() { if (!this.automatic_) {
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_nameservers.html b/ui/webui/resources/cr_components/chromeos/network/network_nameservers.html index a38f892..5b0a1a77 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_nameservers.html +++ b/ui/webui/resources/cr_components/chromeos/network/network_nameservers.html
@@ -4,6 +4,8 @@ <link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html"> <link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_radio_group/cr_radio_group.html"> +<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator.html"> +<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_behavior.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/html/md_select_css.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html"> @@ -32,6 +34,10 @@ margin-inline-start: 38px; } + .nameservers:not([changeable]) { + opacity: var(--cr-disabled-opacity); + } + #radioGroupDiv { align-items: center; display: block; @@ -39,28 +45,38 @@ padding-inline-start: var(--cr-section-padding); } + cr-policy-indicator { + /* Aligns with the other policy indicators. */ + margin-inline-end: calc(var(--settings-control-label-spacing) + 34px); + } </style> <div class="property-box"> - [[i18n('networkNameservers')]] + <div class="start"> + [[i18n('networkNameservers')]] + </div> + <cr-policy-indicator indicator-type="[[getPolicyIndicatorType_( + networkProperties, 'NameServersConfigType')]]"> + </cr-policy-indicator> </div> - <div id="radioGroupDiv"> <cr-radio-group id="nameserverType" class="layout vertical" selected="[[nameserversType_]]" on-selected-changed="onTypeChange_" aria-label="[[i18n('networkNameservers')]]"> <!-- Automatic nameservers --> - <cr-radio-button name="automatic"> + <cr-radio-button name="automatic" disabled="[[!canChangeConfigType_]]"> [[i18n('networkNameserversAutomatic')]] </cr-radio-button> <template is="dom-if" if="[[showNameservers_(nameserversType_, 'automatic', nameservers_)]]"> - <div class="nameservers">[[getNameserversString_(nameservers_)]]</div> + <div class="nameservers" changeable$="[[canChangeConfigType_]]"> + [[getNameserversString_(nameservers_)]] + </div> </template> <!-- Google nameservers --> - <cr-radio-button name="google"> + <cr-radio-button name="google" disabled="[[!canChangeConfigType_]]"> [[i18n('networkNameserversGoogle')]] <template is="dom-if" if="[[i18nExists('networkGoogleNameserversLearnMoreUrl')]]"> @@ -72,11 +88,13 @@ </cr-radio-button> <template is="dom-if" if="[[showNameservers_(nameserversType_, 'google', nameservers_)]]"> - <div class="nameservers">[[getNameserversString_(nameservers_)]]</div> + <div class$="nameservers"> + [[getNameserversString_(nameservers_)]] + </div> </template> <!-- Custom nameservers --> - <cr-radio-button name="custom"> + <cr-radio-button name="custom" disabled="[[!canChangeConfigType_]]"> [[i18n('networkNameserversCustom')]] </cr-radio-button> <template is="dom-if" if="[[showNameservers_(nameserversType_, @@ -85,7 +103,8 @@ <template is="dom-repeat" items="[[nameservers_]]"> <cr-input id="nameserver[[index]]" value="[[item]]" on-change="onValueChange_" - disabled="[[!canEdit_(editable, nameserversType_)]]"> + disabled="[[!canEditCustomNameServers_(editable, + nameserversType_, networkProperties)]]"> </cr-input> </template> </div>
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_nameservers.js b/ui/webui/resources/cr_components/chromeos/network/network_nameservers.js index 9a44715..d4087786 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_nameservers.js +++ b/ui/webui/resources/cr_components/chromeos/network/network_nameservers.js
@@ -8,7 +8,7 @@ Polymer({ is: 'network-nameservers', - behaviors: [I18nBehavior], + behaviors: [I18nBehavior, CrPolicyNetworkBehavior], properties: { /** @@ -54,6 +54,12 @@ return this.i18nAdvanced( 'networkNameserversGoogle', {substitutions: [], tags: ['a']}); } + }, + + /** @private */ + canChangeConfigType_: { + type: Boolean, + computed: 'computeCanChangeConfigType_(editable, networkProperties)', } }, @@ -134,12 +140,36 @@ /** * @param {boolean} editable + * @param {!CrOnc.NetworkProperties} networkProperties + * @return {boolean} True if the nameservers config type type can be changed. + * @private + */ + computeCanChangeConfigType_: function(editable, networkProperties) { + if (!editable) { + return false; + } + + return !this.isNetworkPolicyPathEnforced( + networkProperties, 'NameServersConfigType') && + !this.isNetworkPolicyPathEnforced( + networkProperties, 'StaticIPConfig.NameServers'); + }, + + /** + * @param {boolean} editable * @param {string} nameserversType + * @param {!CrOnc.NetworkProperties} networkProperties * @return {boolean} True if the nameservers are editable. * @private */ - canEdit_: function(editable, nameserversType) { - return editable && nameserversType == 'custom'; + canEditCustomNameServers_: function( + editable, nameserversType, networkProperties) { + return editable && nameserversType == 'custom' && + !this.isNetworkPolicyEnforced( + networkProperties.NameServersConfigType) && + !!networkProperties.StaticIPConfig && + !this.isNetworkPolicyEnforced( + networkProperties.StaticIPConfig.NameServers); }, /**
diff --git a/ui/webui/resources/cr_elements/policy/cr_policy_network_behavior.js b/ui/webui/resources/cr_elements/policy/cr_policy_network_behavior.js index e8ae4c5..dd564c7 100644 --- a/ui/webui/resources/cr_elements/policy/cr_policy_network_behavior.js +++ b/ui/webui/resources/cr_elements/policy/cr_policy_network_behavior.js
@@ -121,4 +121,88 @@ } return CrPolicyIndicatorType.NONE; }, + + /** + * @param {Object} dict A managed ONC dictionary. + * @param {string} path A path to a setting inside |dict|. + * @return {!CrOnc.ManagedProperty|undefined} The value of the setting at + * |path|. + * @private + */ + getSettingAtPath_: function(dict, path) { + const keys = path.split('.'); + for (let i = 0; i < keys.length; ++i) { + const key = keys[i]; + if (typeof dict !== 'object' || !(key in dict)) { + return undefined; + } + dict = dict[key]; + } + return dict; + }, + + /** + * Get managed property at the given path. If the property is not policy + * managed, return 'undefined'. If the property's value is 'undefined' return + * a non-editable policy managed 'CrOnc.ManagedProperty' object. + * @param {!CrOnc.NetworkProperties} networkProperties + * @param {string} path + * @return {!CrOnc.ManagedProperty|undefined} + * @private + */ + getManagedSettingAtPath_: function(networkProperties, path) { + if (!this.isPolicySource(networkProperties.Source)) { + return undefined; + } + const setting = this.getSettingAtPath_(networkProperties, path); + if (setting) { + return setting; + } + // If setting is not defined, return a non-editable managed property with + // 'undefined' value enforced by 'networkProperties.Source'. + return { + 'Effective': networkProperties.Source, + 'DeviceEditable': false, + 'UserEditable': false, + 'UserPolicy': undefined, + 'DevicePolicy': undefined + }; + }, + + /** + * @param {!CrOnc.NetworkProperties} networkProperties + * @param {string} path A path to a setting inside |networkProperties|. + * @return {boolean} True if the setting at |path| is managed by policy (e.g. + * 'StaticIPConfig.NameServers'). + */ + isNetworkPolicyPathManaged: function(networkProperties, path) { + return this.isNetworkPolicyControlled( + this.getManagedSettingAtPath_(networkProperties, path)); + }, + + /** + * @param {!CrOnc.NetworkProperties} networkProperties + * @param {string} path A path to a setting inside |networkProperties|. + * @return {boolean} True if the setting at |path| is enforced by policy (e.g. + * 'StaticIPConfig.NameServers'). + */ + isNetworkPolicyPathEnforced: function(networkProperties, path) { + return this.isNetworkPolicyEnforced( + this.getManagedSettingAtPath_(networkProperties, path)); + }, + + /** + * Get policy indicator type for the setting at |path|. + * @param {CrOnc.NetworkProperties} networkProperties + * @param {string} path + * @return {CrPolicyIndicatorType} + */ + getPolicyIndicatorType_: function(networkProperties, path) { + if (!this.isNetworkPolicyPathManaged(networkProperties, path)) { + return CrPolicyIndicatorType.NONE; + } + return networkProperties.Source == CrOnc.Source.DEVICE_POLICY ? + CrPolicyIndicatorType.DEVICE_POLICY : + CrPolicyIndicatorType.USER_POLICY; + }, };
diff --git a/ui/webui/resources/cr_elements/shared_vars_css.html b/ui/webui/resources/cr_elements/shared_vars_css.html index 74b01e40..ba6b742 100644 --- a/ui/webui/resources/cr_elements/shared_vars_css.html +++ b/ui/webui/resources/cr_elements/shared_vars_css.html
@@ -17,6 +17,7 @@ --google-grey-refresh-100: #F1F3F4; --google-grey-200: #E8EAED; --google-grey-400: #BDC1C6; + --google-grey-500-rgb: 158, 158, 158; --google-grey-600-rgb: 128, 134, 139; --google-grey-600: rgb(var(--google-grey-600-rgb)); /* -refresh differentiates from google-grey-700 in polymer's color.html. */ @@ -58,7 +59,7 @@ --cr-card-elevation: { background-color: rgba(255, 255, 255, .04); box-shadow: rgba(0, 0, 0, .3) 0 1px 2px 0, - rgba(0, 0, 0, .15) 0 4px 8px 3px; + rgba(0, 0, 0, .15) 0 4px 8px 3px; } /* TODO(dbeam): form-field-label, {section,title}-text, & toggle colors. */ @@ -66,7 +67,7 @@ --cr-form-field-label-color: var(--dark-secondary-color); --cr-link-color: var(--google-blue-300); --cr-menu-background-color: var(--google-grey-900); - --cr-menu-background-focus-color: rgba(60, 64, 67, .6); + --cr-menu-background-focus-color: rgba(var(--google-grey-800-rgb), .6); --cr-menu-background-sheen: rgba(255, 255, 255, .06); /* Only dark mode. */ --cr-menu-shadow: rgba(0, 0, 0, .3) 0 1px 2px 0, rgba(0, 0, 0, .15) 0 2px 6px 2px;