diff --git a/DEPS b/DEPS index 4d1d781..090f44c 100644 --- a/DEPS +++ b/DEPS
@@ -40,7 +40,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '99d4721171f9b8f23cd907ef3da938c4c5579ae9', + 'skia_revision': 'd689f7a5313a7fd501c2572c493fe6d91a88cba4', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other.
diff --git a/base/json/json_parser.cc b/base/json/json_parser.cc index e85c3d25..814b9c4 100644 --- a/base/json/json_parser.cc +++ b/base/json/json_parser.cc
@@ -144,6 +144,12 @@ explicit JSONStringValue(StringPiece piece) : Value(Type::STRING), string_piece_(piece) {} + ~JSONStringValue() override { + // Ugly hack that prevents ~Value() from trying to destroy string_value_. + // TODO(crbug.com/646113): Clean this up when StringValue will be removed. + type_ = Type::NONE; + } + // Overridden from Value: bool GetAsString(std::string* out_value) const override { string_piece_.CopyToString(out_value); @@ -153,6 +159,12 @@ *out_value = UTF8ToUTF16(string_piece_); return true; } + // base::Value::GetAsString contains a proper implementation now, so the old + // behavior is copied here. + // TODO(crbug.com/646113): Clean this up when StringValue will be removed. + bool GetAsString(const StringValue** out_value) const override { + return false; + } bool GetAsString(StringPiece* out_value) const override { *out_value = string_piece_; return true;
diff --git a/base/test/values_test_util.h b/base/test/values_test_util.h index 886c17d..04af92e5 100644 --- a/base/test/values_test_util.h +++ b/base/test/values_test_util.h
@@ -13,8 +13,8 @@ namespace base { class DictionaryValue; class ListValue; -class StringValue; class Value; +using StringValue = Value; // All the functions below expect that the value for the given key in // the given dictionary equals the given expected value.
diff --git a/base/value_conversions.h b/base/value_conversions.h index 452c587..6ce1bff 100644 --- a/base/value_conversions.h +++ b/base/value_conversions.h
@@ -14,8 +14,8 @@ class FilePath; class TimeDelta; -class StringValue; class Value; +using StringValue = Value; // The caller takes ownership of the returned value. BASE_EXPORT StringValue* CreateFilePathValue(const FilePath& in_value);
diff --git a/base/values.cc b/base/values.cc index 82b137a..145c0c11 100644 --- a/base/values.cc +++ b/base/values.cc
@@ -77,7 +77,8 @@ bool IsAssignmentSafe(Value::Type lhs, Value::Type rhs) { auto IsImplemented = [](Value::Type type) { return type == Value::Type::NONE || type == Value::Type::BOOLEAN || - type == Value::Type::INTEGER || type == Value::Type::DOUBLE; + type == Value::Type::INTEGER || type == Value::Type::DOUBLE || + type == Value::Type::STRING; }; return lhs == rhs || (IsImplemented(lhs) && IsImplemented(rhs)); @@ -91,13 +92,11 @@ } Value::Value(const Value& that) { - InternalCopyFrom(that); + InternalCopyConstructFrom(that); } Value::Value(Value&& that) { - // TODO(crbug.com/646113): Implement InternalMoveFrom for types where moving - // and copying differ. - InternalCopyFrom(that); + InternalMoveConstructFrom(std::move(that)); } Value::Value() : type_(Type::NONE) {} @@ -117,10 +116,12 @@ case Type::DOUBLE: double_value_ = 0.0; return; + case Type::STRING: + string_value_.Init(); + return; // TODO(crbug.com/646113): Implement these once the corresponding derived // classes are removed. - case Type::STRING: case Type::BINARY: case Type::LIST: case Type::DICTIONARY: @@ -140,10 +141,40 @@ } } +Value::Value(const char* in_string) : type_(Type::STRING) { + string_value_.Init(in_string); + DCHECK(IsStringUTF8(*string_value_)); +} + +Value::Value(const std::string& in_string) : type_(Type::STRING) { + string_value_.Init(in_string); + DCHECK(IsStringUTF8(*string_value_)); +} + +Value::Value(std::string&& in_string) : type_(Type::STRING) { + string_value_.Init(std::move(in_string)); + DCHECK(IsStringUTF8(*string_value_)); +} + +Value::Value(const char16* in_string) : type_(Type::STRING) { + string_value_.Init(UTF16ToUTF8(in_string)); +} + +Value::Value(const string16& in_string) : type_(Type::STRING) { + string_value_.Init(UTF16ToUTF8(in_string)); +} + +Value::Value(StringPiece in_string) : Value(in_string.as_string()) {} + Value& Value::operator=(const Value& that) { if (this != &that) { DCHECK(IsAssignmentSafe(type_, that.type_)); - InternalCopyFrom(that); + if (type_ == that.type_) { + InternalCopyAssignFrom(that); + } else { + InternalCleanup(); + InternalCopyConstructFrom(that); + } } return *this; @@ -151,16 +182,21 @@ Value& Value::operator=(Value&& that) { if (this != &that) { - // TODO(crbug.com/646113): Implement InternalMoveFrom for types where moving - // and copying differ. DCHECK(IsAssignmentSafe(type_, that.type_)); - InternalCopyFrom(that); + if (type_ == that.type_) { + InternalMoveAssignFrom(std::move(that)); + } else { + InternalCleanup(); + InternalMoveConstructFrom(std::move(that)); + } } return *this; } -Value::~Value() {} +Value::~Value() { + InternalCleanup(); +} // static const char* Value::GetTypeName(Value::Type type) { @@ -188,6 +224,11 @@ return 0.0; } +const std::string& Value::GetString() const { + CHECK(is_string()); + return *string_value_; +} + bool Value::GetAsBoolean(bool* out_value) const { if (out_value && is_bool()) { *out_value = bool_value_; @@ -217,19 +258,35 @@ } bool Value::GetAsString(std::string* out_value) const { - return false; + if (out_value && is_string()) { + *out_value = *string_value_; + return true; + } + return is_string(); } bool Value::GetAsString(string16* out_value) const { - return false; + if (out_value && is_string()) { + *out_value = UTF8ToUTF16(*string_value_); + return true; + } + return is_string(); } bool Value::GetAsString(const StringValue** out_value) const { - return false; + if (out_value && is_string()) { + *out_value = static_cast<const StringValue*>(this); + return true; + } + return is_string(); } bool Value::GetAsString(StringPiece* out_value) const { - return false; + if (out_value && is_string()) { + *out_value = *string_value_; + return true; + } + return is_string(); } bool Value::GetAsBinary(const BinaryValue** out_value) const { @@ -267,6 +324,10 @@ return new FundamentalValue(int_value_); case Type::DOUBLE: return new FundamentalValue(double_value_); + // For now, make StringValues for backward-compatibility. Convert to + // Value when that code is deleted. + case Type::STRING: + return new StringValue(*string_value_); default: // All other types should be handled by subclasses. @@ -292,6 +353,11 @@ return int_value_ == other->int_value_; case Type::DOUBLE: return double_value_ == other->double_value_; + // TODO(crbug.com/646113): Simplify this once JSONStringValue is removed. + case Type::STRING: { + std::string lhs, rhs; + return GetAsString(&lhs) && other->GetAsString(&rhs) && lhs == rhs; + } default: // This method should only be getting called for the above types -- all // subclasses need to provide their own implementation;. @@ -307,8 +373,7 @@ return a->Equals(b); } -void Value::InternalCopyFrom(const Value& that) { - type_ = that.type_; +void Value::InternalCopyFundamentalValue(const Value& that) { switch (type_) { case Type::NONE: // Nothing to do. @@ -324,9 +389,28 @@ double_value_ = that.double_value_; return; + default: + NOTREACHED(); + } +} + +void Value::InternalCopyConstructFrom(const Value& that) { + type_ = that.type_; + + switch (type_) { + case Type::NONE: + case Type::BOOLEAN: + case Type::INTEGER: + case Type::DOUBLE: + InternalCopyFundamentalValue(that); + return; + + case Type::STRING: + string_value_.Init(*that.string_value_); + return; + // TODO(crbug.com/646113): Implement these once the corresponding derived // classes are removed. - case Type::STRING: case Type::BINARY: case Type::LIST: case Type::DICTIONARY: @@ -334,60 +418,98 @@ } } -///////////////////// StringValue //////////////////// +void Value::InternalMoveConstructFrom(Value&& that) { + type_ = that.type_; -StringValue::StringValue(StringPiece in_value) - : Value(Type::STRING), value_(in_value.as_string()) { - DCHECK(IsStringUTF8(in_value)); + switch (type_) { + case Type::NONE: + case Type::BOOLEAN: + case Type::INTEGER: + case Type::DOUBLE: + InternalCopyFundamentalValue(that); + return; + + case Type::STRING: + string_value_.InitFromMove(std::move(that.string_value_)); + return; + + // TODO(crbug.com/646113): Implement these once the corresponding derived + // classes are removed. + case Type::BINARY: + case Type::LIST: + case Type::DICTIONARY: + return; + } } -StringValue::StringValue(const string16& in_value) - : Value(Type::STRING), value_(UTF16ToUTF8(in_value)) {} +void Value::InternalCopyAssignFrom(const Value& that) { + type_ = that.type_; -StringValue::~StringValue() { + switch (type_) { + case Type::NONE: + case Type::BOOLEAN: + case Type::INTEGER: + case Type::DOUBLE: + InternalCopyFundamentalValue(that); + return; + + case Type::STRING: + *string_value_ = *that.string_value_; + return; + + // TODO(crbug.com/646113): Implement these once the corresponding derived + // classes are removed. + case Type::BINARY: + case Type::LIST: + case Type::DICTIONARY: + return; + } } -std::string* StringValue::GetString() { - return &value_; +void Value::InternalMoveAssignFrom(Value&& that) { + type_ = that.type_; + + switch (type_) { + case Type::NONE: + case Type::BOOLEAN: + case Type::INTEGER: + case Type::DOUBLE: + InternalCopyFundamentalValue(that); + return; + + case Type::STRING: + *string_value_ = std::move(*that.string_value_); + return; + + // TODO(crbug.com/646113): Implement these once the corresponding derived + // classes are removed. + case Type::BINARY: + case Type::LIST: + case Type::DICTIONARY: + return; + } } -const std::string& StringValue::GetString() const { - return value_; -} +void Value::InternalCleanup() { + switch (type_) { + case Type::NONE: + case Type::BOOLEAN: + case Type::INTEGER: + case Type::DOUBLE: + // Nothing to do + return; -bool StringValue::GetAsString(std::string* out_value) const { - if (out_value) - *out_value = value_; - return true; -} + case Type::STRING: + string_value_.Destroy(); + return; -bool StringValue::GetAsString(string16* out_value) const { - if (out_value) - *out_value = UTF8ToUTF16(value_); - return true; -} - -bool StringValue::GetAsString(const StringValue** out_value) const { - if (out_value) - *out_value = this; - return true; -} - -bool StringValue::GetAsString(StringPiece* out_value) const { - if (out_value) - *out_value = value_; - return true; -} - -StringValue* StringValue::DeepCopy() const { - return new StringValue(value_); -} - -bool StringValue::Equals(const Value* other) const { - if (other->GetType() != GetType()) - return false; - std::string lhs, rhs; - return GetAsString(&lhs) && other->GetAsString(&rhs) && lhs == rhs; + // TODO(crbug.com/646113): Implement these once the corresponding derived + // classes are removed. + case Type::BINARY: + case Type::LIST: + case Type::DICTIONARY: + return; + } } ///////////////////// BinaryValue ////////////////////
diff --git a/base/values.h b/base/values.h index 22d6b231..e021f7be 100644 --- a/base/values.h +++ b/base/values.h
@@ -30,6 +30,7 @@ #include "base/base_export.h" #include "base/compiler_specific.h" #include "base/macros.h" +#include "base/memory/manual_constructor.h" #include "base/strings/string16.h" #include "base/strings/string_piece.h" @@ -38,9 +39,9 @@ class BinaryValue; class DictionaryValue; class ListValue; -class StringValue; class Value; using FundamentalValue = Value; +using StringValue = Value; // The Value class is the base class for Values. A Value can be instantiated // via the Create*Value() factory methods, or by directly creating instances of @@ -71,6 +72,19 @@ explicit Value(int in_int); explicit Value(double in_double); + // Value(const char*) and Value(const char16*) are required despite + // Value(const std::string&) and Value(const string16&) because otherwise the + // compiler will choose the Value(bool) constructor for these arguments. + // Value(std::string&&) allow for efficient move construction. + // Value(StringPiece) exists due to many callsites passing StringPieces as + // arguments. + explicit Value(const char* in_string); + explicit Value(const std::string& in_string); + explicit Value(std::string&& in_string); + explicit Value(const char16* in_string); + explicit Value(const string16& in_string); + explicit Value(StringPiece in_string); + Value& operator=(const Value& that); Value& operator=(Value&& that); @@ -101,6 +115,7 @@ bool GetBool() const; int GetInt() const; double GetDouble() const; // Implicitly converts from int if necessary. + const std::string& GetString() const; // These methods allow the convenient retrieval of the contents of the Value. // If the current object can be converted into the given type, the value is @@ -137,44 +152,26 @@ // NULLs are considered equal but different from Value::CreateNullValue(). static bool Equals(const Value* a, const Value* b); - private: - void InternalCopyFrom(const Value& that); - + protected: + // TODO(crbug.com/646113): Make this private once JSONStringValue is removed. Type type_; + private: + void InternalCopyFundamentalValue(const Value& that); + void InternalCopyConstructFrom(const Value& that); + void InternalMoveConstructFrom(Value&& that); + void InternalCopyAssignFrom(const Value& that); + void InternalMoveAssignFrom(Value&& that); + void InternalCleanup(); + union { bool bool_value_; int int_value_; double double_value_; + ManualConstructor<std::string> string_value_; }; }; -class BASE_EXPORT StringValue : public Value { - public: - // Initializes a StringValue with a UTF-8 narrow character string. - explicit StringValue(StringPiece in_value); - - // Initializes a StringValue with a string16. - explicit StringValue(const string16& in_value); - - ~StringValue() override; - - // Returns |value_| as a pointer or reference. - std::string* GetString(); - const std::string& GetString() const; - - // Overridden from Value: - bool GetAsString(std::string* out_value) const override; - bool GetAsString(string16* out_value) const override; - bool GetAsString(const StringValue** out_value) const override; - bool GetAsString(StringPiece* out_value) const override; - StringValue* DeepCopy() const override; - bool Equals(const Value* other) const override; - - private: - std::string value_; -}; - class BASE_EXPORT BinaryValue: public Value { public: // Creates a BinaryValue with a null buffer and size of 0. @@ -545,11 +542,6 @@ BASE_EXPORT std::ostream& operator<<(std::ostream& out, const Value& value); BASE_EXPORT inline std::ostream& operator<<(std::ostream& out, - const StringValue& value) { - return out << static_cast<const Value&>(value); -} - -BASE_EXPORT inline std::ostream& operator<<(std::ostream& out, const DictionaryValue& value) { return out << static_cast<const Value&>(value); }
diff --git a/base/values_unittest.cc b/base/values_unittest.cc index 511d9f983..9f2d9d62 100644 --- a/base/values_unittest.cc +++ b/base/values_unittest.cc
@@ -40,6 +40,48 @@ EXPECT_EQ(-4.655, value.GetDouble()); } +TEST(ValuesTest, ConstructStringFromConstCharPtr) { + const char* str = "foobar"; + StringValue value(str); + EXPECT_EQ(Value::Type::STRING, value.type()); + EXPECT_EQ("foobar", value.GetString()); +} + +TEST(ValuesTest, ConstructStringFromStdStringConstRef) { + std::string str = "foobar"; + StringValue value(str); + EXPECT_EQ(Value::Type::STRING, value.type()); + EXPECT_EQ("foobar", value.GetString()); +} + +TEST(ValuesTest, ConstructStringFromStdStringRefRef) { + std::string str = "foobar"; + StringValue value(std::move(str)); + EXPECT_EQ(Value::Type::STRING, value.type()); + EXPECT_EQ("foobar", value.GetString()); +} + +TEST(ValuesTest, ConstructStringFromConstChar16Ptr) { + string16 str = ASCIIToUTF16("foobar"); + StringValue value(str.c_str()); + EXPECT_EQ(Value::Type::STRING, value.type()); + EXPECT_EQ("foobar", value.GetString()); +} + +TEST(ValuesTest, ConstructStringFromString16) { + string16 str = ASCIIToUTF16("foobar"); + StringValue value(str); + EXPECT_EQ(Value::Type::STRING, value.type()); + EXPECT_EQ("foobar", value.GetString()); +} + +TEST(ValuesTest, ConstructStringFromStringPiece) { + StringPiece str = "foobar"; + StringValue value(str); + EXPECT_EQ(Value::Type::STRING, value.type()); + EXPECT_EQ("foobar", value.GetString()); +} + // Group of tests for the copy constructors and copy-assigmnent. For equality // checks comparisons of the interesting fields are done instead of relying on // Equals being correct. @@ -91,6 +133,19 @@ EXPECT_EQ(value.GetDouble(), blank.GetDouble()); } +TEST(ValuesTest, CopyString) { + StringValue value("foobar"); + StringValue copied_value(value); + EXPECT_EQ(value.type(), copied_value.type()); + EXPECT_EQ(value.GetString(), copied_value.GetString()); + + Value blank; + + blank = value; + EXPECT_EQ(value.type(), blank.type()); + EXPECT_EQ(value.GetString(), blank.GetString()); +} + // Group of tests for the move constructors and move-assigmnent. TEST(ValuesTest, MoveBool) { FundamentalValue true_value(true); @@ -140,6 +195,19 @@ EXPECT_EQ(654.38, blank.GetDouble()); } +TEST(ValuesTest, MoveString) { + StringValue value("foobar"); + StringValue moved_value(std::move(value)); + EXPECT_EQ(Value::Type::STRING, moved_value.type()); + EXPECT_EQ("foobar", moved_value.GetString()); + + Value blank; + + blank = StringValue("foobar"); + EXPECT_EQ(Value::Type::STRING, blank.type()); + EXPECT_EQ("foobar", blank.GetString()); +} + TEST(ValuesTest, Basic) { // Test basic dictionary getting/setting DictionaryValue settings;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java index 5428229e..6e6102d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -86,7 +86,6 @@ public static final String NTP_SNIPPETS_INCREASED_VISIBILITY = "NTPSnippetsIncreasedVisibility"; public static final String NTP_SNIPPETS_SAVE_TO_OFFLINE = "NTPSaveToOffline"; public static final String NTP_SNIPPETS_OFFLINE_BADGE = "NTPOfflineBadge"; - public static final String NTP_SUGGESTIONS_SECTION_DISMISSAL = "NTPSuggestionsSectionDismissal"; public static final String NTP_SUGGESTIONS_STANDALONE_UI = "NTPSuggestionsStandaloneUI"; public static final String SERVICE_WORKER_PAYMENT_APPS = "ServiceWorkerPaymentApps"; public static final String TAB_REPARENTING = "TabReparenting";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java index 4d090a9b..26c56d1e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java
@@ -12,7 +12,6 @@ import org.chromium.chrome.browser.ntp.snippets.CategoryStatus.CategoryStatusEnum; import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; import org.chromium.chrome.browser.ntp.snippets.SnippetsBridge; -import org.chromium.chrome.browser.ntp.snippets.SnippetsConfig; import org.chromium.chrome.browser.ntp.snippets.SuggestionsSource; import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; import org.chromium.chrome.browser.suggestions.SuggestionsRanker; @@ -222,8 +221,6 @@ */ @Override public void dismissSection(SuggestionsSection section) { - assert SnippetsConfig.isSectionDismissalEnabled(); - mUiDelegate.getSuggestionsSource().dismissCategory(section.getCategory()); removeSection(section); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java index c085f9fd..b3eca40 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java
@@ -15,7 +15,6 @@ import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; import org.chromium.chrome.browser.ntp.snippets.SnippetArticleViewHolder; import org.chromium.chrome.browser.ntp.snippets.SnippetsBridge; -import org.chromium.chrome.browser.ntp.snippets.SnippetsConfig; import org.chromium.chrome.browser.ntp.snippets.SuggestionsSource; import org.chromium.chrome.browser.offlinepages.ClientId; import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; @@ -468,9 +467,7 @@ * (as opposed to individual items in it). */ private Set<Integer> getSectionDismissalRange() { - if (hasSuggestions() || !SnippetsConfig.isSectionDismissalEnabled()) { - return Collections.emptySet(); - } + if (hasSuggestions()) return Collections.emptySet(); if (!mMoreButton.isVisible()) { assert getStartingOffsetForChild(mStatus) == 1;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsConfig.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsConfig.java index 6ea61fe0..26a1ff1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsConfig.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsConfig.java
@@ -20,10 +20,6 @@ return ChromeFeatureList.isEnabled(ChromeFeatureList.NTP_SNIPPETS_OFFLINE_BADGE); } - public static boolean isSectionDismissalEnabled() { - return ChromeFeatureList.isEnabled(ChromeFeatureList.NTP_SUGGESTIONS_SECTION_DISMISSAL); - } - /** https://crbug.com/660837 */ public static boolean isIncreasedCardVisibilityEnabled() { return ChromeFeatureList.isEnabled(ChromeFeatureList.NTP_SNIPPETS_INCREASED_VISIBILITY);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java index 52125c7..6cd872f 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java
@@ -50,7 +50,6 @@ import org.chromium.base.ContextUtils; import org.chromium.base.test.util.Feature; import org.chromium.chrome.R; -import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.DisableHistogramsRule; import org.chromium.chrome.browser.EnableFeatures; import org.chromium.chrome.browser.ntp.ContextMenuManager; @@ -822,7 +821,6 @@ @Test @Feature({"Ntp"}) - @EnableFeatures(ChromeFeatureList.NTP_SUGGESTIONS_SECTION_DISMISSAL) public void testAllDismissedVisibility() { ArgumentCaptor<DestructionObserver> observers = ArgumentCaptor.forClass(DestructionObserver.class);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java index 198e424e..3e10559 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java
@@ -37,7 +37,6 @@ import org.chromium.base.Callback; import org.chromium.base.test.util.Feature; -import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.DisableHistogramsRule; import org.chromium.chrome.browser.EnableFeatures; import org.chromium.chrome.browser.ntp.cards.ContentSuggestionsTestUtils.CategoryInfoBuilder; @@ -92,7 +91,6 @@ @Test @Feature({"Ntp"}) - @EnableFeatures(ChromeFeatureList.NTP_SUGGESTIONS_SECTION_DISMISSAL) public void testDismissSibling() { List<SnippetArticle> snippets = createDummySuggestions(3, TEST_CATEGORY_ID); SuggestionsSection section = createSectionWithReloadAction(true); @@ -118,32 +116,6 @@ @Test @Feature({"Ntp"}) - @EnableFeatures({}) - public void testDismissSiblingWithSectionDismissalDisabled() { - List<SnippetArticle> snippets = createDummySuggestions(3, TEST_CATEGORY_ID); - SuggestionsSection section = createSectionWithReloadAction(true); - - section.setStatus(CategoryStatus.AVAILABLE); - assertNotNull(section.getActionItemForTesting()); - - // Without snippets. - assertEquals(ItemViewType.HEADER, section.getItemViewType(0)); - assertEquals(Collections.emptySet(), section.getItemDismissalGroup(0)); - assertEquals(ItemViewType.STATUS, section.getItemViewType(1)); - assertEquals(Collections.emptySet(), section.getItemDismissalGroup(1)); - assertEquals(ItemViewType.ACTION, section.getItemViewType(2)); - assertEquals(Collections.emptySet(), section.getItemDismissalGroup(2)); - - // With snippets. - section.setSuggestions(snippets, CategoryStatus.AVAILABLE, /* replaceExisting = */ true); - assertEquals(ItemViewType.HEADER, section.getItemViewType(0)); - assertEquals(Collections.emptySet(), section.getItemDismissalGroup(0)); - assertEquals(ItemViewType.SNIPPET, section.getItemViewType(1)); - assertEquals(Collections.singleton(1), section.getItemDismissalGroup(1)); - } - - @Test - @Feature({"Ntp"}) public void testAddSuggestionsNotification() { final int suggestionCount = 5; List<SnippetArticle> snippets = createDummySuggestions(suggestionCount, @@ -259,7 +231,6 @@ @Test @Feature({"Ntp"}) - @EnableFeatures({ChromeFeatureList.NTP_SUGGESTIONS_SECTION_DISMISSAL}) public void testDismissSection() { SuggestionsSection section = createSectionWithReloadAction(false); section.setStatus(CategoryStatus.AVAILABLE); @@ -724,7 +695,6 @@ @Test @Feature({"Ntp"}) - @EnableFeatures(ChromeFeatureList.NTP_SUGGESTIONS_SECTION_DISMISSAL) public void testGetItemDismissalGroupWithSuggestions() { List<SnippetArticle> suggestions = createDummySuggestions(5, TEST_CATEGORY_ID); SuggestionsSection section = createSectionWithReloadAction(false); @@ -736,7 +706,6 @@ @Test @Feature({"Ntp"}) - @EnableFeatures(ChromeFeatureList.NTP_SUGGESTIONS_SECTION_DISMISSAL) public void testGetItemDismissalGroupWithActionItem() { SuggestionsSection section = createSectionWithReloadAction(true); assertThat(section.getItemDismissalGroup(1).size(), is(2)); @@ -745,7 +714,6 @@ @Test @Feature({"Ntp"}) - @EnableFeatures(ChromeFeatureList.NTP_SUGGESTIONS_SECTION_DISMISSAL) public void testGetItemDismissalGroupWithoutActionItem() { SuggestionsSection section = createSectionWithReloadAction(false); assertThat(section.getItemDismissalGroup(1).size(), is(1));
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index a969e90..ccf4d0a4 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -6761,18 +6761,6 @@ <message name="IDS_FLAGS_DATASAVER_PROMPT_DEMO_MODE" desc="The value of the Data Saver prompt flag which always shows prompt on network properties change."> Demo mode </message> - <message name="IDS_FLAGS_SUPERVISED_USER_SAFESITES_NAME" desc="Name of the flag to enable/disable the supervised user SafeSites filtering feature."> - Child account SafeSites filtering - </message> - <message name="IDS_FLAGS_SUPERVISED_USER_SAFESITES_DESCRIPTION" desc="Description for the flag to enable/disable the supervised user SafeSites filtering feature."> - Enable or disable SafeSites filtering for child accounts. - </message> - <message name="IDS_SUPERVISED_USER_SAFESITES_BLACKLIST_ONLY" desc="Description for the choice to enable only the static blacklist in the supervised user SafeSites filtering feature."> - Static blacklist only - </message> - <message name="IDS_SUPERVISED_USER_SAFESITES_ONLINE_CHECK_ONLY" desc="Description for the choice to enable only the online check in the supervised user SafeSites filtering feature."> - Online check only - </message> <message name="IDS_FLAGS_DISABLE_UNIFIED_MEDIA_PIPELINE_NAME" desc="Title for the flag to disable the unified media pipeline on Android."> Disables the unified media pipeline on Android. </message> @@ -8049,7 +8037,7 @@ <!-- Supervised User Block Interstitial data --> <message name="IDS_BLOCK_INTERSTITIAL_DEFAULT_FEEDBACK_TEXT" desc="The default text for feedback about a blocked site."> - <ph name="REASON">$1<ex>This site was blocked due to the SafeSites filter.</ex></ph> + <ph name="REASON">$1<ex>It may have mature content.</ex></ph> I don't think this site should be blocked! </message>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 78ebb3d..d9688de 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -418,22 +418,6 @@ }; #endif // OS_CHROMEOS -const FeatureEntry::Choice kSupervisedUserSafeSitesChoices[] = { - { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, - { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, - switches::kSupervisedUserSafeSites, - "enabled" }, - { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, - switches::kSupervisedUserSafeSites, - "disabled" }, - { IDS_SUPERVISED_USER_SAFESITES_BLACKLIST_ONLY, - switches::kSupervisedUserSafeSites, - "blacklist-only" }, - { IDS_SUPERVISED_USER_SAFESITES_ONLINE_CHECK_ONLY, - switches::kSupervisedUserSafeSites, - "online-check-only" } -}; - const FeatureEntry::Choice kV8CacheOptionsChoices[] = { { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, switches::kV8CacheOptions, "none" }, @@ -1600,9 +1584,6 @@ IDS_FLAGS_DATASAVER_PROMPT_DESCRIPTION, kOsCrOS, MULTI_VALUE_TYPE(kDataSaverPromptChoices)}, #endif // OS_CHROMEOS - {"supervised-user-safesites", IDS_FLAGS_SUPERVISED_USER_SAFESITES_NAME, - IDS_FLAGS_SUPERVISED_USER_SAFESITES_DESCRIPTION, kOsAll, - MULTI_VALUE_TYPE(kSupervisedUserSafeSitesChoices)}, #if defined(OS_ANDROID) {"enable-autofill-keyboard-accessory-view", IDS_FLAGS_AUTOFILL_ACCESSORY_VIEW_NAME,
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index 593b2ca1..9854124 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -65,7 +65,6 @@ &ntp_snippets::kForeignSessionsSuggestionsFeature, &ntp_snippets::kOfflineBadgeFeature, &ntp_snippets::kSaveToOfflineFeature, - &ntp_snippets::kSectionDismissalFeature, &offline_pages::kBackgroundLoaderForDownloadsFeature, &offline_pages::kOfflinePagesCTFeature, // See crbug.com/620421. &offline_pages::kOfflinePagesSharingFeature,
diff --git a/chrome/browser/android/vr_shell/OWNERS b/chrome/browser/android/vr_shell/OWNERS index 1b51b3c..0b3ab0a 100644 --- a/chrome/browser/android/vr_shell/OWNERS +++ b/chrome/browser/android/vr_shell/OWNERS
@@ -4,3 +4,4 @@ bshe@chromium.org girard@chromium.org mthiesse@chromium.org +cjgrant@chromium.org
diff --git a/chrome/browser/chromeos/input_method/candidate_window_controller_impl.cc b/chrome/browser/chromeos/input_method/candidate_window_controller_impl.cc index 1c84d39..a291ad1 100644 --- a/chrome/browser/chromeos/input_method/candidate_window_controller_impl.cc +++ b/chrome/browser/chromeos/input_method/candidate_window_controller_impl.cc
@@ -12,6 +12,7 @@ #include "ash/wm/window_util.h" #include "base/logging.h" #include "chrome/browser/chromeos/input_method/mode_indicator_controller.h" +#include "chrome/browser/ui/ash/ash_util.h" #include "ui/base/ime/ime_bridge.h" #include "ui/chromeos/ime/infolist_window.h" #include "ui/views/widget/widget.h" @@ -44,12 +45,19 @@ if (candidate_window_view_) return; - aura::Window* active_window = ash::wm::GetActiveWindow(); - candidate_window_view_ = - new ui::ime::CandidateWindowView(ash::Shell::GetContainer( - active_window ? active_window->GetRootWindow() - : ash::Shell::GetTargetRootWindow(), - ash::kShellWindowId_SettingBubbleContainer)); + // TODO(moshayedi): crbug.com/684658. Setting parent is nullptr in mash is + // just for the sake of not crashing. It doesn't provide the same behaviour + // as we have in ChromeOS. For example, candidate pop-up disappears when + // dragging the window in mash, but it shouldn't. + gfx::NativeView parent = nullptr; + if (!chrome::IsRunningInMash()) { + aura::Window* active_window = ash::wm::GetActiveWindow(); + parent = ash::Shell::GetContainer( + active_window ? active_window->GetRootWindow() + : ash::Shell::GetTargetRootWindow(), + ash::kShellWindowId_SettingBubbleContainer); + } + candidate_window_view_ = new ui::ime::CandidateWindowView(parent); candidate_window_view_->AddObserver(this); candidate_window_view_->SetCursorBounds(cursor_bounds_, composition_head_); views::Widget* widget = candidate_window_view_->InitWidget();
diff --git a/chrome/browser/chromeos/login/screens/user_image_model.cc b/chrome/browser/chromeos/login/screens/user_image_model.cc index 797a4d5b..28604c3 100644 --- a/chrome/browser/chromeos/login/screens/user_image_model.cc +++ b/chrome/browser/chromeos/login/screens/user_image_model.cc
@@ -12,6 +12,7 @@ const char UserImageModel::kContextKeyProfilePictureDataURL[] = "profilePictureDataURL"; const char UserImageModel::kContextKeySelectedImageURL[] = "selectedImageURL"; +const char UserImageModel::kContextKeyHasGaiaAccount[] = "hasGaiaAccount"; UserImageModel::UserImageModel(BaseScreenDelegate* base_screen_delegate) : BaseScreen(base_screen_delegate, OobeScreen::SCREEN_USER_IMAGE_PICKER) {}
diff --git a/chrome/browser/chromeos/login/screens/user_image_model.h b/chrome/browser/chromeos/login/screens/user_image_model.h index 9e9a0617..2f75110 100644 --- a/chrome/browser/chromeos/login/screens/user_image_model.h +++ b/chrome/browser/chromeos/login/screens/user_image_model.h
@@ -19,6 +19,7 @@ static const char kContextKeyIsCameraPresent[]; static const char kContextKeySelectedImageURL[]; static const char kContextKeyProfilePictureDataURL[]; + static const char kContextKeyHasGaiaAccount[]; explicit UserImageModel(BaseScreenDelegate* base_screen_delegate); ~UserImageModel() override;
diff --git a/chrome/browser/chromeos/login/screens/user_image_screen.cc b/chrome/browser/chromeos/login/screens/user_image_screen.cc index 99352fe..73e2202 100644 --- a/chrome/browser/chromeos/login/screens/user_image_screen.cc +++ b/chrome/browser/chromeos/login/screens/user_image_screen.cc
@@ -280,8 +280,14 @@ kContextKeySelectedImageURL, default_user_image::GetDefaultImageUrl(selected_image_)); - // Start fetching the profile image. - GetUserImageManager()->DownloadProfileImage(kProfileDownloadReason); + const user_manager::User* user = GetUser(); + // Fetch profile image for GAIA accounts. + if (user && user->HasGaiaAccount()) { + GetContextEditor().SetBoolean(kContextKeyHasGaiaAccount, true); + GetUserImageManager()->DownloadProfileImage(kProfileDownloadReason); + } else { + GetContextEditor().SetBoolean(kContextKeyHasGaiaAccount, false); + } } void UserImageScreen::Hide() {
diff --git a/chrome/browser/chromeos/settings/system_settings_provider.h b/chrome/browser/chromeos/settings/system_settings_provider.h index 802beb5..0a59bc5 100644 --- a/chrome/browser/chromeos/settings/system_settings_provider.h +++ b/chrome/browser/chromeos/settings/system_settings_provider.h
@@ -15,7 +15,8 @@ #include "third_party/icu/source/i18n/unicode/timezone.h" namespace base { -class StringValue; +class Value; +using StringValue = Value; } namespace chromeos {
diff --git a/chrome/browser/extensions/api/streams_private/streams_private_api.cc b/chrome/browser/extensions/api/streams_private/streams_private_api.cc index dc12dac..21c333a6 100644 --- a/chrome/browser/extensions/api/streams_private/streams_private_api.cc +++ b/chrome/browser/extensions/api/streams_private/streams_private_api.cc
@@ -37,9 +37,8 @@ while (headers->EnumerateHeaderLines(&iter, &header_name, &header_value)) { base::Value* existing_value = NULL; if (result->Get(header_name, &existing_value)) { - base::StringValue* existing_string_value = - static_cast<base::StringValue*>(existing_value); - existing_string_value->GetString()->append(", ").append(header_value); + *existing_value = + base::Value(existing_value->GetString() + ", " + header_value); } else { result->SetString(header_name, header_value); }
diff --git a/chrome/browser/extensions/webstore_data_fetcher.cc b/chrome/browser/extensions/webstore_data_fetcher.cc index c914ff3..e8e8b69 100644 --- a/chrome/browser/extensions/webstore_data_fetcher.cc +++ b/chrome/browser/extensions/webstore_data_fetcher.cc
@@ -37,15 +37,26 @@ WebstoreDataFetcher::~WebstoreDataFetcher() {} +void WebstoreDataFetcher::SetJsonPostData(const std::string& json) { + json_post_data_ = json; +} + void WebstoreDataFetcher::Start() { GURL webstore_data_url(extension_urls::GetWebstoreItemJsonDataURL(id_)); - + net::URLFetcher::RequestType request_type = + json_post_data_.empty() ? net::URLFetcher::GET : net::URLFetcher::POST; webstore_data_url_fetcher_ = - net::URLFetcher::Create(webstore_data_url, net::URLFetcher::GET, this); + net::URLFetcher::Create(webstore_data_url, request_type, this); webstore_data_url_fetcher_->SetRequestContext(request_context_); webstore_data_url_fetcher_->SetReferrer(referrer_url_.spec()); webstore_data_url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DISABLE_CACHE); + + if (!json_post_data_.empty()) { + webstore_data_url_fetcher_->SetUploadData("application/json", + json_post_data_); + } + if (max_auto_retries_ > 0) { webstore_data_url_fetcher_->SetMaxRetriesOn5xx(max_auto_retries_); webstore_data_url_fetcher_->SetAutomaticallyRetryOnNetworkChanges(
diff --git a/chrome/browser/extensions/webstore_data_fetcher.h b/chrome/browser/extensions/webstore_data_fetcher.h index bcb48a5c..7179fb7c 100644 --- a/chrome/browser/extensions/webstore_data_fetcher.h +++ b/chrome/browser/extensions/webstore_data_fetcher.h
@@ -37,6 +37,10 @@ const std::string webstore_item_id); ~WebstoreDataFetcher() override; + // Makes this request use a POST instead of GET, and sends |json| in the + // body of the request. If |json| is empty, this is a no-op. + void SetJsonPostData(const std::string& json); + void Start(); void set_max_auto_retries(int max_retries) { @@ -54,6 +58,7 @@ net::URLRequestContextGetter* request_context_; GURL referrer_url_; std::string id_; + std::string json_post_data_; // For fetching webstore JSON data. std::unique_ptr<net::URLFetcher> webstore_data_url_fetcher_;
diff --git a/chrome/browser/extensions/webstore_inline_installer.cc b/chrome/browser/extensions/webstore_inline_installer.cc index 9e992bc..38931a3 100644 --- a/chrome/browser/extensions/webstore_inline_installer.cc +++ b/chrome/browser/extensions/webstore_inline_installer.cc
@@ -4,11 +4,17 @@ #include "chrome/browser/extensions/webstore_inline_installer.h" +#include <utility> + +#include "base/json/json_writer.h" #include "base/strings/stringprintf.h" +#include "base/values.h" +#include "chrome/browser/extensions/webstore_data_fetcher.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h" #include "content/public/browser/navigation_details.h" +#include "content/public/browser/navigation_entry.h" #include "content/public/browser/web_contents.h" using content::WebContents; @@ -95,6 +101,41 @@ return true; } +std::string WebstoreInlineInstaller::GetJsonPostData() { + // web_contents() might return null during tab destruction. This object would + // also be destroyed shortly thereafter but check to be on the safe side. + if (!web_contents()) + return std::string(); + + content::NavigationController& navigation_controller = + web_contents()->GetController(); + content::NavigationEntry* navigation_entry = + navigation_controller.GetLastCommittedEntry(); + + if (navigation_entry) { + const std::vector<GURL>& redirect_urls = + navigation_entry->GetRedirectChain(); + + if (!redirect_urls.empty()) { + base::DictionaryValue dictionary; + dictionary.SetString("id", id()); + dictionary.SetString("referrer", requestor_url_.spec()); + std::unique_ptr<base::ListValue> redirect_chain = + base::MakeUnique<base::ListValue>(); + for (const GURL& url : redirect_urls) { + redirect_chain->AppendString(url.spec()); + } + dictionary.Set("redirect_chain", std::move(redirect_chain)); + + std::string json; + base::JSONWriter::Write(dictionary, &json); + return json; + } + } + + return std::string(); +} + bool WebstoreInlineInstaller::CheckRequestorAlive() const { // The frame or tab may have gone away - cancel installation in that case. return host_ != nullptr && web_contents() != nullptr;
diff --git a/chrome/browser/extensions/webstore_inline_installer.h b/chrome/browser/extensions/webstore_inline_installer.h index 9e11fa4..bc711be 100644 --- a/chrome/browser/extensions/webstore_inline_installer.h +++ b/chrome/browser/extensions/webstore_inline_installer.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_EXTENSIONS_WEBSTORE_INLINE_INSTALLER_H_ #define CHROME_BROWSER_EXTENSIONS_WEBSTORE_INLINE_INSTALLER_H_ +#include <memory> #include <string> #include "base/macros.h" @@ -49,6 +50,7 @@ ~WebstoreInlineInstaller() override; // Implementations WebstoreStandaloneInstaller Template Method's hooks. + std::string GetJsonPostData() override; bool CheckRequestorAlive() const override; const GURL& GetRequestorURL() const override; bool ShouldShowPostInstallUI() const override;
diff --git a/chrome/browser/extensions/webstore_inline_installer_browsertest.cc b/chrome/browser/extensions/webstore_inline_installer_browsertest.cc index 5ae1fef..35d5edc9 100644 --- a/chrome/browser/extensions/webstore_inline_installer_browsertest.cc +++ b/chrome/browser/extensions/webstore_inline_installer_browsertest.cc
@@ -4,9 +4,11 @@ #include "chrome/browser/extensions/webstore_inline_installer.h" +#include "base/json/json_reader.h" #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" +#include "base/values.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/extensions/extension_install_prompt.h" #include "chrome/browser/extensions/extension_service.h" @@ -25,6 +27,8 @@ #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" #include "extensions/common/permissions/permission_set.h" +#include "net/dns/mock_host_resolver.h" +#include "net/test/embedded_test_server/http_request.h" #include "url/gurl.h" using content::WebContents; @@ -40,6 +44,9 @@ const char kTestDataPath[] = "extensions/api_test/webstore_inline_install"; const char kCrxFilename[] = "extension.crx"; +const char kRedirect1Domain[] = "redirect1.com"; +const char kRedirect2Domain[] = "redirect2.com"; + // A struct for letting us store the actual parameters that were passed to // the install callback. struct InstallResult { @@ -363,6 +370,75 @@ RunTest("runTest"); } +class WebstoreInlineInstallerRedirectTest : public WebstoreInlineInstallerTest { + public: + WebstoreInlineInstallerRedirectTest() : cws_request_received_(false) {} + ~WebstoreInlineInstallerRedirectTest() override {} + + void SetUpInProcessBrowserTestFixture() override { + WebstoreInstallerTest::SetUpInProcessBrowserTestFixture(); + host_resolver()->AddRule(kRedirect1Domain, "127.0.0.1"); + host_resolver()->AddRule(kRedirect2Domain, "127.0.0.1"); + } + + void ProcessServerRequest( + const net::test_server::HttpRequest& request) override { + if (request.content.find("redirect_chain") != std::string::npos) { + cws_request_received_ = true; + + std::unique_ptr<base::Value> contents = + base::JSONReader::Read(request.content); + ASSERT_EQ(base::Value::Type::DICTIONARY, contents->GetType()); + cws_request_json_data_ = base::DictionaryValue::From(std::move(contents)); + } + } + + bool cws_request_received_; + std::unique_ptr<base::DictionaryValue> cws_request_json_data_; +}; + +// Test that an install from a page arrived at via redirects includes the +// redirect information in the webstore request. +IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerRedirectTest, + IncludesRedirectData) { + // Hand craft a url that will cause the test server to issue redirects. + const std::vector<std::string> redirects = {kRedirect1Domain, + kRedirect2Domain}; + net::HostPortPair host_port = embedded_test_server()->host_port_pair(); + std::string redirect_chain; + for (const auto& redirect : redirects) { + std::string redirect_url = base::StringPrintf( + "http://%s:%d/server-redirect?", redirect.c_str(), host_port.port()); + redirect_chain += redirect_url; + } + const GURL install_url = + GURL(redirect_chain + + GenerateTestServerUrl(kAppDomain, "install.html").spec()); + + AutoAcceptInstall(); + ui_test_utils::NavigateToURL(browser(), install_url); + RunTest("runTest"); + + EXPECT_TRUE(cws_request_received_); + ASSERT_NE(nullptr, cws_request_json_data_); + + base::ListValue* redirect_list = nullptr; + cws_request_json_data_->GetList("redirect_chain", &redirect_list); + ASSERT_NE(nullptr, redirect_list); + + // Check that the expected domains are in the redirect list. + const std::vector<std::string> expected_redirect_domains = { + kRedirect1Domain, kRedirect2Domain, kAppDomain}; + ASSERT_EQ(expected_redirect_domains.size(), redirect_list->GetSize()); + int i = 0; + for (const auto& value : *redirect_list) { + std::string value_string; + ASSERT_TRUE(value->GetAsString(&value_string)); + GURL redirect_url(value_string); + EXPECT_EQ(expected_redirect_domains[i++], redirect_url.host()); + } +} + class WebstoreInlineInstallerListenerTest : public WebstoreInlineInstallerTest { public: WebstoreInlineInstallerListenerTest() {}
diff --git a/chrome/browser/extensions/webstore_installer_test.cc b/chrome/browser/extensions/webstore_installer_test.cc index 1cd0398..967a525 100644 --- a/chrome/browser/extensions/webstore_installer_test.cc +++ b/chrome/browser/extensions/webstore_installer_test.cc
@@ -37,6 +37,8 @@ using extensions::WebstoreInlineInstallerFactory; using extensions::WebstoreStandaloneInstaller; +using net::test_server::HttpRequest; + WebstoreInstallerTest::WebstoreInstallerTest( const std::string& webstore_domain, const std::string& test_data_path, @@ -54,6 +56,9 @@ void WebstoreInstallerTest::SetUpCommandLine(base::CommandLine* command_line) { ExtensionBrowserTest::SetUpCommandLine(command_line); + + embedded_test_server()->RegisterRequestMonitor(base::Bind( + &WebstoreInstallerTest::ProcessServerRequest, base::Unretained(this))); // We start the test server now instead of in // SetUpInProcessBrowserTestFixture so that we can get its port number. ASSERT_TRUE(embedded_test_server()->Start()); @@ -137,6 +142,8 @@ ExecuteJavaScriptWithUserGestureForTests(base::UTF8ToUTF16(script)); } +void WebstoreInstallerTest::ProcessServerRequest(const HttpRequest& request) {} + void WebstoreInstallerTest::AutoAcceptInstall() { install_auto_confirm_.reset(); // Destroy any old override first. install_auto_confirm_.reset(new extensions::ScopedTestDialogAutoConfirm(
diff --git a/chrome/browser/extensions/webstore_installer_test.h b/chrome/browser/extensions/webstore_installer_test.h index 4c67ef2b..5f6f98a1 100644 --- a/chrome/browser/extensions/webstore_installer_test.h +++ b/chrome/browser/extensions/webstore_installer_test.h
@@ -21,6 +21,12 @@ class WebContents; } +namespace net { +namespace test_server { +struct HttpRequest; +} +} + class WebstoreInstallerTest : public ExtensionBrowserTest { public: WebstoreInstallerTest(const std::string& webstore_domain, @@ -54,6 +60,10 @@ // Runs a test without waiting for any results from the renderer. void RunTestAsync(const std::string& test_function_name); + // Can be overridden to inspect requests to the embedded test server. + virtual void ProcessServerRequest( + const net::test_server::HttpRequest& request); + // Configures command line switches to simulate a user accepting the install // prompt. void AutoAcceptInstall();
diff --git a/chrome/browser/extensions/webstore_standalone_installer.cc b/chrome/browser/extensions/webstore_standalone_installer.cc index 84f1905..425fb1f 100644 --- a/chrome/browser/extensions/webstore_standalone_installer.cc +++ b/chrome/browser/extensions/webstore_standalone_installer.cc
@@ -69,6 +69,11 @@ profile_->GetRequestContext(), GetRequestorURL(), id_)); + + std::string json_post_data = GetJsonPostData(); + if (!json_post_data.empty()) + webstore_data_fetcher_->SetJsonPostData(json_post_data); + webstore_data_fetcher_->Start(); } @@ -159,6 +164,10 @@ // Default implementation sets no properties. } +std::string WebstoreStandaloneInstaller::GetJsonPostData() { + return std::string(); +} + void WebstoreStandaloneInstaller::OnManifestParsed() { ProceedWithInstallPrompt(); }
diff --git a/chrome/browser/extensions/webstore_standalone_installer.h b/chrome/browser/extensions/webstore_standalone_installer.h index 73110be..400d947 100644 --- a/chrome/browser/extensions/webstore_standalone_installer.h +++ b/chrome/browser/extensions/webstore_standalone_installer.h
@@ -91,6 +91,11 @@ // Allows subclasses to set properties of the install data. virtual void InitInstallData(ActiveInstallData* install_data) const; + // Gives subclasses an opportunity to provide extra post data in the form of + // serialized JSON to the webstore data request before sending. The default + // implementation returns an empty string. + virtual std::string GetJsonPostData(); + // Called at certain check points of the workflow to decide whether it makes // sense to proceed with installation. A requestor can be a website that // initiated an inline installation, or a command line option.
diff --git a/chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.cc b/chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.cc index 4122c379..ffa82726 100644 --- a/chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.cc +++ b/chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.cc
@@ -108,6 +108,11 @@ // static std::unique_ptr<ntp_tiles::MostVisitedSites> ChromeMostVisitedSitesFactory::NewForProfile(Profile* profile) { + // MostVisitedSites doesn't exist in incognito profiles. + if (profile->IsOffTheRecord()) { + return nullptr; + } + return base::MakeUnique<ntp_tiles::MostVisitedSites>( profile->GetPrefs(), TopSitesFactory::GetForProfile(profile), SuggestionsServiceFactory::GetForProfile(profile),
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc index 05f545d..9d46ce9 100644 --- a/chrome/browser/password_manager/password_manager_browsertest.cc +++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -1493,6 +1493,49 @@ base::ASCIIToUTF16("password")); } +// Tests that after HTTP -> HTTPS migration the credential is autofilled. +IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, + HttpMigratedCredentialAutofilled) { + net::EmbeddedTestServer https_test_server( + net::EmbeddedTestServer::TYPE_HTTPS); + https_test_server.ServeFilesFromSourceDirectory( + base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); + ASSERT_TRUE(https_test_server.Start()); + + // Add an http credential to the password store. + GURL https_origin = https_test_server.base_url(); + ASSERT_TRUE(https_origin.SchemeIs(url::kHttpsScheme)); + GURL::Replacements rep; + rep.SetSchemeStr(url::kHttpScheme); + GURL http_origin = https_origin.ReplaceComponents(rep); + autofill::PasswordForm http_form; + http_form.signon_realm = http_origin.spec(); + http_form.origin = http_origin; + // Assume that the previous action was already HTTPS one matching the current + // page. + http_form.action = https_origin; + http_form.username_value = base::ASCIIToUTF16("user"); + http_form.password_value = base::ASCIIToUTF16("12345"); + scoped_refptr<password_manager::TestPasswordStore> password_store = + static_cast<password_manager::TestPasswordStore*>( + PasswordStoreFactory::GetForProfile( + browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS).get()); + password_store->AddLogin(http_form); + + NavigationObserver form_observer(WebContents()); + ui_test_utils::NavigateToURL( + browser(), https_test_server.GetURL("/password/password_form.html")); + form_observer.Wait(); + WaitForPasswordStore(); + + // Let the user interact with the page, so that DOM gets modification events, + // needed for autofilling fields. + content::SimulateMouseClickAt( + WebContents(), 0, blink::WebMouseEvent::Button::Left, gfx::Point(1, 1)); + WaitForElementValue("username_field", "user"); + CheckElementValue("password_field", "12345"); +} + IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, PromptWhenPasswordFormWithoutUsernameFieldSubmitted) { scoped_refptr<password_manager::TestPasswordStore> password_store =
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_user_image.js b/chrome/browser/resources/chromeos/login/oobe_screen_user_image.js index 0628c6a7..c6589fb7c 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_user_image.js +++ b/chrome/browser/resources/chromeos/login/oobe_screen_user_image.js
@@ -10,6 +10,7 @@ var CONTEXT_KEY_IS_CAMERA_PRESENT = 'isCameraPresent'; var CONTEXT_KEY_SELECTED_IMAGE_URL = 'selectedImageURL'; var CONTEXT_KEY_PROFILE_PICTURE_DATA_URL = 'profilePictureDataURL'; + var CONTEXT_KEY_HAS_GAIA_ACCOUNT = 'hasGaiaAccount'; var UserImagesGrid = options.UserImagesGrid; var ButtonImages = UserImagesGrid.ButtonImages; @@ -47,26 +48,6 @@ loadTimeData.getString('takePhoto'), loadTimeData.getString('photoFromCamera')); - this.profileImageLoading = true; - - // Profile image data (if present). - this.profileImage_ = imageGrid.addItem( - ButtonImages.PROFILE_PICTURE, // Image URL. - loadTimeData.getString('profilePhoto'), // Title. - undefined, // Click handler. - 0, // Position. - function(el) { - // Custom decorator for Profile image element. - var spinner = el.ownerDocument.createElement('div'); - spinner.className = 'spinner'; - var spinnerBg = el.ownerDocument.createElement('div'); - spinnerBg.className = 'spinner-bg'; - spinnerBg.appendChild(spinner); - el.appendChild(spinnerBg); - el.id = 'profile-image'; - }); - this.profileImage_.type = 'profile'; - $('take-photo').addEventListener( 'click', this.handleTakePhoto_.bind(this)); $('discard-photo').addEventListener( @@ -91,6 +72,31 @@ }); this.context.addObserver(CONTEXT_KEY_SELECTED_IMAGE_URL, this.setSelectedImage_); + this.context.addObserver(CONTEXT_KEY_HAS_GAIA_ACCOUNT, + function(hasGaiaAccount) { + if (!hasGaiaAccount) { + imageGrid.removeItem(self.profileImage_); + } else { + self.profileImageLoading = true; + // Profile image data (if present). + self.profileImage_ = imageGrid.addItem( + ButtonImages.PROFILE_PICTURE, // Image URL. + loadTimeData.getString('profilePhoto'), // Title. + undefined, // Click handler. + 0, // Position. + function(el) { + // Custom decorator for Profile image element. + var spinner = el.ownerDocument.createElement('div'); + spinner.className = 'spinner'; + var spinnerBg = el.ownerDocument.createElement('div'); + spinnerBg.className = 'spinner-bg'; + spinnerBg.appendChild(spinner); + el.appendChild(spinnerBg); + el.id = 'profile-image'; + }); + self.profileImage_.type = 'profile'; + } + }); this.context.addObserver(CONTEXT_KEY_PROFILE_PICTURE_DATA_URL, function(url) { self.profileImageLoading = false;
diff --git a/chrome/browser/resources/vr_shell/OWNERS b/chrome/browser/resources/vr_shell/OWNERS index 4adfe100..4df2af8 100644 --- a/chrome/browser/resources/vr_shell/OWNERS +++ b/chrome/browser/resources/vr_shell/OWNERS
@@ -1,3 +1,4 @@ bshe@chromium.org girard@chromium.org mthiesse@chromium.org +cjgrant@chromium.org
diff --git a/chrome/browser/search/instant_service.cc b/chrome/browser/search/instant_service.cc index 4a1c3b1..e313d56 100644 --- a/chrome/browser/search/instant_service.cc +++ b/chrome/browser/search/instant_service.cc
@@ -103,7 +103,8 @@ if (base::FeatureList::IsEnabled(kNtpTilesFeature)) { most_visited_sites_ = ChromeMostVisitedSitesFactory::NewForProfile(profile_); - most_visited_sites_->SetMostVisitedURLsObserver(this, 8); + if (most_visited_sites_) + most_visited_sites_->SetMostVisitedURLsObserver(this, 8); } else { top_sites_ = TopSitesFactory::GetForProfile(profile_); if (top_sites_) {
diff --git a/chrome/browser/supervised_user/experimental/supervised_user_filtering_switches.cc b/chrome/browser/supervised_user/experimental/supervised_user_filtering_switches.cc index 5014f821..1868fa3 100644 --- a/chrome/browser/supervised_user/experimental/supervised_user_filtering_switches.cc +++ b/chrome/browser/supervised_user/experimental/supervised_user_filtering_switches.cc
@@ -35,24 +35,6 @@ if (!profile->GetPrefs()->GetBoolean(prefs::kSupervisedUserSafeSites)) return SafeSitesState::DISABLED; - std::string arg = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - switches::kSupervisedUserSafeSites); - if (!arg.empty()) { - if (arg == "enabled") - return SafeSitesState::ENABLED; - if (arg == "disabled") - return SafeSitesState::DISABLED; - if (arg == "blacklist-only") - return SafeSitesState::BLACKLIST_ONLY; - if (arg == "online-check-only") - return SafeSitesState::ONLINE_CHECK_ONLY; - - LOG(WARNING) << "Invalid value \"" << arg << "\" specified for flag \"" - << switches::kSupervisedUserSafeSites - << "\", defaulting to \"disabled\""; - return SafeSitesState::DISABLED; - } - // If no cmdline arg is specified, evaluate the field trial. if (trial_group == "Disabled") return SafeSitesState::DISABLED;
diff --git a/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.cc b/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.cc index ab19dac..35f36bf7 100644 --- a/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.cc +++ b/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.cc
@@ -14,8 +14,8 @@ #include "chrome/common/render_messages.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "content/public/browser/navigation_controller.h" -#include "content/public/browser/navigation_details.h" #include "content/public/browser/navigation_entry.h" +#include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "third_party/WebKit/public/web/WebWindowFeatures.h" @@ -47,13 +47,16 @@ PopupBlockerTabHelper::~PopupBlockerTabHelper() { } -void PopupBlockerTabHelper::DidNavigateMainFrame( - const content::LoadCommittedDetails& details, - const content::FrameNavigateParams& params) { +void PopupBlockerTabHelper::DidFinishNavigation( + content::NavigationHandle* navigation_handle) { // Clear all page actions, blocked content notifications and browser actions - // for this tab, unless this is an in-page navigation. - if (details.is_in_page) + // for this tab, unless this is an in-page navigation. Also only consider + // main frame navigations that successfully committed. + if (!navigation_handle->IsInMainFrame() || + !navigation_handle->HasCommitted() || + navigation_handle->IsSamePage()) { return; + } // Close blocked popups. if (!blocked_popups_.IsEmpty()) {
diff --git a/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h b/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h index 0b700b71..0e0fabc 100644 --- a/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h +++ b/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h
@@ -53,9 +53,8 @@ PopupIdMap GetBlockedPopupRequests(); // content::WebContentsObserver overrides: - void DidNavigateMainFrame( - const content::LoadCommittedDetails& details, - const content::FrameNavigateParams& params) override; + void DidFinishNavigation( + content::NavigationHandle* navigation_handle) override; private: struct BlockedRequest;
diff --git a/chrome/browser/ui/webui/options/manage_profile_handler.h b/chrome/browser/ui/webui/options/manage_profile_handler.h index 9208771..0e0cc31 100644 --- a/chrome/browser/ui/webui/options/manage_profile_handler.h +++ b/chrome/browser/ui/webui/options/manage_profile_handler.h
@@ -15,7 +15,8 @@ #include "components/sync/driver/sync_service_observer.h" namespace base { -class StringValue; +class Value; +using StringValue = Value; } namespace options {
diff --git a/chrome/browser/ui/webui/vr_shell/OWNERS b/chrome/browser/ui/webui/vr_shell/OWNERS index 4adfe100..4df2af8 100644 --- a/chrome/browser/ui/webui/vr_shell/OWNERS +++ b/chrome/browser/ui/webui/vr_shell/OWNERS
@@ -1,3 +1,4 @@ bshe@chromium.org girard@chromium.org mthiesse@chromium.org +cjgrant@chromium.org
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index bb414a62..ca32982 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc
@@ -792,10 +792,6 @@ // Used for testing. const char kSupervisedUserId[] = "managed-user-id"; -// Enables/disables SafeSites filtering for supervised users. Possible values -// are "enabled", "disabled", "blacklist-only", and "online-check-only". -const char kSupervisedUserSafeSites[] = "supervised-user-safesites"; - // Used to authenticate requests to the Sync service for supervised users. // Setting this switch also causes Sync to be set up for a supervised user. const char kSupervisedUserSyncToken[] = "managed-user-sync-token";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 9bb2cbf..9d3daa3 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h
@@ -224,7 +224,6 @@ extern const char kStartMaximized[]; extern const char kStartStackProfiler[]; extern const char kSupervisedUserId[]; -extern const char kSupervisedUserSafeSites[]; extern const char kSupervisedUserSyncToken[]; extern const char kSystemLogUploadFrequency[]; extern const char kTestName[];
diff --git a/chromeos/network/network_state_unittest.cc b/chromeos/network/network_state_unittest.cc index 6cd28ae..5fdb1d6 100644 --- a/chromeos/network/network_state_unittest.cc +++ b/chromeos/network/network_state_unittest.cc
@@ -27,7 +27,11 @@ explicit TestStringValue(const std::string& in_value) : base::Value(Type::STRING), value_(in_value) {} - ~TestStringValue() override {} + ~TestStringValue() override { + // Ugly hack that prevents ~Value() from trying to destroy string_value_. + // TODO(crbug.com/646113): Clean this up when StringValue will be removed. + type_ = Type::NONE; + } // Overridden from Value: bool GetAsString(std::string* out_value) const override {
diff --git a/components/ntp_snippets/features.cc b/components/ntp_snippets/features.cc index b680661..8c40e5a7 100644 --- a/components/ntp_snippets/features.cc +++ b/components/ntp_snippets/features.cc
@@ -36,15 +36,9 @@ const base::Feature kContentSuggestionsSource{ "NTPSnippets", base::FEATURE_ENABLED_BY_DEFAULT}; -const base::Feature kSectionDismissalFeature{ - "NTPSuggestionsSectionDismissal", base::FEATURE_ENABLED_BY_DEFAULT}; - const base::Feature kForeignSessionsSuggestionsFeature{ "NTPForeignSessionsSuggestions", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kFetchMoreFeature{"NTPSuggestionsFetchMore", - base::FEATURE_ENABLED_BY_DEFAULT}; - const base::Feature kPreferAmpUrlsFeature{"NTPPreferAmpUrls", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/components/ntp_snippets/features.h b/components/ntp_snippets/features.h index bf9b944..cc8be99 100644 --- a/components/ntp_snippets/features.h +++ b/components/ntp_snippets/features.h
@@ -32,9 +32,6 @@ // Feature to allow offline badges to appear on snippets. extern const base::Feature kOfflineBadgeFeature; -// Feature to allow dismissing sections. -extern const base::Feature kSectionDismissalFeature; - // Feature to allow specification of content suggestions source. // TODO(peconn): Figure out how to remove this, it is useful to specify the // source, but you shouldn't be able to disable it. @@ -43,9 +40,6 @@ // Feature to allow UI as specified here: https://crbug.com/660837. extern const base::Feature kIncreasedVisibility; -// Feature to enable the Fetch More action -extern const base::Feature kFetchMoreFeature; - // Feature to prefer AMP URLs over regular URLs when available. extern const base::Feature kPreferAmpUrlsFeature;
diff --git a/components/ntp_snippets/remote/json_request.cc b/components/ntp_snippets/remote/json_request.cc index 9c24b7f8..8e522936 100644 --- a/components/ntp_snippets/remote/json_request.cc +++ b/components/ntp_snippets/remote/json_request.cc
@@ -141,7 +141,7 @@ ContentSuggestionsCardLayout::FULL_CARD, // TODO(dgn): merge has_more_action and has_reload_action when we remove // the kFetchMoreFeature flag. See https://crbug.com/667752 - /*has_more_action=*/base::FeatureList::IsEnabled(kFetchMoreFeature), + /*has_more_action=*/true, /*has_reload_action=*/true, /*has_view_all_action=*/false, /*show_if_empty=*/true, @@ -154,8 +154,7 @@ title, ContentSuggestionsCardLayout::FULL_CARD, // TODO(dgn): merge has_more_action and has_reload_action when we remove // the kFetchMoreFeature flag. See https://crbug.com/667752 - /*has_more_action=*/allow_fetching_more_results && - base::FeatureList::IsEnabled(kFetchMoreFeature), + /*has_more_action=*/allow_fetching_more_results, /*has_reload_action=*/allow_fetching_more_results, /*has_view_all_action=*/false, /*show_if_empty=*/false,
diff --git a/components/ntp_snippets/remote/remote_suggestions_fetcher.cc b/components/ntp_snippets/remote/remote_suggestions_fetcher.cc index b4afcee5..56eaa12 100644 --- a/components/ntp_snippets/remote/remote_suggestions_fetcher.cc +++ b/components/ntp_snippets/remote/remote_suggestions_fetcher.cc
@@ -213,7 +213,7 @@ ContentSuggestionsCardLayout::FULL_CARD, // TODO(dgn): merge has_more_action and has_reload_action when we remove // the kFetchMoreFeature flag. See https://crbug.com/667752 - /*has_more_action=*/base::FeatureList::IsEnabled(kFetchMoreFeature), + /*has_more_action=*/true, /*has_reload_action=*/true, /*has_view_all_action=*/false, /*show_if_empty=*/true, @@ -226,8 +226,7 @@ title, ContentSuggestionsCardLayout::FULL_CARD, // TODO(dgn): merge has_more_action and has_reload_action when we remove // the kFetchMoreFeature flag. See https://crbug.com/667752 - /*has_more_action=*/allow_fetching_more_results && - base::FeatureList::IsEnabled(kFetchMoreFeature), + /*has_more_action=*/allow_fetching_more_results, /*has_reload_action=*/allow_fetching_more_results, /*has_view_all_action=*/false, /*show_if_empty=*/false,
diff --git a/components/password_manager/core/browser/form_fetcher_impl_unittest.cc b/components/password_manager/core/browser/form_fetcher_impl_unittest.cc index 9e3e072..4dd2d59 100644 --- a/components/password_manager/core/browser/form_fetcher_impl_unittest.cc +++ b/components/password_manager/core/browser/form_fetcher_impl_unittest.cc
@@ -490,10 +490,6 @@ form_fetcher_->OnGetPasswordStoreResults(MakeResults(empty_forms)); ASSERT_TRUE(migrator_ptr); - // Setting action equal to origin is necessary in order to mirror the behavior - // in HttpPasswordMigrator. - https_form.action = https_form.origin; - // Now perform the actual migration. EXPECT_CALL(*mock_store_, AddLogin(https_form)); EXPECT_CALL(*static_cast<MockFormFetcherImpl*>(form_fetcher_.get()),
diff --git a/components/password_manager/core/browser/http_password_migrator.cc b/components/password_manager/core/browser/http_password_migrator.cc index 8f5552a..da6eb67c 100644 --- a/components/password_manager/core/browser/http_password_migrator.cc +++ b/components/password_manager/core/browser/http_password_migrator.cc
@@ -47,7 +47,10 @@ rep.SetSchemeStr(url::kHttpsScheme); form->origin = form->origin.ReplaceComponents(rep); form->signon_realm = form->origin.spec(); - form->action = form->origin; + // If |action| is not HTTPS then it's most likely obsolete. Otherwise, it + // may still be valid. + if (!form->action.SchemeIs(url::kHttpsScheme)) + form->action = form->origin; form->form_data = autofill::FormData(); form->generation_upload_status = autofill::PasswordForm::NO_SIGNAL_SENT; form->skip_zero_click = false;
diff --git a/components/password_manager/core/browser/http_password_migrator_unittest.cc b/components/password_manager/core/browser/http_password_migrator_unittest.cc index ab7bb55..e536f10 100644 --- a/components/password_manager/core/browser/http_password_migrator_unittest.cc +++ b/components/password_manager/core/browser/http_password_migrator_unittest.cc
@@ -28,7 +28,7 @@ PasswordForm form; form.origin = GURL(kTestHttpURL); form.signon_realm = form.origin.spec(); - form.action = GURL(kTestHttpURL); + form.action = GURL("https://example.org/action.html"); form.username_value = base::ASCIIToUTF16("user"); form.password_value = base::ASCIIToUTF16("password"); return form; @@ -116,7 +116,6 @@ PasswordForm expected_form = form; expected_form.origin = GURL(kTestHttpsURL); expected_form.signon_realm = expected_form.origin.spec(); - expected_form.action = expected_form.origin; EXPECT_CALL(store(), AddLogin(expected_form)); EXPECT_CALL(consumer(), ProcessForms(ElementsAre(Pointee(expected_form))));
diff --git a/components/subresource_filter/content/browser/BUILD.gn b/components/subresource_filter/content/browser/BUILD.gn index 5fe23a1..e49864e 100644 --- a/components/subresource_filter/content/browser/BUILD.gn +++ b/components/subresource_filter/content/browser/BUILD.gn
@@ -10,6 +10,8 @@ "content_subresource_filter_driver.h", "content_subresource_filter_driver_factory.cc", "content_subresource_filter_driver_factory.h", + "verified_ruleset_dealer.cc", + "verified_ruleset_dealer.h", ] deps = [ "//base", @@ -29,6 +31,7 @@ sources = [ "content_ruleset_service_delegate_unittest.cc", "content_subresource_filter_driver_factory_unittest.cc", + "verified_ruleset_dealer_unittest.cc", ] deps = [ ":browser", @@ -37,6 +40,8 @@ "//components/subresource_filter/content/common", "//components/subresource_filter/core/browser", "//components/subresource_filter/core/browser:test_support", + "//components/subresource_filter/core/common", + "//components/subresource_filter/core/common:test_support", "//content/test:test_support", "//ipc", "//ipc:test_support",
diff --git a/components/subresource_filter/content/browser/verified_ruleset_dealer.cc b/components/subresource_filter/content/browser/verified_ruleset_dealer.cc new file mode 100644 index 0000000..cb6b79d --- /dev/null +++ b/components/subresource_filter/content/browser/verified_ruleset_dealer.cc
@@ -0,0 +1,81 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/subresource_filter/content/browser/verified_ruleset_dealer.h" + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/files/file.h" +#include "base/location.h" +#include "base/logging.h" +#include "components/subresource_filter/core/common/indexed_ruleset.h" +#include "components/subresource_filter/core/common/memory_mapped_ruleset.h" + +namespace subresource_filter { + +VerifiedRulesetDealer::VerifiedRulesetDealer() = default; +VerifiedRulesetDealer::~VerifiedRulesetDealer() = default; + +void VerifiedRulesetDealer::SetRulesetFile(base::File ruleset_file) { + RulesetDealer::SetRulesetFile(std::move(ruleset_file)); + status_ = RulesetVerificationStatus::NOT_VERIFIED; +} + +scoped_refptr<const MemoryMappedRuleset> VerifiedRulesetDealer::GetRuleset() { + DCHECK(CalledOnValidThread()); + + // TODO(pkalinnikov): Record verification status to a histogram. + switch (status_) { + case RulesetVerificationStatus::NOT_VERIFIED: { + auto ruleset = RulesetDealer::GetRuleset(); + if (ruleset && + IndexedRulesetMatcher::Verify(ruleset->data(), ruleset->length())) { + status_ = RulesetVerificationStatus::INTACT; + return ruleset; + } + status_ = RulesetVerificationStatus::CORRUPT; + return nullptr; + } + case RulesetVerificationStatus::INTACT: { + auto ruleset = RulesetDealer::GetRuleset(); + DCHECK(ruleset); + return ruleset; + } + case RulesetVerificationStatus::CORRUPT: + return nullptr; + default: + NOTREACHED(); + return nullptr; + } +} + +VerifiedRulesetDealer::Handle::Handle( + scoped_refptr<base::SequencedTaskRunner> task_runner) + : task_runner_(task_runner.get()), + dealer_(new VerifiedRulesetDealer, + base::OnTaskRunnerDeleter(std::move(task_runner))) {} + +VerifiedRulesetDealer::Handle::~Handle() = default; + +void VerifiedRulesetDealer::Handle::GetDealerAsync( + base::Callback<void(VerifiedRulesetDealer*)> callback) { + DCHECK(thread_checker_.CalledOnValidThread()); + + // NOTE: Properties of the sequenced |task_runner| guarantee that the + // |callback| will always be provided with a valid pointer, because the + // corresponding task will be posted *before* a task to delete the pointer + // upon destruction of |this| Handler. + task_runner_->PostTask(FROM_HERE, + base::Bind(std::move(callback), dealer_.get())); +} + +void VerifiedRulesetDealer::Handle::SetRulesetFile(base::File file) { + DCHECK(thread_checker_.CalledOnValidThread()); + task_runner_->PostTask( + FROM_HERE, + base::Bind(&VerifiedRulesetDealer::SetRulesetFile, + base::Unretained(dealer_.get()), base::Passed(&file))); +} + +} // namespace subresource_filter
diff --git a/components/subresource_filter/content/browser/verified_ruleset_dealer.h b/components/subresource_filter/content/browser/verified_ruleset_dealer.h new file mode 100644 index 0000000..187b7ed --- /dev/null +++ b/components/subresource_filter/content/browser/verified_ruleset_dealer.h
@@ -0,0 +1,92 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_VERIFIED_RULESET_DEALER_H_ +#define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_VERIFIED_RULESET_DEALER_H_ + +#include <memory> + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/sequenced_task_runner.h" +#include "base/threading/thread_checker.h" +#include "components/subresource_filter/content/common/ruleset_dealer.h" + +namespace base { +class File; +} // namespace base + +namespace subresource_filter { + +class MemoryMappedRuleset; + +// The integrity verification status of a given ruleset version. +// +// A ruleset file starts from the NOT_VERIFIED state, after which it can be +// classified as INTACT or CORRUPT upon integrity verification. +enum class RulesetVerificationStatus { + NOT_VERIFIED, + INTACT, + CORRUPT, +}; + +// This class is the same as RulesetDealer, but additionally does a one-time +// integrity checking on the ruleset before handing it out from GetRuleset(). +// +// The |status| of verification is persisted throughout the entire lifetime of +// |this| object, and is reset to NOT_VERIFIED only when a new ruleset is +// supplied to SetRulesetFile() method. +class VerifiedRulesetDealer : public RulesetDealer { + public: + class Handle; + + VerifiedRulesetDealer(); + ~VerifiedRulesetDealer() override; + + // RulesetDealer: + void SetRulesetFile(base::File ruleset_file) override; + scoped_refptr<const MemoryMappedRuleset> GetRuleset() override; + + // For tests only. + RulesetVerificationStatus status() const { return status_; } + + private: + RulesetVerificationStatus status_ = RulesetVerificationStatus::NOT_VERIFIED; + + DISALLOW_COPY_AND_ASSIGN(VerifiedRulesetDealer); +}; + +// The UI-thread handle that owns a VerifiedRulesetDealer living on a dedicated +// sequenced |task_runner|. Provides asynchronous access to the instance, and +// destroys it asynchronously. +class VerifiedRulesetDealer::Handle { + public: + // Creates a VerifiedRulesetDealer that is owned by this handle, accessed + // through this handle, but lives on |task_runner|. + explicit Handle(scoped_refptr<base::SequencedTaskRunner> task_runner); + ~Handle(); + + // Invokes |callback| on |task_runner|, providing a pointer to the underlying + // VerifiedRulesetDealer as an argument. The pointer is guaranteed to be valid + // at least until the callback returns. + void GetDealerAsync(base::Callback<void(VerifiedRulesetDealer*)> callback); + + // Sets the ruleset |file| that the VerifiedRulesetDealer should distribute + // from now on. + void SetRulesetFile(base::File file); + + private: + // Note: Raw pointer, |dealer_| already holds a reference to |task_runner_|. + base::SequencedTaskRunner* task_runner_; + std::unique_ptr<VerifiedRulesetDealer, base::OnTaskRunnerDeleter> dealer_; + + base::ThreadChecker thread_checker_; + + DISALLOW_COPY_AND_ASSIGN(Handle); +}; + +} // namespace subresource_filter + +#endif // COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_VERIFIED_RULESET_DEALER_H_
diff --git a/components/subresource_filter/content/browser/verified_ruleset_dealer_unittest.cc b/components/subresource_filter/content/browser/verified_ruleset_dealer_unittest.cc new file mode 100644 index 0000000..4182e1c8 --- /dev/null +++ b/components/subresource_filter/content/browser/verified_ruleset_dealer_unittest.cc
@@ -0,0 +1,339 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/subresource_filter/content/browser/verified_ruleset_dealer.h" + +#include <memory> +#include <vector> + +#include "base/bind.h" +#include "base/files/file.h" +#include "base/test/test_simple_task_runner.h" +#include "components/subresource_filter/core/common/memory_mapped_ruleset.h" +#include "components/subresource_filter/core/common/test_ruleset_creator.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace subresource_filter { + +namespace { + +// TODO(pkalinnikov): Consider putting this to a test_support for this test file +// and SubresourceFilterRulesetDealerTest. +class TestRulesets { + public: + TestRulesets() = default; + + void CreateRulesets(bool many_rules = false) { + if (many_rules) { + ASSERT_NO_FATAL_FAILURE( + test_ruleset_creator_.CreateRulesetToDisallowURLsWithManySuffixes( + kTestRulesetSuffix1, kNumberOfRulesInBigRuleset, + &test_ruleset_pair_1_)); + ASSERT_NO_FATAL_FAILURE( + test_ruleset_creator_.CreateRulesetToDisallowURLsWithManySuffixes( + kTestRulesetSuffix2, kNumberOfRulesInBigRuleset, + &test_ruleset_pair_2_)); + } else { + ASSERT_NO_FATAL_FAILURE( + test_ruleset_creator_.CreateRulesetToDisallowURLsWithPathSuffix( + kTestRulesetSuffix1, &test_ruleset_pair_1_)); + ASSERT_NO_FATAL_FAILURE( + test_ruleset_creator_.CreateRulesetToDisallowURLsWithPathSuffix( + kTestRulesetSuffix2, &test_ruleset_pair_2_)); + } + } + + const testing::TestRuleset& indexed_1() const { + return test_ruleset_pair_1_.indexed; + } + + const testing::TestRuleset& indexed_2() const { + return test_ruleset_pair_2_.indexed; + } + + private: + static constexpr const char kTestRulesetSuffix1[] = "foo"; + static constexpr const char kTestRulesetSuffix2[] = "bar"; + static constexpr int kNumberOfRulesInBigRuleset = 500; + + testing::TestRulesetCreator test_ruleset_creator_; + testing::TestRulesetPair test_ruleset_pair_1_; + testing::TestRulesetPair test_ruleset_pair_2_; + + DISALLOW_COPY_AND_ASSIGN(TestRulesets); +}; + +constexpr const char TestRulesets::kTestRulesetSuffix1[]; +constexpr const char TestRulesets::kTestRulesetSuffix2[]; +constexpr int TestRulesets::kNumberOfRulesInBigRuleset; + +std::vector<uint8_t> ReadRulesetContents(const MemoryMappedRuleset* ruleset) { + return std::vector<uint8_t>(ruleset->data(), + ruleset->data() + ruleset->length()); +} + +} // namespace + +// Tests for VerifiedRulesetDealer. -------------------------------------------- +// +// Note that VerifiedRulesetDealer uses RulesetDealer very directly to provide +// MemoryMappedRulesets. Many aspects of its work, e.g., lifetime of a +// MemoryMappedRuleset, its lazy creation, etc., are covered with tests to +// RulesetDealer, therefore these aspects are not tested here. + +class SubresourceFilterVerifiedRulesetDealerTest : public ::testing::Test { + public: + SubresourceFilterVerifiedRulesetDealerTest() = default; + + protected: + void SetUp() override { + rulesets_.CreateRulesets(true /* many_rules */); + ruleset_dealer_.reset(new VerifiedRulesetDealer); + } + + const TestRulesets& rulesets() const { return rulesets_; } + VerifiedRulesetDealer* ruleset_dealer() { return ruleset_dealer_.get(); } + + bool has_cached_ruleset() const { + return ruleset_dealer_->has_cached_ruleset(); + } + + private: + TestRulesets rulesets_; + std::unique_ptr<VerifiedRulesetDealer> ruleset_dealer_; + + DISALLOW_COPY_AND_ASSIGN(SubresourceFilterVerifiedRulesetDealerTest); +}; + +TEST_F(SubresourceFilterVerifiedRulesetDealerTest, + RulesetIsMemoryMappedAndVerifiedLazily) { + ruleset_dealer()->SetRulesetFile( + testing::TestRuleset::Open(rulesets().indexed_1())); + + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); + EXPECT_FALSE(has_cached_ruleset()); + EXPECT_EQ(RulesetVerificationStatus::NOT_VERIFIED, + ruleset_dealer()->status()); + + scoped_refptr<const MemoryMappedRuleset> ref_to_ruleset = + ruleset_dealer()->GetRuleset(); + + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); + EXPECT_TRUE(ref_to_ruleset); + EXPECT_TRUE(has_cached_ruleset()); + EXPECT_EQ(RulesetVerificationStatus::INTACT, ruleset_dealer()->status()); +} + +TEST_F(SubresourceFilterVerifiedRulesetDealerTest, + CorruptedRulesetIsNeitherProvidedNorCached) { + testing::TestRuleset::CorruptByTruncating(rulesets().indexed_1(), 123); + + ruleset_dealer()->SetRulesetFile( + testing::TestRuleset::Open(rulesets().indexed_1())); + + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); + EXPECT_FALSE(has_cached_ruleset()); + EXPECT_EQ(RulesetVerificationStatus::NOT_VERIFIED, + ruleset_dealer()->status()); + + scoped_refptr<const MemoryMappedRuleset> ref_to_ruleset = + ruleset_dealer()->GetRuleset(); + + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); + EXPECT_FALSE(ref_to_ruleset); + EXPECT_FALSE(has_cached_ruleset()); + EXPECT_EQ(RulesetVerificationStatus::CORRUPT, ruleset_dealer()->status()); +} + +TEST_F(SubresourceFilterVerifiedRulesetDealerTest, + TruncatingFileMakesRulesetInvalid) { + testing::TestRuleset::CorruptByTruncating(rulesets().indexed_1(), 4096); + ruleset_dealer()->SetRulesetFile( + testing::TestRuleset::Open(rulesets().indexed_1())); + scoped_refptr<const MemoryMappedRuleset> ref_to_ruleset = + ruleset_dealer()->GetRuleset(); + + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); + EXPECT_FALSE(ref_to_ruleset); + EXPECT_FALSE(has_cached_ruleset()); + EXPECT_EQ(RulesetVerificationStatus::CORRUPT, ruleset_dealer()->status()); +} + +TEST_F(SubresourceFilterVerifiedRulesetDealerTest, + FillingRangeMakesRulesetInvalid) { + testing::TestRuleset::CorruptByFilling(rulesets().indexed_1(), + 2501 /* from */, 4000 /* to */, + 255 /* fill_with */); + ruleset_dealer()->SetRulesetFile( + testing::TestRuleset::Open(rulesets().indexed_1())); + scoped_refptr<const MemoryMappedRuleset> ref_to_ruleset = + ruleset_dealer()->GetRuleset(); + + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); + EXPECT_FALSE(ref_to_ruleset); + EXPECT_FALSE(has_cached_ruleset()); + EXPECT_EQ(RulesetVerificationStatus::CORRUPT, ruleset_dealer()->status()); +} + +TEST_F(SubresourceFilterVerifiedRulesetDealerTest, + RulesetIsVerifiedAfterUpdate) { + testing::TestRuleset::CorruptByTruncating(rulesets().indexed_1(), 123); + + ruleset_dealer()->SetRulesetFile( + testing::TestRuleset::Open(rulesets().indexed_1())); + + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); + EXPECT_FALSE(has_cached_ruleset()); + EXPECT_EQ(RulesetVerificationStatus::NOT_VERIFIED, + ruleset_dealer()->status()); + + scoped_refptr<const MemoryMappedRuleset> ref_to_ruleset = + ruleset_dealer()->GetRuleset(); + + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); + EXPECT_FALSE(ref_to_ruleset); + EXPECT_FALSE(has_cached_ruleset()); + EXPECT_EQ(RulesetVerificationStatus::CORRUPT, ruleset_dealer()->status()); + + ruleset_dealer()->SetRulesetFile( + testing::TestRuleset::Open(rulesets().indexed_2())); + EXPECT_EQ(RulesetVerificationStatus::NOT_VERIFIED, + ruleset_dealer()->status()); + ref_to_ruleset = ruleset_dealer()->GetRuleset(); + + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); + EXPECT_TRUE(ref_to_ruleset); + EXPECT_TRUE(has_cached_ruleset()); + EXPECT_EQ(RulesetVerificationStatus::INTACT, ruleset_dealer()->status()); +} + +// Tests for VerifiedRulesetDealer::Handle. ------------------------------------ + +namespace { + +class TestVerifiedRulesetDealerClient { + public: + TestVerifiedRulesetDealerClient() = default; + + base::Callback<void(VerifiedRulesetDealer*)> GetCallback() { + return base::Bind(&TestVerifiedRulesetDealerClient::Callback, + base::Unretained(this)); + } + + void ExpectRulesetState(bool expected_availability, + RulesetVerificationStatus expected_status = + RulesetVerificationStatus::NOT_VERIFIED) const { + ASSERT_EQ(1, invocation_counter_); + EXPECT_EQ(expected_availability, is_ruleset_file_available_); + EXPECT_FALSE(has_cached_ruleset_); + EXPECT_EQ(expected_status, status_); + } + + void ExpectRulesetContents( + const std::vector<uint8_t> expected_contents) const { + ExpectRulesetState(true, RulesetVerificationStatus::INTACT); + EXPECT_TRUE(ruleset_is_created_); + EXPECT_EQ(expected_contents, contents_); + } + + private: + void Callback(VerifiedRulesetDealer* dealer) { + ++invocation_counter_; + ASSERT_TRUE(dealer); + + is_ruleset_file_available_ = dealer->IsRulesetFileAvailable(); + has_cached_ruleset_ = dealer->has_cached_ruleset(); + status_ = dealer->status(); + + auto ruleset = dealer->GetRuleset(); + ruleset_is_created_ = !!ruleset; + if (ruleset_is_created_) + contents_ = ReadRulesetContents(ruleset.get()); + } + + bool is_ruleset_file_available_ = false; + bool has_cached_ruleset_ = false; + RulesetVerificationStatus status_ = RulesetVerificationStatus::NOT_VERIFIED; + + bool ruleset_is_created_ = false; + std::vector<uint8_t> contents_; + + int invocation_counter_ = 0; + + DISALLOW_COPY_AND_ASSIGN(TestVerifiedRulesetDealerClient); +}; + +} // namespace + +class SubresourceFilterVerifiedRulesetDealerHandleTest + : public ::testing::Test { + public: + SubresourceFilterVerifiedRulesetDealerHandleTest() = default; + + protected: + void SetUp() override { + rulesets_.CreateRulesets(false /* many_rules */); + task_runner_ = new base::TestSimpleTaskRunner; + } + + const TestRulesets& rulesets() const { return rulesets_; } + base::TestSimpleTaskRunner* task_runner() { return task_runner_.get(); } + + private: + TestRulesets rulesets_; + scoped_refptr<base::TestSimpleTaskRunner> task_runner_; + + DISALLOW_COPY_AND_ASSIGN(SubresourceFilterVerifiedRulesetDealerHandleTest); +}; + +TEST_F(SubresourceFilterVerifiedRulesetDealerHandleTest, + RulesetIsMappedLazily) { + TestVerifiedRulesetDealerClient before_set_ruleset; + TestVerifiedRulesetDealerClient after_set_ruleset; + TestVerifiedRulesetDealerClient after_warm_up; + + std::unique_ptr<VerifiedRulesetDealer::Handle> dealer_handle( + new VerifiedRulesetDealer::Handle(task_runner())); + dealer_handle->GetDealerAsync(before_set_ruleset.GetCallback()); + dealer_handle->SetRulesetFile( + testing::TestRuleset::Open(rulesets().indexed_1())); + dealer_handle->GetDealerAsync(after_set_ruleset.GetCallback()); + dealer_handle->GetDealerAsync(after_warm_up.GetCallback()); + dealer_handle.reset(nullptr); + task_runner()->RunUntilIdle(); + + before_set_ruleset.ExpectRulesetState(false); + after_set_ruleset.ExpectRulesetState(true); + after_warm_up.ExpectRulesetContents(rulesets().indexed_1().contents); +} + +TEST_F(SubresourceFilterVerifiedRulesetDealerHandleTest, RulesetFileIsUpdated) { + TestVerifiedRulesetDealerClient after_set_ruleset_1; + TestVerifiedRulesetDealerClient read_ruleset_1; + TestVerifiedRulesetDealerClient after_set_ruleset_2; + TestVerifiedRulesetDealerClient read_ruleset_2; + + std::unique_ptr<VerifiedRulesetDealer::Handle> dealer_handle( + new VerifiedRulesetDealer::Handle(task_runner())); + + dealer_handle->SetRulesetFile( + testing::TestRuleset::Open(rulesets().indexed_1())); + dealer_handle->GetDealerAsync(after_set_ruleset_1.GetCallback()); + dealer_handle->GetDealerAsync(read_ruleset_1.GetCallback()); + + dealer_handle->SetRulesetFile( + testing::TestRuleset::Open(rulesets().indexed_2())); + dealer_handle->GetDealerAsync(after_set_ruleset_2.GetCallback()); + dealer_handle->GetDealerAsync(read_ruleset_2.GetCallback()); + + dealer_handle.reset(nullptr); + task_runner()->RunUntilIdle(); + + after_set_ruleset_1.ExpectRulesetState(true); + read_ruleset_1.ExpectRulesetContents(rulesets().indexed_1().contents); + after_set_ruleset_2.ExpectRulesetState(true); + read_ruleset_2.ExpectRulesetContents(rulesets().indexed_2().contents); +} + +} // namespace subresource_filter
diff --git a/components/subresource_filter/content/common/ruleset_dealer.cc b/components/subresource_filter/content/common/ruleset_dealer.cc index e5e490b..9cdbc3f 100644 --- a/components/subresource_filter/content/common/ruleset_dealer.cc +++ b/components/subresource_filter/content/common/ruleset_dealer.cc
@@ -9,20 +9,26 @@ namespace subresource_filter { -RulesetDealer::RulesetDealer() = default; +RulesetDealer::RulesetDealer() { + DetachFromThread(); +} + RulesetDealer::~RulesetDealer() = default; void RulesetDealer::SetRulesetFile(base::File ruleset_file) { + DCHECK(CalledOnValidThread()); DCHECK(ruleset_file.IsValid()); ruleset_file_ = std::move(ruleset_file); weak_cached_ruleset_.reset(); } -bool RulesetDealer::IsRulesetAvailable() const { +bool RulesetDealer::IsRulesetFileAvailable() const { + DCHECK(CalledOnValidThread()); return ruleset_file_.IsValid(); } scoped_refptr<const MemoryMappedRuleset> RulesetDealer::GetRuleset() { + DCHECK(CalledOnValidThread()); if (!ruleset_file_.IsValid()) return nullptr;
diff --git a/components/subresource_filter/content/common/ruleset_dealer.h b/components/subresource_filter/content/common/ruleset_dealer.h index a467fcd..5934154 100644 --- a/components/subresource_filter/content/common/ruleset_dealer.h +++ b/components/subresource_filter/content/common/ruleset_dealer.h
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "base/threading/non_thread_safe.h" namespace subresource_filter { @@ -29,29 +30,29 @@ // they will use the same, cached, MemoryMappedRuleset instance, and will // not call mmap() multiple times. // -class RulesetDealer { +class RulesetDealer : protected base::NonThreadSafe { public: RulesetDealer(); virtual ~RulesetDealer(); // Sets the |ruleset_file| to memory map and distribute from now on. - void SetRulesetFile(base::File ruleset_file); + virtual void SetRulesetFile(base::File ruleset_file); - // Returns whether a subsequent call to GetRuleset() would return a non-null - // ruleset, but without memory mapping the ruleset. - bool IsRulesetAvailable() const; + // Returns whether |this| dealer has a ruleset file to read from. Does not + // interact with the file system. + bool IsRulesetFileAvailable() const; // Returns the set |ruleset_file|. Normally, the same instance is used by all // call sites in a given process. That intance is mapped lazily and umapped // eagerly as soon as the last reference to it is dropped. - scoped_refptr<const MemoryMappedRuleset> GetRuleset(); + virtual scoped_refptr<const MemoryMappedRuleset> GetRuleset(); + + // For testing only. + bool has_cached_ruleset() const { return !!weak_cached_ruleset_.get(); } private: friend class SubresourceFilterRulesetDealerTest; - // Exposed for testing only. - bool has_cached_ruleset() const { return !!weak_cached_ruleset_.get(); } - base::File ruleset_file_; base::WeakPtr<MemoryMappedRuleset> weak_cached_ruleset_;
diff --git a/components/subresource_filter/content/common/ruleset_dealer_unittest.cc b/components/subresource_filter/content/common/ruleset_dealer_unittest.cc index 2fd8ca0..fcf7acd 100644 --- a/components/subresource_filter/content/common/ruleset_dealer_unittest.cc +++ b/components/subresource_filter/content/common/ruleset_dealer_unittest.cc
@@ -15,8 +15,8 @@ namespace { -const char kTestRulesetData1[] = "foo"; -const char kTestRulesetData2[] = "bar"; +const char kTestRulesetSuffix1[] = "foo"; +const char kTestRulesetSuffix2[] = "bar"; std::vector<uint8_t> ReadRulesetContents(const MemoryMappedRuleset* ruleset) { return std::vector<uint8_t>(ruleset->data(), @@ -34,10 +34,10 @@ ResetRulesetDealer(); ASSERT_NO_FATAL_FAILURE( test_ruleset_creator_.CreateRulesetToDisallowURLsWithPathSuffix( - kTestRulesetData1, &test_ruleset_pair_1_)); + kTestRulesetSuffix1, &test_ruleset_pair_1_)); ASSERT_NO_FATAL_FAILURE( test_ruleset_creator_.CreateRulesetToDisallowURLsWithPathSuffix( - kTestRulesetData2, &test_ruleset_pair_2_)); + kTestRulesetSuffix2, &test_ruleset_pair_2_)); } testing::TestRuleset& test_indexed_ruleset_1() { @@ -66,29 +66,29 @@ }; TEST_F(SubresourceFilterRulesetDealerTest, NoRuleset) { - EXPECT_FALSE(ruleset_dealer()->IsRulesetAvailable()); + EXPECT_FALSE(ruleset_dealer()->IsRulesetFileAvailable()); EXPECT_FALSE(!!ruleset_dealer()->GetRuleset()); } TEST_F(SubresourceFilterRulesetDealerTest, MostRecentlySetRulesetIsReturned) { ruleset_dealer()->SetRulesetFile( testing::TestRuleset::Open(test_indexed_ruleset_1())); - EXPECT_TRUE(ruleset_dealer()->IsRulesetAvailable()); + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); scoped_refptr<const MemoryMappedRuleset> ref_to_ruleset_1 = ruleset_dealer()->GetRuleset(); - EXPECT_TRUE(ruleset_dealer()->IsRulesetAvailable()); + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); ASSERT_TRUE(!!ref_to_ruleset_1); EXPECT_EQ(test_indexed_ruleset_1().contents, ReadRulesetContents(ref_to_ruleset_1.get())); ruleset_dealer()->SetRulesetFile( testing::TestRuleset::Open(test_indexed_ruleset_2())); - EXPECT_TRUE(ruleset_dealer()->IsRulesetAvailable()); + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); scoped_refptr<const MemoryMappedRuleset> ref_to_ruleset_2 = ruleset_dealer()->GetRuleset(); - EXPECT_TRUE(ruleset_dealer()->IsRulesetAvailable()); + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); ASSERT_TRUE(!!ref_to_ruleset_2); EXPECT_EQ(test_indexed_ruleset_1().contents, ReadRulesetContents(ref_to_ruleset_1.get())); @@ -106,7 +106,7 @@ scoped_refptr<const MemoryMappedRuleset> another_ref_to_ruleset = ruleset_dealer()->GetRuleset(); - EXPECT_TRUE(ruleset_dealer()->IsRulesetAvailable()); + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); EXPECT_TRUE(!!ref_to_ruleset); EXPECT_TRUE(!!another_ref_to_ruleset); EXPECT_EQ(ref_to_ruleset.get(), another_ref_to_ruleset.get()); @@ -116,13 +116,13 @@ ruleset_dealer()->SetRulesetFile( testing::TestRuleset::Open(test_indexed_ruleset_1())); - EXPECT_TRUE(ruleset_dealer()->IsRulesetAvailable()); + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); EXPECT_FALSE(has_cached_ruleset()); scoped_refptr<const MemoryMappedRuleset> ref_to_ruleset = ruleset_dealer()->GetRuleset(); - EXPECT_TRUE(ruleset_dealer()->IsRulesetAvailable()); + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); EXPECT_TRUE(!!ref_to_ruleset); EXPECT_TRUE(has_cached_ruleset()); } @@ -143,14 +143,14 @@ another_ref_to_ruleset = nullptr; - EXPECT_TRUE(ruleset_dealer()->IsRulesetAvailable()); + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); EXPECT_TRUE(has_cached_ruleset()); EXPECT_EQ(test_indexed_ruleset_1().contents, ReadRulesetContents(ref_to_ruleset.get())); ref_to_ruleset = nullptr; - EXPECT_TRUE(ruleset_dealer()->IsRulesetAvailable()); + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); EXPECT_FALSE(has_cached_ruleset()); } @@ -170,7 +170,7 @@ ref_to_ruleset = ruleset_dealer()->GetRuleset(); - EXPECT_TRUE(ruleset_dealer()->IsRulesetAvailable()); + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); EXPECT_TRUE(has_cached_ruleset()); ASSERT_TRUE(!!ref_to_ruleset); EXPECT_EQ(test_indexed_ruleset_1().contents, @@ -178,7 +178,7 @@ ref_to_ruleset = nullptr; - EXPECT_TRUE(ruleset_dealer()->IsRulesetAvailable()); + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); EXPECT_FALSE(has_cached_ruleset()); } @@ -189,21 +189,21 @@ scoped_refptr<const MemoryMappedRuleset> ref_to_ruleset = ruleset_dealer()->GetRuleset(); - ASSERT_TRUE(ruleset_dealer()->IsRulesetAvailable()); + ASSERT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); ASSERT_TRUE(!!ref_to_ruleset); ASSERT_TRUE(has_cached_ruleset()); ruleset_dealer()->SetRulesetFile( testing::TestRuleset::Open(test_indexed_ruleset_2())); - EXPECT_TRUE(ruleset_dealer()->IsRulesetAvailable()); + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); EXPECT_FALSE(has_cached_ruleset()); // Check that nothing explodes if the last reference to the old ruleset is // dropped after it is no longer cached by the RulesetDealer. ref_to_ruleset = nullptr; - EXPECT_TRUE(ruleset_dealer()->IsRulesetAvailable()); + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); EXPECT_FALSE(has_cached_ruleset()); } @@ -223,18 +223,18 @@ ruleset_dealer()->SetRulesetFile( testing::TestRuleset::Open(test_indexed_ruleset_2())); - EXPECT_TRUE(ruleset_dealer()->IsRulesetAvailable()); + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); scoped_refptr<const MemoryMappedRuleset> ref_to_ruleset_2 = ruleset_dealer()->GetRuleset(); - EXPECT_TRUE(ruleset_dealer()->IsRulesetAvailable()); + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); ref_to_ruleset_1 = nullptr; - EXPECT_TRUE(ruleset_dealer()->IsRulesetAvailable()); + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); scoped_refptr<const MemoryMappedRuleset> another_ref_to_ruleset_2 = ruleset_dealer()->GetRuleset(); - EXPECT_TRUE(ruleset_dealer()->IsRulesetAvailable()); + EXPECT_TRUE(ruleset_dealer()->IsRulesetFileAvailable()); EXPECT_TRUE(has_cached_ruleset()); ASSERT_TRUE(!!ref_to_ruleset_2); EXPECT_TRUE(!!another_ref_to_ruleset_2);
diff --git a/components/subresource_filter/content/renderer/subresource_filter_agent.cc b/components/subresource_filter/content/renderer/subresource_filter_agent.cc index 7290e0d..876cea1 100644 --- a/components/subresource_filter/content/renderer/subresource_filter_agent.cc +++ b/components/subresource_filter/content/renderer/subresource_filter_agent.cc
@@ -84,7 +84,7 @@ if (activation_state_for_provisional_load_ != ActivationState::DISABLED) { UMA_HISTOGRAM_BOOLEAN("SubresourceFilter.DocumentLoad.RulesetIsAvailable", - ruleset_dealer_->IsRulesetAvailable()); + ruleset_dealer_->IsRulesetFileAvailable()); } } @@ -163,7 +163,7 @@ ancestor_document_urls.front().SchemeIsFile()) { RecordHistogramsOnLoadCommitted(); if (activation_state_for_provisional_load_ != ActivationState::DISABLED && - ruleset_dealer_->IsRulesetAvailable()) { + ruleset_dealer_->IsRulesetFileAvailable()) { base::Closure first_disallowed_load_callback( base::Bind(&SubresourceFilterAgent:: SignalFirstSubresourceDisallowedForCommittedLoad,
diff --git a/components/subresource_filter/core/common/test_ruleset_creator.cc b/components/subresource_filter/core/common/test_ruleset_creator.cc index 08cd6271..81aabf8 100644 --- a/components/subresource_filter/core/common/test_ruleset_creator.cc +++ b/components/subresource_filter/core/common/test_ruleset_creator.cc
@@ -4,6 +4,8 @@ #include "components/subresource_filter/core/common/test_ruleset_creator.h" +#include <string> + #include "base/files/file_util.h" #include "base/logging.h" #include "base/strings/string_number_conversions.h" @@ -21,6 +23,15 @@ // The methods below assume that char and uint8_t are interchangeable. static_assert(CHAR_BIT == 8, "Assumed char was 8 bits."); +void WriteRulesetContents(const std::vector<uint8_t>& contents, + base::FilePath path) { + int ruleset_size_as_int = base::checked_cast<int>(contents.size()); + int num_bytes_written = + base::WriteFile(path, reinterpret_cast<const char*>(contents.data()), + ruleset_size_as_int); + ASSERT_EQ(ruleset_size_as_int, num_bytes_written); +} + std::vector<uint8_t> SerializeUnindexedRulesetWithMultipleRules( const std::vector<proto::UrlRule>& rules) { std::string ruleset_contents; @@ -65,6 +76,33 @@ return file; } +// static +void TestRuleset::CorruptByTruncating(const TestRuleset& ruleset, + size_t tail_size) { + ASSERT_GT(tail_size, 0u); + ASSERT_FALSE(ruleset.contents.empty()); + std::vector<uint8_t> new_contents = ruleset.contents; + + const size_t new_size = + tail_size < new_contents.size() ? new_contents.size() - tail_size : 0; + new_contents.resize(new_size); + WriteRulesetContents(new_contents, ruleset.path); +} + +// static +void TestRuleset::CorruptByFilling(const TestRuleset& ruleset, + size_t from, + size_t to, + uint8_t fill_with) { + ASSERT_LT(from, to); + ASSERT_LE(to, ruleset.contents.size()); + + std::vector<uint8_t> new_contents = ruleset.contents; + for (size_t i = from; i < to; ++i) + new_contents[i] = fill_with; + WriteRulesetContents(new_contents, ruleset.path); +} + // TestRulesetPair ------------------------------------------------------------- TestRulesetPair::TestRulesetPair() = default; @@ -93,6 +131,21 @@ test_unindexed_ruleset)); } +void TestRulesetCreator::CreateRulesetToDisallowURLsWithManySuffixes( + base::StringPiece suffix, + int num_of_suffixes, + TestRulesetPair* test_ruleset_pair) { + DCHECK(test_ruleset_pair); + + std::vector<proto::UrlRule> rules; + for (int i = 0; i < num_of_suffixes; ++i) { + std::string current_suffix = + suffix.as_string() + '_' + base::IntToString(i); + rules.push_back(CreateSuffixRule(current_suffix)); + } + CreateRulesetWithRules(rules, test_ruleset_pair); +} + void TestRulesetCreator::CreateRulesetWithRules( const std::vector<proto::UrlRule>& rules, TestRulesetPair* test_ruleset_pair) { @@ -119,11 +172,7 @@ ruleset->contents = std::move(ruleset_contents); ASSERT_NO_FATAL_FAILURE(GetUniqueTemporaryPath(&ruleset->path)); - int ruleset_size_as_int = base::checked_cast<int>(ruleset->contents.size()); - int num_bytes_written = base::WriteFile( - ruleset->path, reinterpret_cast<const char*>(ruleset->contents.data()), - ruleset_size_as_int); - ASSERT_EQ(ruleset_size_as_int, num_bytes_written); + WriteRulesetContents(ruleset->contents, ruleset->path); } } // namespace testing
diff --git a/components/subresource_filter/core/common/test_ruleset_creator.h b/components/subresource_filter/core/common/test_ruleset_creator.h index eef00b0..9ff0b53e 100644 --- a/components/subresource_filter/core/common/test_ruleset_creator.h +++ b/components/subresource_filter/core/common/test_ruleset_creator.h
@@ -30,6 +30,15 @@ // Convenience function to open a read-only file handle to |ruleset|. static base::File Open(const TestRuleset& ruleset); + // Corrupts the |ruleset| file by truncating its tail of a certain size. + static void CorruptByTruncating(const TestRuleset& ruleset, size_t tail_size); + + // Overrides all bytes in the [from..to) range by |fill_with|. + static void CorruptByFilling(const TestRuleset& ruleset, + size_t from, + size_t to, + uint8_t fill_with); + std::vector<uint8_t> contents; base::FilePath path; }; @@ -61,14 +70,22 @@ base::StringPiece suffix, TestRulesetPair* test_ruleset_pair); - void CreateRulesetWithRules(const std::vector<proto::UrlRule>& rules, - TestRulesetPair* test_ruleset_pair); - // Same as above, but only creates an unindexed ruleset. void CreateUnindexedRulesetToDisallowURLsWithPathSuffix( base::StringPiece suffix, TestRuleset* test_unindexed_ruleset); + // Similar to CreateRulesetToDisallowURLsWithPathSuffix, but the resulting + // ruleset consists of |num_of_suffixes| rules, each of them disallowing URLs + // with suffixes of the form |suffix|_k, 0 <= k < |num_of_suffixes|. + void CreateRulesetToDisallowURLsWithManySuffixes( + base::StringPiece suffix, + int num_of_suffixes, + TestRulesetPair* test_ruleset_pair); + + void CreateRulesetWithRules(const std::vector<proto::UrlRule>& rules, + TestRulesetPair* test_ruleset_pair); + // Returns a unique |path| that is valid for the lifetime of this instance. // No file at |path| will be automatically created. void GetUniqueTemporaryPath(base::FilePath* path);
diff --git a/components/sync/base/model_type.h b/components/sync/base/model_type.h index 5cca1a08..8ce553a 100644 --- a/components/sync/base/model_type.h +++ b/components/sync/base/model_type.h
@@ -16,8 +16,8 @@ namespace base { class ListValue; -class StringValue; class Value; +using StringValue = Value; } namespace sync_pb {
diff --git a/components/sync/syncable/syncable_id.h b/components/sync/syncable/syncable_id.h index 28e2b6b..df74680 100644 --- a/components/sync/syncable/syncable_id.h +++ b/components/sync/syncable/syncable_id.h
@@ -15,7 +15,8 @@ #include "base/trace_event/memory_usage_estimator.h" namespace base { -class StringValue; +class Value; +using StringValue = Value; } // namespace base namespace sql {
diff --git a/content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.cc b/content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.cc index be6a91c..fed5af3 100644 --- a/content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.cc +++ b/content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.cc
@@ -38,6 +38,8 @@ #define SOCK_NONBLOCK O_NONBLOCK #endif +#define CASES SANDBOX_BPF_DSL_CASES + namespace { #if !defined(__i386__) @@ -177,16 +179,26 @@ // documented to be a valid errno, but we will use it anyways. return Error(EPERM); } + + // https://crbug.com/682488 + if (sysno == __NR_getsockopt || sysno == __NR_setsockopt) { + // The baseline policy applies other restrictions to these syscalls. + const Arg<int> level(1); + const Arg<int> option(2); + return If(AllOf(level == SOL_SOCKET, option == SO_SNDTIMEO), Allow()) + .Else(SandboxBPFBasePolicy::EvaluateSyscall(sysno)); + } #elif defined(__i386__) if (sysno == __NR_socketcall) { + // The baseline policy allows other socketcall sub-calls. const Arg<int> socketcall(0); - const Arg<int> domain(1); - const Arg<int> type(2); - const Arg<int> protocol(3); - return If(socketcall == SYS_CONNECT, Allow()) - .ElseIf(socketcall == SYS_SOCKET, Allow()) - .ElseIf(socketcall == SYS_GETSOCKOPT, Allow()) - .Else(Error(EPERM)); + return Switch(socketcall) + .CASES((SYS_CONNECT, + SYS_SOCKET, + SYS_SETSOCKOPT, + SYS_GETSOCKOPT), + Allow()) + .Default(SandboxBPFBasePolicy::EvaluateSyscall(sysno)); } #endif
diff --git a/extensions/browser/api/idle/idle_manager.h b/extensions/browser/api/idle/idle_manager.h index d8ff5a03..2dd296b 100644 --- a/extensions/browser/api/idle/idle_manager.h +++ b/extensions/browser/api/idle/idle_manager.h
@@ -22,7 +22,8 @@ #include "ui/base/idle/idle.h" namespace base { -class StringValue; +class Value; +using StringValue = Value; } // namespace base namespace content {
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 50a4d1b9..7791700 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -354,18 +354,12 @@ <message name="IDS_IOS_BOOKMARK_NAME_FIELD_HEADER" desc="Title shown above bookmark name field on Edit Bookmark screen. [Length: 20em]"> Name </message> - <message name="IDS_IOS_BOOKMARK_NEW_ALL_BOOKMARKS_LABEL" desc="A label for a button that takes the user to a screen where they can see all their bookmarks. [Length: 30em.]"> - All Bookmarks - </message> <message name="IDS_IOS_BOOKMARK_NEW_BACK_LABEL" desc="Accessibility label for a button that takes the user back to the previous screen. [Length: 30em.]"> Back </message> <message name="IDS_IOS_BOOKMARK_NEW_BOOKMARKS_BAR_TITLE" desc="Text that describes the bookmarks present in the bookmarks bar for chrome on desktop. [Length: 30em.] [iOS only]"> Bookmarks Bar </message> - <message name="IDS_IOS_BOOKMARK_NEW_BOOKMARKS_LABEL" desc="A title for the screen where the user can see all their bookmarks. [Length: 30em.]"> - Bookmarks - </message> <message name="IDS_IOS_BOOKMARK_NEW_BOOKMARK_CREATED" desc="A description presented to the user that they just created a bookmark. [Length: 30em.] [iOS only]"> Item created </message>
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm index 42b945f..ca7030b 100644 --- a/ios/chrome/browser/about_flags.mm +++ b/ios/chrome/browser/about_flags.mm
@@ -122,15 +122,6 @@ command_line->AppendSwitch(switches::kDisableLRUSnapshotCache); } - // Populate command line flag for the AllBookmarks from the - // configuration plist. - NSString* enableAllBookmarks = [defaults stringForKey:@"AllBookmarks"]; - if ([enableAllBookmarks isEqualToString:@"Enabled"]) { - command_line->AppendSwitch(switches::kEnableAllBookmarksView); - } else if ([enableAllBookmarks isEqualToString:@"Disabled"]) { - command_line->AppendSwitch(switches::kDisableAllBookmarksView); - } - // Populate command line flags from PasswordGenerationEnabled. NSString* enablePasswordGenerationValue = [defaults stringForKey:@"PasswordGenerationEnabled"];
diff --git a/ios/chrome/browser/chrome_switches.cc b/ios/chrome/browser/chrome_switches.cc index 2d4c469..2f92cc5 100644 --- a/ios/chrome/browser/chrome_switches.cc +++ b/ios/chrome/browser/chrome_switches.cc
@@ -12,9 +12,6 @@ // all work out. // ----------------------------------------------------------------------------- -// Disables all bookmarks view in bookmark manager. -const char kDisableAllBookmarksView[] = "disable-all-bookmarks-view"; - // Disables Contextual Search. const char kDisableContextualSearch[] = "disable-contextual-search"; @@ -65,9 +62,6 @@ // Disables the Suggestions UI const char kDisableSuggestionsUI[] = "disable-suggestions-ui"; -// Enables all bookmarks view in bookmark manager. -const char kEnableAllBookmarksView[] = "enable-all-bookmarks-view"; - // Enables Contextual Search. const char kEnableContextualSearch[] = "enable-contextual-search";
diff --git a/ios/chrome/browser/chrome_switches.h b/ios/chrome/browser/chrome_switches.h index 852ba2b..93f34187 100644 --- a/ios/chrome/browser/chrome_switches.h +++ b/ios/chrome/browser/chrome_switches.h
@@ -9,7 +9,6 @@ namespace switches { -extern const char kDisableAllBookmarksView[]; extern const char kDisableContextualSearch[]; extern const char kDisableIOSFastWebScrollViewInsets[]; extern const char kDisableIOSFeatures[]; @@ -27,7 +26,6 @@ extern const char kDisableDownloadImageRenaming[]; extern const char kDisableSuggestionsUI[]; -extern const char kEnableAllBookmarksView[]; extern const char kEnableContextualSearch[]; extern const char kEnableIOSFastWebScrollViewInsets[]; extern const char kEnableIOSFeatures[];
diff --git a/ios/chrome/browser/content_suggestions/BUILD.gn b/ios/chrome/browser/content_suggestions/BUILD.gn index 8a5a3d5..ce76fb1 100644 --- a/ios/chrome/browser/content_suggestions/BUILD.gn +++ b/ios/chrome/browser/content_suggestions/BUILD.gn
@@ -7,11 +7,17 @@ sources = [ "content_suggestions_coordinator.h", "content_suggestions_coordinator.mm", + "content_suggestions_mediator.h", + "content_suggestions_mediator.mm", + "content_suggestions_service_bridge_observer.h", + "content_suggestions_service_bridge_observer.mm", ] deps = [ "//base", + "//components/ntp_snippets", "//ios/chrome/app/strings", "//ios/chrome/browser", + "//ios/chrome/browser/ntp_snippets", "//ios/chrome/browser/ui/content_suggestions", "//ui/base", ]
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.h b/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.h index 8c051bb..7a1bcf0 100644 --- a/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.h +++ b/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.h
@@ -7,10 +7,16 @@ #import "ios/chrome/browser/chrome_coordinator.h" +namespace ios { +class ChromeBrowserState; +} + // Coordinator to manage the Suggestions UI via a // ContentSuggestionsViewController. @interface ContentSuggestionsCoordinator : ChromeCoordinator +// BrowserState used to create the ContentSuggestionFactory. +@property(nonatomic, assign) ios::ChromeBrowserState* browserState; // Whether the Suggestions UI is displayed. If this is true, start is a no-op. @property(nonatomic, readonly) BOOL visible;
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm b/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm index 0df1af28..bbc9d7a 100644 --- a/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm +++ b/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm
@@ -5,6 +5,8 @@ #import "ios/chrome/browser/content_suggestions/content_suggestions_coordinator.h" #include "base/mac/scoped_nsobject.h" +#import "ios/chrome/browser/content_suggestions/content_suggestions_mediator.h" +#include "ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h" #include "ios/chrome/grit/ios_strings.h" @@ -16,25 +18,33 @@ @interface ContentSuggestionsCoordinator ()<ContentSuggestionsCommands> { UINavigationController* _navigationController; + ContentSuggestionsMediator* _contentSuggestionsMediator; } @end @implementation ContentSuggestionsCoordinator +@synthesize browserState = _browserState; @synthesize visible = _visible; - (void)start { - if (self.visible) { - // Prevent this coordinator from being started twice in a row. + if (self.visible || !self.browserState) { + // Prevent this coordinator from being started twice in a row or without a + // browser state. return; } _visible = YES; + _contentSuggestionsMediator = [[ContentSuggestionsMediator alloc] + initWithContentService:IOSChromeContentSuggestionsServiceFactory:: + GetForBrowserState(self.browserState)]; + ContentSuggestionsViewController* suggestionsViewController = [[ContentSuggestionsViewController alloc] - initWithStyle:CollectionViewControllerStyleDefault]; + initWithStyle:CollectionViewControllerStyleDefault + dataSource:_contentSuggestionsMediator]; suggestionsViewController.suggestionCommandHandler = self; _navigationController = [[UINavigationController alloc]
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_mediator.h b/ios/chrome/browser/content_suggestions/content_suggestions_mediator.h new file mode 100644 index 0000000..f53553a --- /dev/null +++ b/ios/chrome/browser/content_suggestions/content_suggestions_mediator.h
@@ -0,0 +1,30 @@ +// 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 IOS_CHROME_BROWSER_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_MEDIATOR_H_ +#define IOS_CHROME_BROWSER_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_MEDIATOR_H_ + +#import <UIKit/UIKit.h> + +#import "ios/chrome/browser/content_suggestions/content_suggestions_mediator.h" +#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_data_source.h" + +namespace ntp_snippets { +class ContentSuggestionsService; +} + +// Mediator for ContentSuggestions. Makes the interface between a +// ntp_snippets::ContentSuggestionsService and the Objective-C services using +// its data. +@interface ContentSuggestionsMediator : NSObject<ContentSuggestionsDataSource> + +// Initialize the mediator with the |contentService| to mediate. +- (instancetype)initWithContentService: + (ntp_snippets::ContentSuggestionsService*)contentService + NS_DESIGNATED_INITIALIZER; +- (instancetype)init NS_UNAVAILABLE; + +@end + +#endif // IOS_CHROME_BROWSER_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_MEDIATOR_H_
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm b/ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm new file mode 100644 index 0000000..c87b163 --- /dev/null +++ b/ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm
@@ -0,0 +1,113 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/content_suggestions/content_suggestions_mediator.h" + +#include "base/memory/ptr_util.h" +#include "components/ntp_snippets/category.h" +#include "components/ntp_snippets/content_suggestion.h" +#import "ios/chrome/browser/content_suggestions/content_suggestions_service_bridge_observer.h" +#import "ios/chrome/browser/ui/content_suggestions/content_suggestion.h" +#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_data_sink.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@interface ContentSuggestionsMediator ()<ContentSuggestionsServiceObserver> { + // Bridge for this class to become an observer of a ContentSuggestionsService. + std::unique_ptr<ContentSuggestionsServiceBridge> _suggestionBridge; +} + +@property(nonatomic, assign) + ntp_snippets::ContentSuggestionsService* contentService; + +// Converts the data in |category| to ContentSuggestion and adds them to the +// |contentArray|. +- (void)addContentInCategory:(ntp_snippets::Category&)category + toArray:(NSMutableArray<ContentSuggestion*>*)contentArray; + +// Converts the |contentsuggestion| to a ContentSuggestion. +- (ContentSuggestion*)convertContentSuggestion: + (const ntp_snippets::ContentSuggestion&)contentsuggestion; + +@end + +@implementation ContentSuggestionsMediator + +@synthesize contentService = _contentService; +@synthesize dataSink = _dataSink; + +- (instancetype)initWithContentService: + (ntp_snippets::ContentSuggestionsService*)contentService { + self = [super init]; + if (self) { + _suggestionBridge = + base::MakeUnique<ContentSuggestionsServiceBridge>(self, contentService); + _contentService = contentService; + } + return self; +} + +#pragma mark - ContentSuggestionsDataSource + +- (NSArray<ContentSuggestion*>*)allSuggestions { + std::vector<ntp_snippets::Category> categories = + self.contentService->GetCategories(); + NSMutableArray<ContentSuggestion*>* dataHolders = [NSMutableArray array]; + for (auto& category : categories) { + [self addContentInCategory:category toArray:dataHolders]; + } + return dataHolders; +} + +#pragma mark - ContentSuggestionsServiceObserver + +- (void)contentSuggestionsService: + (ntp_snippets::ContentSuggestionsService*)suggestionsService + newSuggestionsInCategory:(ntp_snippets::Category)category { + [self.dataSink dataAvailable]; +} + +- (void)contentSuggestionsService: + (ntp_snippets::ContentSuggestionsService*)suggestionsService + category:(ntp_snippets::Category)category + statusChangedTo:(ntp_snippets::CategoryStatus)status { + // Update dataSink. +} + +- (void)contentSuggestionsService: + (ntp_snippets::ContentSuggestionsService*)suggestionsService + SuggestionInvalidated: + (const ntp_snippets::ContentSuggestion::ID&)suggestion_id { + // Update dataSink. +} + +- (void)contentSuggestionsServiceFullRefreshRequired: + (ntp_snippets::ContentSuggestionsService*)suggestionsService { + // Update dataSink. +} + +- (void)contentSuggestionsServiceShutdown: + (ntp_snippets::ContentSuggestionsService*)suggestionsService { + // Update dataSink. +} + +#pragma mark - Private + +- (void)addContentInCategory:(ntp_snippets::Category&)category + toArray:(NSMutableArray<ContentSuggestion*>*)contentArray { + const std::vector<ntp_snippets::ContentSuggestion>& suggestions = + self.contentService->GetSuggestionsForCategory(category); + for (auto& contentSuggestion : suggestions) { + [contentArray addObject:[self convertContentSuggestion:contentSuggestion]]; + } +} + +- (ContentSuggestion*)convertContentSuggestion: + (const ntp_snippets::ContentSuggestion&)contentsuggestion { + return [[ContentSuggestion alloc] init]; +} + +@end
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_service_bridge_observer.h b/ios/chrome/browser/content_suggestions/content_suggestions_service_bridge_observer.h new file mode 100644 index 0000000..50ed8590 --- /dev/null +++ b/ios/chrome/browser/content_suggestions/content_suggestions_service_bridge_observer.h
@@ -0,0 +1,69 @@ +// 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 IOS_CHROME_BROWSER_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_SERVICE_BRIDGE_OBSERVER_H_ +#define IOS_CHROME_BROWSER_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_SERVICE_BRIDGE_OBSERVER_H_ + +#include "components/ntp_snippets/content_suggestions_service.h" + +// Observes ContentSuggestionsService events from Objective-C. To use as a +// ntp_snippets::ContentSuggestionsService::Observer, wrap in a +// ContentSuggestionsServiceBridge. +@protocol ContentSuggestionsServiceObserver + +// Invoked by ntp_snippets::ContentSuggestionsService::OnNewSuggestions. +- (void)contentSuggestionsService: + (ntp_snippets::ContentSuggestionsService*)suggestionsService + newSuggestionsInCategory:(ntp_snippets::Category)category; + +// Invoked by ntp_snippets::ContentSuggestionsService::OnCategoryStatusChanged. +- (void)contentSuggestionsService: + (ntp_snippets::ContentSuggestionsService*)suggestionsService + category:(ntp_snippets::Category)category + statusChangedTo:(ntp_snippets::CategoryStatus)status; + +// Invoked by ntp_snippets::ContentSuggestionsService::OnSuggestionInvalidated. +- (void)contentSuggestionsService: + (ntp_snippets::ContentSuggestionsService*)suggestionsService + SuggestionInvalidated: + (const ntp_snippets::ContentSuggestion::ID&)suggestion_id; + +// Invoked by ntp_snippets::ContentSuggestionsService::OnFullRefreshRequired. +- (void)contentSuggestionsServiceFullRefreshRequired: + (ntp_snippets::ContentSuggestionsService*)suggestionsService; + +// Invoked by +// ntp_snippets::ContentSuggestionsService::ContentSuggestionsServiceShutdown. +- (void)contentSuggestionsServiceShutdown: + (ntp_snippets::ContentSuggestionsService*)suggestionsService; + +@end + +// Observer for the ContentSuggestionsService that translates all the callbacks +// to Objective-C calls. +class ContentSuggestionsServiceBridge + : public ntp_snippets::ContentSuggestionsService::Observer { + public: + ContentSuggestionsServiceBridge( + id<ContentSuggestionsServiceObserver> observer, + ntp_snippets::ContentSuggestionsService* service); + ~ContentSuggestionsServiceBridge() override; + + private: + void OnNewSuggestions(ntp_snippets::Category category) override; + void OnCategoryStatusChanged( + ntp_snippets::Category category, + ntp_snippets::CategoryStatus new_status) override; + void OnSuggestionInvalidated( + const ntp_snippets::ContentSuggestion::ID& suggestion_id) override; + void OnFullRefreshRequired() override; + void ContentSuggestionsServiceShutdown() override; + + __unsafe_unretained id<ContentSuggestionsServiceObserver> observer_; + ntp_snippets::ContentSuggestionsService* service_; // weak + + DISALLOW_COPY_AND_ASSIGN(ContentSuggestionsServiceBridge); +}; + +#endif // IOS_CHROME_BROWSER_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_SERVICE_BRIDGE_OBSERVER_H_
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_service_bridge_observer.mm b/ios/chrome/browser/content_suggestions/content_suggestions_service_bridge_observer.mm new file mode 100644 index 0000000..90d3d7c --- /dev/null +++ b/ios/chrome/browser/content_suggestions/content_suggestions_service_bridge_observer.mm
@@ -0,0 +1,49 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/content_suggestions/content_suggestions_service_bridge_observer.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +ContentSuggestionsServiceBridge::ContentSuggestionsServiceBridge( + id<ContentSuggestionsServiceObserver> observer, + ntp_snippets::ContentSuggestionsService* service) { + observer_ = observer; + service_ = service; + service->AddObserver(this); +} + +ContentSuggestionsServiceBridge::~ContentSuggestionsServiceBridge() { + service_->RemoveObserver(this); +} + +void ContentSuggestionsServiceBridge::OnNewSuggestions( + ntp_snippets::Category category) { + [observer_ contentSuggestionsService:service_ + newSuggestionsInCategory:category]; +} + +void ContentSuggestionsServiceBridge::OnCategoryStatusChanged( + ntp_snippets::Category category, + ntp_snippets::CategoryStatus new_status) { + [observer_ contentSuggestionsService:service_ + category:category + statusChangedTo:new_status]; +} + +void ContentSuggestionsServiceBridge::OnSuggestionInvalidated( + const ntp_snippets::ContentSuggestion::ID& suggestion_id) { + [observer_ contentSuggestionsService:service_ + SuggestionInvalidated:suggestion_id]; +} + +void ContentSuggestionsServiceBridge::OnFullRefreshRequired() { + [observer_ contentSuggestionsServiceFullRefreshRequired:service_]; +} + +void ContentSuggestionsServiceBridge::ContentSuggestionsServiceShutdown() { + [observer_ contentSuggestionsServiceShutdown:service_]; +}
diff --git a/ios/chrome/browser/experimental_flags.h b/ios/chrome/browser/experimental_flags.h index a23319a..efdc73a 100644 --- a/ios/chrome/browser/experimental_flags.h +++ b/ios/chrome/browser/experimental_flags.h
@@ -43,9 +43,6 @@ // Whether background crash report upload should generate a local notification. bool IsAlertOnBackgroundUploadEnabled(); -// Whether the All Bookmarks view is visible in bookmarks. -bool IsAllBookmarksEnabled(); - // Whether auto-reload is enabled. bool IsAutoReloadEnabled();
diff --git a/ios/chrome/browser/experimental_flags.mm b/ios/chrome/browser/experimental_flags.mm index 8f83865..892a616 100644 --- a/ios/chrome/browser/experimental_flags.mm +++ b/ios/chrome/browser/experimental_flags.mm
@@ -85,25 +85,6 @@ boolForKey:kEnableAlertOnBackgroundUpload]; } -bool IsAllBookmarksEnabled() { - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - if (command_line->HasSwitch(switches::kEnableAllBookmarksView)) { - return true; - } else if (command_line->HasSwitch(switches::kDisableAllBookmarksView)) { - return false; - } - - // Check if the finch experiment exists. - std::string group_name = - base::FieldTrialList::FindFullName("RemoveAllBookmarks"); - - if (group_name.empty()) { - return false; // If no finch experiment, all bookmarks is disabled. - } - return base::StartsWith(group_name, "Enabled", - base::CompareCase::INSENSITIVE_ASCII); -} - bool IsAutoReloadEnabled() { std::string group_name = base::FieldTrialList::FindFullName("IOSAutoReload"); base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
diff --git a/ios/chrome/browser/native_app_launcher/BUILD.gn b/ios/chrome/browser/native_app_launcher/BUILD.gn index 687ac9db..99552a3 100644 --- a/ios/chrome/browser/native_app_launcher/BUILD.gn +++ b/ios/chrome/browser/native_app_launcher/BUILD.gn
@@ -51,6 +51,7 @@ } source_set("native_app_launcher_internal") { + configs += [ "//build/config/compiler:enable_arc" ] sources = [ "native_app_navigation_controller.h", "native_app_navigation_controller.mm",
diff --git a/ios/chrome/browser/native_app_launcher/DEPS b/ios/chrome/browser/native_app_launcher/DEPS index 1c40ab5f..eb9956d 100644 --- a/ios/chrome/browser/native_app_launcher/DEPS +++ b/ios/chrome/browser/native_app_launcher/DEPS
@@ -5,4 +5,7 @@ "+ios/web/navigation/navigation_manager_impl.h", "+ios/web/web_state/web_state_impl.h", ], + "^native_app_navigation_controller\.mm$": [ + "+ios/web/web_state/ui/crw_web_controller.h", + ], }
diff --git a/ios/chrome/browser/native_app_launcher/native_app_navigation_controller.mm b/ios/chrome/browser/native_app_launcher/native_app_navigation_controller.mm index bbb39766..5181252a 100644 --- a/ios/chrome/browser/native_app_launcher/native_app_navigation_controller.mm +++ b/ios/chrome/browser/native_app_launcher/native_app_navigation_controller.mm
@@ -20,9 +20,14 @@ #import "ios/public/provider/chrome/browser/native_app_launcher/native_app_types.h" #import "ios/public/provider/chrome/browser/native_app_launcher/native_app_whitelist_manager.h" #include "ios/web/public/web_state/web_state.h" +#import "ios/web/web_state/ui/crw_web_controller.h" #import "net/base/mac/url_conversions.h" #include "net/url_request/url_request_context_getter.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + using base::UserMetricsAction; @interface NativeAppNavigationController () @@ -48,10 +53,10 @@ // DEPRECATED: Tab hosting the infobar and is also used for accessing Tab // states such as navigation manager and whether it is a pre-rendered tab. // Use |webState| whenever possible. - __unsafe_unretained Tab* _tab; // weak - base::scoped_nsprotocol<id<NativeAppMetadata>> _metadata; + __weak Tab* _tab; + id<NativeAppMetadata> _metadata; // A set of appIds encoded as NSStrings. - base::scoped_nsobject<NSMutableSet> _appsPossiblyBeingInstalled; + NSMutableSet* _appsPossiblyBeingInstalled; } // Designated initializer. Use this instead of -init. @@ -68,16 +73,16 @@ // same webState. DCHECK(!tab || [tab webState] == webState); _tab = tab; - _appsPossiblyBeingInstalled.reset([[NSMutableSet alloc] init]); + _appsPossiblyBeingInstalled = [[NSMutableSet alloc] init]; } return self; } - (void)copyStateFrom:(NativeAppNavigationController*)controller { DCHECK(controller); - _appsPossiblyBeingInstalled.reset([[NSMutableSet alloc] - initWithSet:[controller appsPossiblyBeingInstalled]]); - for (NSString* appIdString in _appsPossiblyBeingInstalled.get()) { + _appsPossiblyBeingInstalled = [[NSMutableSet alloc] + initWithSet:[controller appsPossiblyBeingInstalled]]; + for (NSString* appIdString in _appsPossiblyBeingInstalled) { DCHECK([appIdString isKindOfClass:[NSString class]]); NSURL* appURL = [ios::GetChromeBrowserProvider()->GetNativeAppWhitelistManager() @@ -92,7 +97,6 @@ - (void)dealloc { [[InstallationNotifier sharedInstance] unregisterForNotifications:self]; - [super dealloc]; } - (NSMutableSet*)appsPossiblyBeingInstalled { @@ -102,9 +106,8 @@ - (void)showInfoBarIfNecessary { // Find a potential matching native app. GURL pageURL = _webState->GetLastCommittedURL(); - _metadata.reset( - [ios::GetChromeBrowserProvider()->GetNativeAppWhitelistManager() - newNativeAppForURL:pageURL]); + _metadata = [ios::GetChromeBrowserProvider()->GetNativeAppWhitelistManager() + nativeAppForURL:pageURL]; if (!_metadata || [_metadata shouldBypassInfoBars]) return;
diff --git a/ios/chrome/browser/native_app_launcher/native_app_navigation_util.mm b/ios/chrome/browser/native_app_launcher/native_app_navigation_util.mm index 7a6c34e..072e0d8 100644 --- a/ios/chrome/browser/native_app_launcher/native_app_navigation_util.mm +++ b/ios/chrome/browser/native_app_launcher/native_app_navigation_util.mm
@@ -9,6 +9,10 @@ #include "ios/web/public/navigation_manager.h" #import "ios/web/public/web_state/web_state.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + namespace native_app_launcher { bool IsLinkNavigation(web::WebState* web_state) {
diff --git a/ios/chrome/browser/resources/Settings.bundle/Experimental.plist b/ios/chrome/browser/resources/Settings.bundle/Experimental.plist index 67dd19d..0b517c4 100644 --- a/ios/chrome/browser/resources/Settings.bundle/Experimental.plist +++ b/ios/chrome/browser/resources/Settings.bundle/Experimental.plist
@@ -128,28 +128,6 @@ <key>Type</key> <string>PSMultiValueSpecifier</string> <key>Title</key> - <string>Enable All Bookmarks</string> - <key>Key</key> - <string>AllBookmarks</string> - <key>DefaultValue</key> - <string></string> - <key>Titles</key> - <array> - <string>Default</string> - <string>Enabled</string> - <string>Disabled</string> - </array> - <key>Values</key> - <array> - <string></string> - <string>Enabled</string> - <string>Disabled</string> - </array> - </dict> - <dict> - <key>Type</key> - <string>PSMultiValueSpecifier</string> - <key>Title</key> <string>Enable Popular Sites</string> <key>Key</key> <string>EnablePopularSites</string>
diff --git a/ios/chrome/browser/suggestions/image_fetcher_impl.mm b/ios/chrome/browser/suggestions/image_fetcher_impl.mm index ceee532..c701dfc4 100644 --- a/ios/chrome/browser/suggestions/image_fetcher_impl.mm +++ b/ios/chrome/browser/suggestions/image_fetcher_impl.mm
@@ -40,7 +40,6 @@ DataUseServiceName data_use_service_name) { // Not implemented - will be obsolete once iOS also uses // image_fetcher::ImageDataFetcher. - NOTREACHED(); } void ImageFetcherImpl::StartOrQueueNetworkRequest(
diff --git a/ios/chrome/browser/tabs/tab.mm b/ios/chrome/browser/tabs/tab.mm index 36ff77d..670c8cc5 100644 --- a/ios/chrome/browser/tabs/tab.mm +++ b/ios/chrome/browser/tabs/tab.mm
@@ -1847,8 +1847,8 @@ return NO; base::scoped_nsprotocol<id<NativeAppMetadata>> metadata( - [ios::GetChromeBrowserProvider()->GetNativeAppWhitelistManager() - newNativeAppForURL:url]); + [[ios::GetChromeBrowserProvider()->GetNativeAppWhitelistManager() + nativeAppForURL:url] retain]); if (![metadata shouldAutoOpenLinks]) return NO;
diff --git a/ios/chrome/browser/ui/authentication/signin_interaction_controller_egtest.mm b/ios/chrome/browser/ui/authentication/signin_interaction_controller_egtest.mm index d827393..cd544f5 100644 --- a/ios/chrome/browser/ui/authentication/signin_interaction_controller_egtest.mm +++ b/ios/chrome/browser/ui/authentication/signin_interaction_controller_egtest.mm
@@ -547,9 +547,7 @@ } // Selects the top level folder (Sign In promo is only shown there). - NSString* topLevelFolderTitle = experimental_flags::IsAllBookmarksEnabled() - ? @"All Bookmarks" - : @"Mobile Bookmarks"; + NSString* topLevelFolderTitle = @"Mobile Bookmarks"; id<GREYMatcher> all_bookmarks_matcher = grey_allOf(grey_kindOfClass(NSClassFromString(@"BookmarkMenuCell")), grey_descendant(grey_text(topLevelFolderTitle)), nil);
diff --git a/ios/chrome/browser/ui/bookmarks/BUILD.gn b/ios/chrome/browser/ui/bookmarks/BUILD.gn index c589e26..807c3fd 100644 --- a/ios/chrome/browser/ui/bookmarks/BUILD.gn +++ b/ios/chrome/browser/ui/bookmarks/BUILD.gn
@@ -4,8 +4,6 @@ source_set("bookmarks") { sources = [ - "bookmark_all_collection_view.h", - "bookmark_all_collection_view.mm", "bookmark_collection_cells.h", "bookmark_collection_cells.mm", "bookmark_collection_view.h", @@ -204,9 +202,6 @@ "resources/bookmark_blue_folder.png", "resources/bookmark_blue_folder@2x.png", "resources/bookmark_blue_folder@3x.png", - "resources/bookmark_blue_star.png", - "resources/bookmark_blue_star@2x.png", - "resources/bookmark_blue_star@3x.png", "resources/bookmark_gray_back.png", "resources/bookmark_gray_back@2x.png", "resources/bookmark_gray_back@3x.png", @@ -228,9 +223,6 @@ "resources/bookmark_gray_new_folder.png", "resources/bookmark_gray_new_folder@2x.png", "resources/bookmark_gray_new_folder@3x.png", - "resources/bookmark_gray_star.png", - "resources/bookmark_gray_star@2x.png", - "resources/bookmark_gray_star@3x.png", "resources/bookmark_gray_star_large.png", "resources/bookmark_gray_star_large@2x.png", "resources/bookmark_gray_star_large@3x.png",
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_folder_collection_view.mm b/ios/chrome/browser/ui/bookmarks/bookmark_folder_collection_view.mm index 7f68a85..ffcbd4f 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_folder_collection_view.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_folder_collection_view.mm
@@ -439,9 +439,6 @@ } - (void)promoStateChangedAnimated:(BOOL)animate { - if (experimental_flags::IsAllBookmarksEnabled()) - return; // The promo is not shown if All Bookmarks is enabled. - BOOL newPromoState = !self.editing && self.folder && self.folder->type() == BookmarkNode::MOBILE &&
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_home_handset_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_home_handset_view_controller.mm index ab58a75..6dcefb3 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_home_handset_view_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_handset_view_controller.mm
@@ -21,7 +21,6 @@ #import "ios/chrome/browser/ui/alert_coordinator/action_sheet_coordinator.h" #import "ios/chrome/browser/ui/bookmarks/bars/bookmark_editing_bar.h" #import "ios/chrome/browser/ui/bookmarks/bars/bookmark_navigation_bar.h" -#import "ios/chrome/browser/ui/bookmarks/bookmark_all_collection_view.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_collection_cells.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_collection_view.h" @@ -68,7 +67,6 @@ // time, it contains exactly one of the BookmarkCollectionView subclasses. @property(nonatomic, retain) UIView* contentView; // The possible views that can be shown from the menu. -@property(nonatomic, retain) BookmarkAllCollectionView* allItemsView; @property(nonatomic, retain) BookmarkFolderCollectionView* folderView; // This view is created and used if the model is not fully loaded yet by the // time this controller starts. @@ -121,7 +119,6 @@ // view has been loaded, and the bookmark model is loaded. - (void)loadBookmarkViews; // If the view doesn't exist, create it. -- (void)ensureAllViewExists; - (void)ensureFolderViewExists; // Updates the property 'primaryMenuItem'. // Updates the UI to reflect the new state of 'primaryMenuItem'. @@ -219,7 +216,6 @@ @end @implementation BookmarkHomeHandsetViewController -@synthesize allItemsView = _allItemsView; @synthesize contentView = _contentView; @synthesize folderView = _folderView; @synthesize waitForModelView = _waitForModelView; @@ -257,7 +253,6 @@ } - (void)dealloc { - _allItemsView.delegate = nil; _folderView.delegate = nil; _menuView.delegate = nil; @@ -380,21 +375,6 @@ } } -- (void)ensureAllViewExists { - if (self.allItemsView) - return; - - base::scoped_nsobject<BookmarkAllCollectionView> view( - [[BookmarkAllCollectionView alloc] - initWithBrowserState:self.browserState - frame:[self frameForPrimaryView]]); - self.allItemsView = view; - self.allItemsView.delegate = self; - [self.allItemsView setEditing:self.editing animated:NO]; - self.allItemsView.autoresizingMask = - UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; -} - - (void)ensureFolderViewExists { if (self.folderView) return; @@ -412,30 +392,21 @@ - (void)updatePrimaryMenuItem:(BookmarkMenuItem*)menuItem animated:(BOOL)animated { + DCHECK(menuItem.type == bookmarks::MenuItemFolder); if ([self.primaryMenuItem isEqual:menuItem]) return; // Disable editing on previous primary view before dismissing it. No need to // animate because this view is immediately removed from hierarchy. - [self.primaryView setEditing:NO animated:NO]; + if ([[self primaryMenuItem] supportsEditing]) + [self.primaryView setEditing:NO animated:NO]; [[self primaryView] removeFromSuperview]; self.primaryMenuItem = menuItem; - switch (self.primaryMenuItem.type) { - case bookmarks::MenuItemAll: - [self ensureAllViewExists]; - break; - case bookmarks::MenuItemFolder: - [self ensureFolderViewExists]; - [self.folderView resetFolder:self.primaryMenuItem.folder]; - [self.folderView promoStateChangedAnimated:NO]; - break; - case bookmarks::MenuItemDivider: - case bookmarks::MenuItemSectionHeader: - NOTREACHED(); - break; - } + [self ensureFolderViewExists]; + [self.folderView resetFolder:self.primaryMenuItem.folder]; + [self.folderView promoStateChangedAnimated:NO]; UIView* primaryView = [self primaryView]; [[self primaryView] changeOrientation:GetInterfaceOrientation()]; @@ -451,16 +422,9 @@ } - (UIView<BookmarkHomePrimaryView>*)primaryView { - switch (self.primaryMenuItem.type) { - case bookmarks::MenuItemAll: - return self.allItemsView; - case bookmarks::MenuItemFolder: - return self.folderView; - case bookmarks::MenuItemDivider: - case bookmarks::MenuItemSectionHeader: - NOTREACHED(); - return nil; - } + if (self.primaryMenuItem.type == bookmarks::MenuItemFolder) + return self.folderView; + return nil; } #pragma mark - Editing bar methods. @@ -1157,15 +1121,6 @@ #pragma mark - BookmarkPromoControllerDelegate - (void)promoStateChanged:(BOOL)promoEnabled { - [self.allItemsView.collectionView reloadData]; - // This is required to workaround a crash seen once on iOS 7.1 when - // the collection gets two reloadData without getting a call to layout - // subviews, the collection view will reuse some cached data for the perfoming - // the layout which are invalid after the second call to reloadData. - // Forcing the layout invalidation after each reloadData seems to fix the - // issue. - [self.allItemsView.collectionView.collectionViewLayout invalidateLayout]; - [self.folderView promoStateChangedAnimated:self.folderView == [self primaryView]]; }
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_home_tablet_ntp_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_home_tablet_ntp_controller.mm index e4e521b..bbb6f7e 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_home_tablet_ntp_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_tablet_ntp_controller.mm
@@ -24,7 +24,6 @@ #import "ios/chrome/browser/ui/alert_coordinator/action_sheet_coordinator.h" #import "ios/chrome/browser/ui/bookmarks/bars/bookmark_editing_bar.h" #import "ios/chrome/browser/ui/bookmarks/bars/bookmark_navigation_bar.h" -#import "ios/chrome/browser/ui/bookmarks/bookmark_all_collection_view.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_collection_view.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.h" @@ -131,7 +130,6 @@ // time, it contains exactly one of the BookmarkCollectionView subclasses. @property(nonatomic, retain) ContentView* contentView; // The possible views that can be shown from the menu. -@property(nonatomic, retain) BookmarkAllCollectionView* allItemsView; @property(nonatomic, retain) BookmarkFolderCollectionView* folderView; // This view is created and used if the model is not fully loaded yet by the // time this controller starts. @@ -185,7 +183,6 @@ // loaded, and the bookmark model is loaded. - (void)loadBookmarkViews; // If the view doesn't exist, create it. -- (void)ensureAllViewExists; - (void)ensureFolderViewExists; // Updates the property 'primaryMenuItem'. // Updates the UI to reflect the new state of 'primaryMenuItem'. @@ -282,7 +279,6 @@ @synthesize bookmarks = _bookmarks; @synthesize contentView = _contentView; -@synthesize allItemsView = _allItemsView; @synthesize folderView = _folderView; @synthesize waitForModelView = _waitForModelView; @@ -329,7 +325,6 @@ - (void)dealloc { _contentView.delegate = nil; - _allItemsView.delegate = nil; _folderView.delegate = nil; _menuView.delegate = nil; @@ -506,20 +501,6 @@ } } -- (void)ensureAllViewExists { - if (self.allItemsView) - return; - - base::scoped_nsobject<BookmarkAllCollectionView> view( - [[BookmarkAllCollectionView alloc] initWithBrowserState:self.browserState - frame:CGRectZero]); - self.allItemsView = view; - self.allItemsView.delegate = self; - [self.allItemsView setEditing:self.editing animated:NO]; - self.allItemsView.autoresizingMask = - UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; -} - - (void)ensureFolderViewExists { if (self.folderView) return; @@ -537,6 +518,7 @@ - (void)updatePrimaryMenuItem:(BookmarkMenuItem*)menuItem animated:(BOOL)animated { + DCHECK(menuItem.type == bookmarks::MenuItemFolder); if ([self.primaryMenuItem isEqual:menuItem]) return; @@ -546,20 +528,9 @@ [[self primaryView] removeFromSuperview]; self.primaryMenuItem = menuItem; - switch (self.primaryMenuItem.type) { - case bookmarks::MenuItemAll: - [self ensureAllViewExists]; - break; - case bookmarks::MenuItemFolder: - [self ensureFolderViewExists]; - [self.folderView resetFolder:self.primaryMenuItem.folder]; - [self.folderView promoStateChangedAnimated:NO]; - break; - case bookmarks::MenuItemDivider: - case bookmarks::MenuItemSectionHeader: - NOTREACHED(); - break; - } + [self ensureFolderViewExists]; + [self.folderView resetFolder:self.primaryMenuItem.folder]; + [self.folderView promoStateChangedAnimated:NO]; [[self primaryView] changeOrientation:GetInterfaceOrientation()]; [[self primaryView] setScrollsToTop:self.scrollToTop]; @@ -578,20 +549,9 @@ } - (UIView<BookmarkHomePrimaryView>*)primaryView { - if (!self.primaryMenuItem) - return nil; - DCHECK([self contentView]); - - switch (self.primaryMenuItem.type) { - case bookmarks::MenuItemAll: - return self.allItemsView; - case bookmarks::MenuItemFolder: - return self.folderView; - case bookmarks::MenuItemDivider: - case bookmarks::MenuItemSectionHeader: - NOTREACHED(); - return nil; - } + if (self.primaryMenuItem.type == bookmarks::MenuItemFolder) + return self.folderView; + return nil; } - (BOOL)shouldPresentMenuInSlideInPanel { @@ -1324,14 +1284,6 @@ #pragma mark - BookmarkPromoControllerDelegate - (void)promoStateChanged:(BOOL)promoEnabled { - [self.allItemsView.collectionView reloadData]; - // This is required to workaround a crash seen once on iOS 7.1 when - // the collection gets two reloadData without getting a call to layout - // subviews, the collection view will reuse some cached data for the perfoming - // the layout which are invalid after the second call to reloadData. - // Forcing the layout invalidation after each reloadData seems to fix the - // issue. - [self.allItemsView.collectionView.collectionViewLayout invalidateLayout]; [self.folderView promoStateChangedAnimated:self.folderView == [self primaryView]]; }
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_menu_item.h b/ios/chrome/browser/ui/bookmarks/bookmark_menu_item.h index f9a4b00..d453234 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_menu_item.h +++ b/ios/chrome/browser/ui/bookmarks/bookmark_menu_item.h
@@ -16,8 +16,6 @@ // and must not be changed. New values must be added at the end, and if // a value is removed it should not be reused. typedef enum { - // Corresponds with the "all items" view. - MenuItemAll = 0, // A very thin divider. MenuItemDivider = 1, // A BookmarkNode* that is a folder. @@ -51,7 +49,6 @@ // Returns the menuitem located at the root ancestor of this item. - (BookmarkMenuItem*)parentItem; -+ (BookmarkMenuItem*)allMenuItem; + (BookmarkMenuItem*)dividerMenuItem; + (BookmarkMenuItem*)folderMenuItemForNode:(const bookmarks::BookmarkNode*)node rootAncestor:
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_menu_item.mm b/ios/chrome/browser/ui/bookmarks/bookmark_menu_item.mm index 45c6b0e..b5920fe9 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_menu_item.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_menu_item.mm
@@ -18,11 +18,10 @@ namespace bookmarks { BOOL NumberIsValidMenuItemType(int number) { // Invalid and deprecated numbers. - if (number < 0 || number > MenuItemLast) + if (number < 1 || number > MenuItemLast) return NO; MenuItemType type = static_cast<MenuItemType>(number); switch (type) { - case MenuItemAll: case MenuItemFolder: return YES; @@ -61,7 +60,6 @@ - (UIAccessibilityTraits)accessibilityTraits { switch (self.type) { - case bookmarks::MenuItemAll: case bookmarks::MenuItemFolder: return super.accessibilityTraits |= UIAccessibilityTraitButton; case bookmarks::MenuItemSectionHeader: @@ -73,8 +71,6 @@ - (NSString*)title { switch (self.type) { - case bookmarks::MenuItemAll: - return l10n_util::GetNSString(IDS_IOS_BOOKMARK_NEW_ALL_BOOKMARKS_LABEL); case bookmarks::MenuItemDivider: return nil; case bookmarks::MenuItemFolder: @@ -86,8 +82,6 @@ - (NSString*)titleForMenu { switch (self.type) { - case bookmarks::MenuItemAll: - return l10n_util::GetNSString(IDS_IOS_BOOKMARK_NEW_ALL_BOOKMARKS_LABEL); case bookmarks::MenuItemDivider: case bookmarks::MenuItemFolder: case bookmarks::MenuItemSectionHeader: @@ -97,8 +91,6 @@ - (NSString*)titleForNavigationBar { switch (self.type) { - case bookmarks::MenuItemAll: - return l10n_util::GetNSString(IDS_IOS_BOOKMARK_NEW_BOOKMARKS_LABEL); case bookmarks::MenuItemDivider: case bookmarks::MenuItemFolder: case bookmarks::MenuItemSectionHeader: @@ -108,8 +100,6 @@ - (NSString*)accessibilityIdentifier { switch (self.type) { - case bookmarks::MenuItemAll: - return @"MenuItemAll"; case bookmarks::MenuItemDivider: return nil; case bookmarks::MenuItemFolder: @@ -121,11 +111,6 @@ - (UIImage*)imagePrimary:(BOOL)primary { switch (self.type) { - case bookmarks::MenuItemAll: - if (primary) - return [UIImage imageNamed:@"bookmark_blue_star"]; - else - return [UIImage imageNamed:@"bookmark_gray_star"]; case bookmarks::MenuItemFolder: if (self.folder->type() == BookmarkNode::BOOKMARK_BAR || self.folder->type() == BookmarkNode::MOBILE || @@ -152,7 +137,6 @@ case bookmarks::MenuItemDivider: case bookmarks::MenuItemSectionHeader: return NO; - case bookmarks::MenuItemAll: case bookmarks::MenuItemFolder: return YES; } @@ -160,7 +144,6 @@ - (BOOL)supportsEditing { switch (self.type) { - case bookmarks::MenuItemAll: case bookmarks::MenuItemFolder: return YES; case bookmarks::MenuItemDivider: @@ -181,7 +164,6 @@ switch (self.type) { case bookmarks::MenuItemDivider: - case bookmarks::MenuItemAll: return YES; case bookmarks::MenuItemFolder: return self.folder == otherMenuItem.folder; @@ -203,7 +185,6 @@ - (NSUInteger)hash { switch (self.type) { case bookmarks::MenuItemDivider: - case bookmarks::MenuItemAll: return self.type; case bookmarks::MenuItemFolder: return self.type + reinterpret_cast<NSUInteger>(self.folder); @@ -212,12 +193,6 @@ } } -+ (BookmarkMenuItem*)allMenuItem { - BookmarkMenuItem* item = [[[BookmarkMenuItem alloc] init] autorelease]; - item.type = bookmarks::MenuItemAll; - return item; -} - + (BookmarkMenuItem*)dividerMenuItem { BookmarkMenuItem* item = [[[BookmarkMenuItem alloc] init] autorelease]; item.type = bookmarks::MenuItemDivider;
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_menu_view.mm b/ios/chrome/browser/ui/bookmarks/bookmark_menu_view.mm index bee854ae..680ec47 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_menu_view.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_menu_view.mm
@@ -137,18 +137,12 @@ [[NSMutableArray alloc] init]); [self.menuItems addObject:topSection]; - if (experimental_flags::IsAllBookmarksEnabled()) { - // All Items is always visible. - [topSection addObject:[BookmarkMenuItem allMenuItem]]; - } - // Bookmarks Bar, Mobile Bookmarks and Other Bookmarks are special folders and - // are shown at the top if they contain anything. - if (!mobileBookmarks->empty() || - !experimental_flags::IsAllBookmarksEnabled()) { - [topSection - addObject:[BookmarkMenuItem folderMenuItemForNode:mobileBookmarks - rootAncestor:mobileBookmarks]]; - } + // Mobile bookmark is shown even if empty. + [topSection + addObject:[BookmarkMenuItem folderMenuItemForNode:mobileBookmarks + rootAncestor:mobileBookmarks]]; + // Bookmarks Bar and Other Bookmarks are special folders and are shown at the + // top if they contain anything. if (!bookmarkBar->empty()) { [topSection addObject:[BookmarkMenuItem folderMenuItemForNode:bookmarkBar rootAncestor:bookmarkBar]]; @@ -268,15 +262,6 @@ return; } - if (node == self.primaryMenuItem.rootAncestor) { - // The deleted node is the root node of the current selected folder. Move to - // all items. - self.primaryMenuItem = [BookmarkMenuItem allMenuItem]; - [self.delegate bookmarkMenuView:self selectedMenuItem:self.primaryMenuItem]; - [self reloadData]; - return; - } - const BookmarkNode* root = RootLevelFolderForNode(parentFolder, self.bookmarkModel); @@ -400,8 +385,7 @@ shouldProcessInkTouchesAtTouchLocation:(CGPoint)location { NSIndexPath* indexPath = [self.tableView indexPathForRowAtPoint:location]; BookmarkMenuItem* menuItem = [self menuItemAtIndexPath:indexPath]; - return menuItem.type == bookmarks::MenuItemAll || - menuItem.type == bookmarks::MenuItemFolder; + return menuItem.type == bookmarks::MenuItemFolder; } - (MDCInkView*)inkTouchController:(MDCInkTouchController*)inkTouchController
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_position_cache.h b/ios/chrome/browser/ui/bookmarks/bookmark_position_cache.h index c999f970..1eaf1f6 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_position_cache.h +++ b/ios/chrome/browser/ui/bookmarks/bookmark_position_cache.h
@@ -20,7 +20,6 @@ @property(nonatomic, assign, readonly) CGFloat position; @property(nonatomic, assign, readonly) bookmarks::MenuItemType type; -+ (BookmarkPositionCache*)cacheForMenuItemAllWithPosition:(CGFloat)position; + (BookmarkPositionCache*)cacheForMenuItemFolderWithPosition:(CGFloat)position folderId:(int64_t)folderId;
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_position_cache.mm b/ios/chrome/browser/ui/bookmarks/bookmark_position_cache.mm index 7d5e7f1..51fdd98 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_position_cache.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_position_cache.mm
@@ -43,13 +43,6 @@ #pragma mark - Public Constructors -+ (BookmarkPositionCache*)cacheForMenuItemAllWithPosition:(CGFloat)position { - return [[[BookmarkPositionCache alloc] - initWithFolderId:0 - position:position - type:bookmarks::MenuItemAll] autorelease]; -} - + (BookmarkPositionCache*)cacheForMenuItemFolderWithPosition:(CGFloat)position folderId:(int64_t)folderId { return [[[BookmarkPositionCache alloc] @@ -91,7 +84,6 @@ return NO; switch (self.type) { case bookmarks::MenuItemDivider: - case bookmarks::MenuItemAll: case bookmarks::MenuItemSectionHeader: return YES; case bookmarks::MenuItemFolder:
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_position_cache_unittest.mm b/ios/chrome/browser/ui/bookmarks/bookmark_position_cache_unittest.mm index 3085820..5c956e2 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_position_cache_unittest.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_position_cache_unittest.mm
@@ -8,16 +8,6 @@ namespace { -TEST(BookmarkPositionCacheTest, TestMenuItemAllCoding) { - BookmarkPositionCache* cache = - [BookmarkPositionCache cacheForMenuItemAllWithPosition:23.2]; - - NSData* data = [NSKeyedArchiver archivedDataWithRootObject:cache]; - BookmarkPositionCache* cache2 = - [NSKeyedUnarchiver unarchiveObjectWithData:data]; - EXPECT_NSEQ(cache, cache2); -} - TEST(BookmarkPositionCacheTest, TestMenuItemFolderCoding) { BookmarkPositionCache* cache = [BookmarkPositionCache cacheForMenuItemFolderWithPosition:1010101
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm index 4c6a27b..80b9d308 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm
@@ -626,9 +626,6 @@ cacheForMenuItemFolderWithPosition:position folderId:item.folder->id()]; break; - case bookmarks::MenuItemAll: - cache = [BookmarkPositionCache cacheForMenuItemAllWithPosition:position]; - break; case bookmarks::MenuItemDivider: case bookmarks::MenuItemSectionHeader: NOTREACHED(); @@ -659,11 +656,6 @@ return NO; switch (cache.type) { - case bookmarks::MenuItemAll: - if (!experimental_flags::IsAllBookmarksEnabled()) - return NO; - *item = [BookmarkMenuItem allMenuItem]; - break; case bookmarks::MenuItemFolder: { const BookmarkNode* bookmark = FindFolderById(model, cache.folderId); if (!bookmark)
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm index 841affa..d9ec4ef 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm
@@ -178,29 +178,17 @@ } TEST_F(BookmarkIOSUtilsUnitTest, TestPositionCache) { - // Try to store and retrieve a cache for the allMenuItem. - BookmarkMenuItem* item = [BookmarkMenuItem allMenuItem]; - CGFloat position = 23; - bookmark_utils_ios::CachePosition(position, item); - CGFloat outPosition; - BookmarkMenuItem* outItem; - BOOL result = bookmark_utils_ios::GetPositionCache(_bookmarkModel, &outItem, - &outPosition); - if (experimental_flags::IsAllBookmarksEnabled()) { - ASSERT_TRUE(result); - EXPECT_NSEQ(item, outItem); - EXPECT_NEAR(position, outPosition, 0.01); - } else { - ASSERT_FALSE(result); - } - // Try to store and retrieve a cache for the folderMenuItem. const BookmarkNode* mobileNode = _bookmarkModel->mobile_node(); const BookmarkNode* f1 = AddFolder(mobileNode, @"f1"); - item = [BookmarkMenuItem folderMenuItemForNode:f1 rootAncestor:NULL]; + BookmarkMenuItem* item = + [BookmarkMenuItem folderMenuItemForNode:f1 rootAncestor:NULL]; + CGFloat position = 23; bookmark_utils_ios::CachePosition(position, item); - result = bookmark_utils_ios::GetPositionCache(_bookmarkModel, &outItem, - &outPosition); + BookmarkMenuItem* outItem = nil; + CGFloat outPosition; + BOOL result = bookmark_utils_ios::GetPositionCache(_bookmarkModel, &outItem, + &outPosition); ASSERT_TRUE(result); EXPECT_NSEQ(item, outItem); EXPECT_NEAR(position, outPosition, 0.01);
diff --git a/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm b/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm index f39f7ad..64d09643 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm
@@ -1005,11 +1005,7 @@ [[self class] removeBookmarkWithTitle:@"Folder 1"]; NSString* rootFolderTitle = nil; - if (experimental_flags::IsAllBookmarksEnabled()) { - rootFolderTitle = @"Bookmarks"; - } else { - rootFolderTitle = @"Mobile Bookmarks"; - } + rootFolderTitle = @"Mobile Bookmarks"; // Folder 2 and 3 are now deleted, UI should have moved to top level folder. [[EarlGrey @@ -1028,10 +1024,6 @@ // Test that the root folder is selected in the menu. This is only the case // on iPhone. - if (experimental_flags::IsAllBookmarksEnabled()) { - rootFolderTitle = @"All Bookmarks"; - } - GREYElementMatcherBlock* selectedMatcher = [GREYElementMatcherBlock matcherWithMatchesBlock:^BOOL(id element) { UITableViewCell* cell = (UITableViewCell*)element; @@ -1301,11 +1293,7 @@ // Navigates to the bookmark manager UI, and selects the top level folder. + (void)openTopLevelBookmarksFolder { - if (experimental_flags::IsAllBookmarksEnabled()) { - [BookmarksTestCase openBookmarkFolder:@"All Bookmarks"]; - } else { - [BookmarksTestCase openMobileBookmarks]; - } + [BookmarksTestCase openMobileBookmarks]; } // Navigates to the bookmark manager UI, and selects MobileBookmarks.
diff --git a/ios/chrome/browser/ui/bookmarks/resources/bookmark_blue_star.png b/ios/chrome/browser/ui/bookmarks/resources/bookmark_blue_star.png deleted file mode 100644 index c50e4bf..0000000 --- a/ios/chrome/browser/ui/bookmarks/resources/bookmark_blue_star.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/bookmarks/resources/bookmark_blue_star@2x.png b/ios/chrome/browser/ui/bookmarks/resources/bookmark_blue_star@2x.png deleted file mode 100644 index f64258e..0000000 --- a/ios/chrome/browser/ui/bookmarks/resources/bookmark_blue_star@2x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/bookmarks/resources/bookmark_blue_star@3x.png b/ios/chrome/browser/ui/bookmarks/resources/bookmark_blue_star@3x.png deleted file mode 100644 index aaee784..0000000 --- a/ios/chrome/browser/ui/bookmarks/resources/bookmark_blue_star@3x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/bookmarks/resources/bookmark_gray_star.png b/ios/chrome/browser/ui/bookmarks/resources/bookmark_gray_star.png deleted file mode 100644 index b623b08d1..0000000 --- a/ios/chrome/browser/ui/bookmarks/resources/bookmark_gray_star.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/bookmarks/resources/bookmark_gray_star@2x.png b/ios/chrome/browser/ui/bookmarks/resources/bookmark_gray_star@2x.png deleted file mode 100644 index e295f56..0000000 --- a/ios/chrome/browser/ui/bookmarks/resources/bookmark_gray_star@2x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/bookmarks/resources/bookmark_gray_star@3x.png b/ios/chrome/browser/ui/bookmarks/resources/bookmark_gray_star@3x.png deleted file mode 100644 index 993dfd2..0000000 --- a/ios/chrome/browser/ui/bookmarks/resources/bookmark_gray_star@3x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm index d00a200..f662304 100644 --- a/ios/chrome/browser/ui/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -4400,6 +4400,7 @@ _contentSuggestionsCoordinator.reset([[ContentSuggestionsCoordinator alloc] initWithBaseViewController:self]); } + [_contentSuggestionsCoordinator setBrowserState:_browserState]; [_contentSuggestionsCoordinator start]; }
diff --git a/ios/chrome/browser/ui/content_suggestions/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/BUILD.gn index c35d965..0479d04 100644 --- a/ios/chrome/browser/ui/content_suggestions/BUILD.gn +++ b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
@@ -5,11 +5,15 @@ source_set("content_suggestions") { configs += [ "//build/config/compiler:enable_arc" ] sources = [ + "content_suggestion.h", + "content_suggestion.mm", "content_suggestions_article_item.h", "content_suggestions_article_item.mm", "content_suggestions_collection_updater.h", "content_suggestions_collection_updater.mm", "content_suggestions_commands.h", + "content_suggestions_data_sink.h", + "content_suggestions_data_source.h", "content_suggestions_expandable_item.h", "content_suggestions_expandable_item.mm", "content_suggestions_favicon_internal_cell.h",
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestion.h b/ios/chrome/browser/ui/content_suggestions/content_suggestion.h new file mode 100644 index 0000000..68bcf1b --- /dev/null +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestion.h
@@ -0,0 +1,18 @@ +// 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 IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTION_H_ +#define IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTION_H_ + +#import <UIKit/UIKit.h> + +// Data for a suggestions item, compatible with Objective-C. +@interface ContentSuggestion : NSObject + +@property(nonatomic, copy) NSString* title; +@property(nonatomic, strong) UIImage* image; + +@end + +#endif // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTION_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestion.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestion.mm new file mode 100644 index 0000000..0d25178 --- /dev/null +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestion.mm
@@ -0,0 +1,16 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/content_suggestions/content_suggestion.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@implementation ContentSuggestion + +@synthesize title = _title; +@synthesize image = _image; + +@end
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.h index b453f17..29615fd 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.h +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.h
@@ -9,6 +9,7 @@ #import "ios/chrome/browser/ui/collection_view/collection_view_model.h" +@protocol ContentSuggestionsDataSource; @class ContentSuggestionsViewController; // Enum defining the ItemType of this ContentSuggestionsCollectionUpdater. @@ -24,6 +25,12 @@ // handling the items addition. @interface ContentSuggestionsCollectionUpdater : NSObject +// Initialize with the |dataSource| used to get the data. +- (instancetype)initWithDataSource:(id<ContentSuggestionsDataSource>)dataSource + NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + // |collectionViewController| this Updater will update. Needs to be set before // adding items. @property(nonatomic, assign)
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm index 6ba3bf0d..68c32ab 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm
@@ -9,6 +9,8 @@ #import "ios/chrome/browser/ui/collection_view/collection_view_controller.h" #import "ios/chrome/browser/ui/collection_view/collection_view_model.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_article_item.h" +#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_data_sink.h" +#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_data_source.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_expandable_item.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_favicon_item.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_item.h" @@ -19,9 +21,26 @@ #error "This file requires ARC support." #endif +@interface ContentSuggestionsCollectionUpdater ()<ContentSuggestionsDataSink> + +@property(nonatomic, weak) id<ContentSuggestionsDataSource> dataSource; + +@end + @implementation ContentSuggestionsCollectionUpdater @synthesize collectionViewController = _collectionViewController; +@synthesize dataSource = _dataSource; + +- (instancetype)initWithDataSource: + (id<ContentSuggestionsDataSource>)dataSource { + self = [super init]; + if (self) { + _dataSource = dataSource; + _dataSource.dataSink = self; + } + return self; +} #pragma mark - Properties @@ -30,6 +49,10 @@ _collectionViewController = collectionViewController; [collectionViewController loadModel]; CollectionViewModel* model = collectionViewController.collectionViewModel; + + // TODO(crbug.com/686728): Load the data with the dataSource instead of hard + // coded value. + NSInteger sectionIdentifier = kSectionIdentifierEnumZero; // Stack Item. @@ -88,6 +111,12 @@ } } +#pragma mark - ContentSuggestionsDataSink + +- (void)dataAvailable { + // TODO(crbug.com/686728): Get the new data from the DataSource. +} + #pragma mark - Public methods - (void)addTextItem:(NSString*)title
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_data_sink.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_data_sink.h new file mode 100644 index 0000000..ebf8bfa --- /dev/null +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_data_sink.h
@@ -0,0 +1,17 @@ +// 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 IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_DATA_SINK_H_ +#define IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_DATA_SINK_H_ + +// Data sink for the ContentSuggestions. It will be notified when new data needs +// to be pulled. +@protocol ContentSuggestionsDataSink + +// Notifies the Data Sink that new data is available. +- (void)dataAvailable; + +@end + +#endif // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_DATA_SINK_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_data_source.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_data_source.h new file mode 100644 index 0000000..39eff1cc --- /dev/null +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_data_source.h
@@ -0,0 +1,24 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_DATA_SOURCE_H_ +#define IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_DATA_SOURCE_H_ + +@class ContentSuggestion; +@protocol ContentSuggestionsDataSink; + +// DataSource for the content suggestions. Provides the suggestions data in a +// format compatible with Objective-C. +@protocol ContentSuggestionsDataSource + +// The data sink that will be notified when the data change. +@property(nonatomic, weak) id<ContentSuggestionsDataSink> dataSink; + +// Returns all the data currently available. Returns an empty array if nothing +// is available. +- (NSArray<ContentSuggestion*>*)allSuggestions; + +@end + +#endif // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_DATA_SOURCE_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h index df6a46d..b078851e 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h
@@ -12,12 +12,20 @@ #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_favicon_item.h" @protocol ContentSuggestionsCommands; +@protocol ContentSuggestionsDataSource; // CollectionViewController to display the suggestions items. @interface ContentSuggestionsViewController : CollectionViewController<ContentSuggestionsExpandableCellDelegate, ContentSuggestionsFaviconCellDelegate> +- (instancetype)initWithStyle:(CollectionViewControllerStyle)style + dataSource:(id<ContentSuggestionsDataSource>)dataSource + NS_DESIGNATED_INITIALIZER; + +- (instancetype)initWithStyle:(CollectionViewControllerStyle)style + NS_UNAVAILABLE; + // Handler for the commands sent by the ContentSuggestionsViewController. @property(nonatomic, weak) id<ContentSuggestionsCommands> suggestionCommandHandler;
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm index 3b82cd53..f7d7440 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
@@ -40,12 +40,21 @@ @synthesize suggestionCommandHandler = _suggestionCommandHandler; @synthesize collectionUpdater = _collectionUpdater; +- (instancetype)initWithStyle:(CollectionViewControllerStyle)style + dataSource:(id<ContentSuggestionsDataSource>)dataSource { + self = [super initWithStyle:style]; + if (self) { + _collectionUpdater = [[ContentSuggestionsCollectionUpdater alloc] + initWithDataSource:dataSource]; + } + return self; +} + #pragma mark - UIViewController - (void)viewDidLoad { [super viewDidLoad]; - _collectionUpdater = [[ContentSuggestionsCollectionUpdater alloc] init]; _collectionUpdater.collectionViewController = self; self.collectionView.delegate = self;
diff --git a/ios/public/provider/chrome/browser/native_app_launcher/fake_native_app_whitelist_manager.h b/ios/public/provider/chrome/browser/native_app_launcher/fake_native_app_whitelist_manager.h index 9ea2dcb..61fc53ef 100644 --- a/ios/public/provider/chrome/browser/native_app_launcher/fake_native_app_whitelist_manager.h +++ b/ios/public/provider/chrome/browser/native_app_launcher/fake_native_app_whitelist_manager.h
@@ -12,7 +12,7 @@ // Fake NativeAppWhitelistManager used for testing purposes. @interface FakeNativeAppWhitelistManager : NSObject<NativeAppWhitelistManager> -// The metadata returned by calls to |newNativeAppForURL:|. +// The metadata returned by calls to |nativeAppForURL:|. @property(nonatomic, strong, readwrite) id<NativeAppMetadata> metadata; // The Apps array returned by calls to |filteredAppsUsingBlock:|.
diff --git a/ios/public/provider/chrome/browser/native_app_launcher/fake_native_app_whitelist_manager.mm b/ios/public/provider/chrome/browser/native_app_launcher/fake_native_app_whitelist_manager.mm index 5f552b7..eaabe3d 100644 --- a/ios/public/provider/chrome/browser/native_app_launcher/fake_native_app_whitelist_manager.mm +++ b/ios/public/provider/chrome/browser/native_app_launcher/fake_native_app_whitelist_manager.mm
@@ -23,7 +23,7 @@ _appWhitelist = appList; } -- (id<NativeAppMetadata>)newNativeAppForURL:(const GURL&)url { +- (id<NativeAppMetadata>)nativeAppForURL:(const GURL&)url { return _metadata; }
diff --git a/ios/public/provider/chrome/browser/native_app_launcher/native_app_whitelist_manager.h b/ios/public/provider/chrome/browser/native_app_launcher/native_app_whitelist_manager.h index 071ffb9..e846741 100644 --- a/ios/public/provider/chrome/browser/native_app_launcher/native_app_whitelist_manager.h +++ b/ios/public/provider/chrome/browser/native_app_launcher/native_app_whitelist_manager.h
@@ -23,10 +23,9 @@ tldList:(NSArray*)tldList acceptStoreIDs:(NSArray*)storeIDs; -// Returns a new object with the metadata about the iOS native application that -// can handle |url|. Returns nil otherwise. Caller owns the returned object -// and needs to release it when done. -- (id<NativeAppMetadata>)newNativeAppForURL:(const GURL&)url; +// Returns an object with the metadata about the iOS native application that +// can handle |url|. Returns nil otherwise. +- (id<NativeAppMetadata>)nativeAppForURL:(const GURL&)url; // Returns an autoreleased NSArray of NativeAppMetadata objects which // |condition| block returns YES.
diff --git a/ios/showcase/suggestions/sc_suggestions_coordinator.mm b/ios/showcase/suggestions/sc_suggestions_coordinator.mm index e014083..332795c 100644 --- a/ios/showcase/suggestions/sc_suggestions_coordinator.mm +++ b/ios/showcase/suggestions/sc_suggestions_coordinator.mm
@@ -34,7 +34,8 @@ self.alerter.baseViewController = self.baseViewController; _suggestionViewController = [[ContentSuggestionsViewController alloc] - initWithStyle:CollectionViewControllerStyleDefault]; + initWithStyle:CollectionViewControllerStyleDefault + dataSource:nil]; _suggestionViewController.suggestionCommandHandler = reinterpret_cast<id<ContentSuggestionsCommands>>(self.alerter);
diff --git a/ios/web/net/request_tracker_impl.mm b/ios/web/net/request_tracker_impl.mm index b6ac91c..7ffccb9 100644 --- a/ios/web/net/request_tracker_impl.mm +++ b/ios/web/net/request_tracker_impl.mm
@@ -416,6 +416,16 @@ // static void RequestTrackerImpl::BlockUntilTrackersShutdown() { DCHECK_CURRENTLY_ON(web::WebThread::UI); + // Initialize the globals as part of the shutdown to prevent a crash when + // trying to acquire the lock if it was never initialised. It can happen + // if the application is terminated when no RequestTracker has been created + // (which can happen if no UIWebView has been created). See crbug.com/684611 + // for information on such a crash. + // + // As RequestTracker are deprecated and are only used in Sign-In workflow + // it is simpler to just do the initialisation here than tracking whether + // the method should be called or not by client code. + pthread_once(&g_once_control, &InitializeGlobals); { base::AutoLock scoped_lock(*g_waiting_on_io_thread_lock); g_waiting_on_io_thread = true;
diff --git a/ios/web/shell/test/context_menu_egtest.mm b/ios/web/shell/test/context_menu_egtest.mm index bb8fbfbf..ddd7895 100644 --- a/ios/web/shell/test/context_menu_egtest.mm +++ b/ios/web/shell/test/context_menu_egtest.mm
@@ -9,6 +9,7 @@ #import "base/ios/block_types.h" #include "base/strings/sys_string_conversions.h" +#import "ios/testing/earl_grey/disabled_test_macros.h" #import "ios/testing/earl_grey/matchers.h" #import "ios/web/public/test/http_server.h" #include "ios/web/public/test/http_server_util.h" @@ -35,6 +36,11 @@ // Tests context menu appears on a regular link. - (void)testContextMenu { +// TODO(crbug.com/687546): Tests disabled on devices. +#if !TARGET_IPHONE_SIMULATOR + EARL_GREY_TEST_DISABLED(@"Disabled for devices because it is very flaky."); +#endif + // Create map of canned responses and set up the test HTML server. std::map<GURL, std::string> responses; GURL initialURL = web::test::HttpServer::MakeUrl("http://contextMenuOpen");
diff --git a/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc b/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc index b30b3e6ac..1d9f95cd 100644 --- a/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc +++ b/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc
@@ -120,9 +120,7 @@ #if defined(__i386__) || defined(__arm__) || defined(__mips__) case __NR_lstat64: #endif -#if defined(__i386__) || defined(__arm__) || defined(__x86_64__) case __NR_memfd_create: -#endif case __NR_mkdirat: case __NR_mknodat: #if defined(__i386__)
diff --git a/sandbox/linux/system_headers/arm64_linux_syscalls.h b/sandbox/linux/system_headers/arm64_linux_syscalls.h index 8acb2d1..59d0eab8 100644 --- a/sandbox/linux/system_headers/arm64_linux_syscalls.h +++ b/sandbox/linux/system_headers/arm64_linux_syscalls.h
@@ -1059,4 +1059,8 @@ #define __NR_getrandom 278 #endif +#if !defined(__NR_memfd_create) +#define __NR_memfd_create 279 +#endif + #endif // SANDBOX_LINUX_SYSTEM_HEADERS_ARM64_LINUX_SYSCALLS_H_
diff --git a/sandbox/linux/system_headers/mips64_linux_syscalls.h b/sandbox/linux/system_headers/mips64_linux_syscalls.h index 5a179b0..90f3d1be 100644 --- a/sandbox/linux/system_headers/mips64_linux_syscalls.h +++ b/sandbox/linux/system_headers/mips64_linux_syscalls.h
@@ -1267,4 +1267,8 @@ #define __NR_getrandom (__NR_Linux + 313) #endif +#if !defined(__NR_memfd_create) +#define __NR_memfd_create (__NR_Linux + 314) +#endif + #endif // SANDBOX_LINUX_SYSTEM_HEADERS_MIPS64_LINUX_SYSCALLS_H_
diff --git a/sandbox/linux/system_headers/mips_linux_syscalls.h b/sandbox/linux/system_headers/mips_linux_syscalls.h index 819f9eb..784d6b8 100644 --- a/sandbox/linux/system_headers/mips_linux_syscalls.h +++ b/sandbox/linux/system_headers/mips_linux_syscalls.h
@@ -1429,4 +1429,8 @@ #define __NR_getrandom (__NR_Linux + 353) #endif +#if !defined(__NR_memfd_create) +#define __NR_memfd_create (__NR_Linux + 354) +#endif + #endif // SANDBOX_LINUX_SYSTEM_HEADERS_MIPS_LINUX_SYSCALLS_H_
diff --git a/skia/ext/benchmarking_canvas.cc b/skia/ext/benchmarking_canvas.cc index d66614a..3e3602d 100644 --- a/skia/ext/benchmarking_canvas.cc +++ b/skia/ext/benchmarking_canvas.cc
@@ -121,7 +121,7 @@ std::unique_ptr<base::StringValue> val( new base::StringValue(SkBlendMode_Name(mode))); - return std::move(val); + return val; } std::unique_ptr<base::Value> AsValue(SkCanvas::PointMode mode) { @@ -131,7 +131,7 @@ std::unique_ptr<base::StringValue> val( new base::StringValue(gModeStrings[mode])); - return std::move(val); + return val; } std::unique_ptr<base::Value> AsValue(const SkColorFilter& filter) { @@ -261,7 +261,7 @@ std::unique_ptr<base::StringValue> val(new base::StringValue(builder.str())); - return std::move(val); + return val; } std::unique_ptr<base::Value> AsValue(SkClipOp op) { @@ -276,7 +276,7 @@ DCHECK_LT(index, SK_ARRAY_COUNT(gOpStrings)); std::unique_ptr<base::StringValue> val( new base::StringValue(gOpStrings[index])); - return std::move(val); + return val; } std::unique_ptr<base::Value> AsValue(const SkRegion& region) {
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index de9a97cd2..f2659351 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -2378,6 +2378,8 @@ crbug.com/678346 [ Win7 Debug ] storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Pass Timeout ] crbug.com/678346 [ Win7 Debug ] storage/indexeddb/structured-clone.html [ Pass Timeout ] +crbug.com/685456 [ Win Mac ] fast/media/mq-color-gamut-picture.html [ Failure Pass ] + crbug.com/678487 http/tests/inspector/resource-tree/resource-tree-reload.html [ Failure Timeout Pass ] crbug.com/678487 virtual/mojo-loading/http/tests/inspector/resource-tree/resource-tree-reload.html [ Failure Timeout Pass ] crbug.com/678488 http/tests/inspector/search/source-frame-replace-2.html [ Timeout Pass ]
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc index 0c9669cc..f7e50974 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
@@ -282,12 +282,12 @@ // TODO: handle floats & orthogonal children. for (NGBlockNode* node = first_child_; node; node = node->NextSibling()) { Optional<MinAndMaxContentSizes> child_minmax; - if (NeedMinAndMaxContentSizesForContentContribution(*node->Style())) { + if (NeedMinAndMaxContentSizesForContentContribution(node->Style())) { child_minmax = node->ComputeMinAndMaxContentSizes(); } MinAndMaxContentSizes child_sizes = - ComputeMinAndMaxContentContribution(*node->Style(), child_minmax); + ComputeMinAndMaxContentContribution(node->Style(), child_minmax); sizes->min_content = std::max(sizes->min_content, child_sizes.min_content); sizes->max_content = std::max(sizes->max_content, child_sizes.max_content); @@ -380,7 +380,7 @@ curr_bfc_offset_.block_offset += content_size_; while (current_child_) { - EPosition position = current_child_->Style()->position(); + EPosition position = current_child_->Style().position(); if (position == AbsolutePosition || position == FixedPosition) { builder_->AddOutOfFlowChildCandidate(current_child_, GetChildSpaceOffset());
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h index 932a888..daf2b69 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
@@ -108,7 +108,7 @@ // Read-only Getters. const ComputedStyle& CurrentChildStyle() const { DCHECK(current_child_); - return *current_child_->Style(); + return current_child_->Style(); } const NGConstraintSpace& ConstraintSpace() const {
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc index 6bc68e3..e531bfd 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
@@ -116,8 +116,8 @@ NGConstraintSpace* constraint_space = NGConstraintSpaceBuilder( - FromPlatformWritingMode(Style()->getWritingMode())) - .SetTextDirection(Style()->direction()) + FromPlatformWritingMode(Style().getWritingMode())) + .SetTextDirection(Style().direction()) .ToConstraintSpace(); // TODO(cbiesinger): For orthogonal children, we need to always synthesize. @@ -126,7 +126,7 @@ NGLayoutInputNode* first_child = FirstChild(); if (!first_child || first_child->Type() == kLegacyBlock) { NGBlockLayoutAlgorithm minmax_algorithm( - layout_box_, Style(), toNGBlockNode(FirstChild()), constraint_space); + layout_box_, &Style(), toNGBlockNode(FirstChild()), constraint_space); if (minmax_algorithm.ComputeMinAndMaxContentSizes(&sizes)) return sizes; } @@ -134,7 +134,7 @@ // Have to synthesize this value. NGPhysicalFragment* physical_fragment = Layout(constraint_space); NGBoxFragment* fragment = new NGBoxFragment( - FromPlatformWritingMode(Style()->getWritingMode()), Style()->direction(), + FromPlatformWritingMode(Style().getWritingMode()), Style().direction(), toNGPhysicalBoxFragment(physical_fragment)); sizes.min_content = fragment->InlineOverflow(); @@ -142,32 +142,25 @@ // Now, redo with infinite space for max_content constraint_space = NGConstraintSpaceBuilder( - FromPlatformWritingMode(Style()->getWritingMode())) - .SetTextDirection(Style()->direction()) + FromPlatformWritingMode(Style().getWritingMode())) + .SetTextDirection(Style().direction()) .SetAvailableSize({LayoutUnit::max(), LayoutUnit()}) .SetPercentageResolutionSize({LayoutUnit(), LayoutUnit()}) .ToConstraintSpace(); physical_fragment = Layout(constraint_space); fragment = new NGBoxFragment( - FromPlatformWritingMode(Style()->getWritingMode()), Style()->direction(), + FromPlatformWritingMode(Style().getWritingMode()), Style().direction(), toNGPhysicalBoxFragment(physical_fragment)); sizes.max_content = fragment->InlineOverflow(); return sizes; } -ComputedStyle* NGBlockNode::MutableStyle() { +const ComputedStyle& NGBlockNode::Style() const { if (style_) - return style_.get(); + return *style_.get(); DCHECK(layout_box_); - return layout_box_->mutableStyle(); -} - -const ComputedStyle* NGBlockNode::Style() const { - if (style_) - return style_.get(); - DCHECK(layout_box_); - return layout_box_->style(); + return layout_box_->styleRef(); } NGBlockNode* NGBlockNode::NextSibling() { @@ -189,7 +182,7 @@ LayoutObject* child = layout_box_ ? layout_box_->slowFirstChild() : nullptr; if (child) { if (child->isInline()) { - SetFirstChild(new NGInlineNode(child, MutableStyle())); + SetFirstChild(new NGInlineNode(child, &Style())); } else { SetFirstChild(new NGBlockNode(child)); } @@ -252,7 +245,7 @@ layout_box_->setWidth(fragment_->Width()); layout_box_->setHeight(fragment_->Height()); NGBoxStrut border_and_padding = - ComputeBorders(*Style()) + ComputePadding(constraint_space, *Style()); + ComputeBorders(Style()) + ComputePadding(constraint_space, Style()); LayoutUnit intrinsic_logical_height = layout_box_->style()->isHorizontalWritingMode() ? fragment_->HeightOverflow()
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node.h b/third_party/WebKit/Source/core/layout/ng/ng_block_node.h index 28d3574..ce67407 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_node.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node.h
@@ -43,8 +43,7 @@ // using Layout with special constraint spaces. MinAndMaxContentSizes ComputeMinAndMaxContentSizes(); - const ComputedStyle* Style() const; - ComputedStyle* MutableStyle(); + const ComputedStyle& Style() const; NGLayoutInputNode* FirstChild();
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.cc index 89996db..dcb0e27 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.cc
@@ -25,18 +25,18 @@ NGBlockNode* block = toNGBlockNode(input_node); if (!block->CanUseNewLayout()) return new NGLegacyBlockLayoutAlgorithm(block, constraint_space); - const ComputedStyle* style = block->Style(); + const ComputedStyle& style = block->Style(); LayoutObject* layout_object = input_node->GetLayoutObject(); if (block->HasInlineChildren()) { NGInlineNode* child = toNGInlineNode(block->FirstChild()); - return new NGInlineLayoutAlgorithm(layout_object, style, child, + return new NGInlineLayoutAlgorithm(layout_object, &style, child, constraint_space); } NGBlockNode* child = toNGBlockNode(block->FirstChild()); // TODO(layout-ng): The break token should be passed as an argument to this // method instead of getting it from the NGBlockNode NGBreakToken* token = block->CurrentBreakToken(); - return new NGBlockLayoutAlgorithm(layout_object, style, child, + return new NGBlockLayoutAlgorithm(layout_object, &style, child, constraint_space, token); } }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc index cdbda4f8..06d90c47 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -75,7 +75,7 @@ out_of_flow_candidate_positions[position_index++]; if (IsContainingBlockForAbsoluteDescendant(container_style_, - *descendant->Style())) { + descendant->Style())) { NGLogicalOffset offset; NGFragment* fragment = LayoutDescendant(*descendant, static_position, &offset); @@ -100,21 +100,21 @@ Optional<MinAndMaxContentSizes> inline_estimate; Optional<LayoutUnit> block_estimate; - if (AbsoluteNeedsChildInlineSize(*descendant.Style())) { + if (AbsoluteNeedsChildInlineSize(descendant.Style())) { inline_estimate = descendant.ComputeMinAndMaxContentSizes(); } NGAbsolutePhysicalPosition node_position = ComputePartialAbsoluteWithChildInlineSize( - *container_space_, *descendant.Style(), static_position, + *container_space_, descendant.Style(), static_position, inline_estimate); - if (AbsoluteNeedsChildBlockSize(*descendant.Style())) { + if (AbsoluteNeedsChildBlockSize(descendant.Style())) { fragment = GenerateFragment(descendant, block_estimate, node_position); block_estimate = fragment->BlockSize(); } - ComputeFullAbsoluteWithChildBlockSize(*container_space_, *descendant.Style(), + ComputeFullAbsoluteWithChildBlockSize(*container_space_, descendant.Style(), static_position, block_estimate, &node_position);
diff --git a/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp b/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp index 43055af..85f01cb 100644 --- a/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp +++ b/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp
@@ -38,7 +38,6 @@ #include "platform/geometry/IntPoint.h" #include "platform/geometry/IntRect.h" #include "platform/graphics/GraphicsLayer.h" -#include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h" #include "platform/testing/URLTestHelpers.h" #include "public/platform/Platform.h" #include "public/platform/WebLayer.h" @@ -55,13 +54,9 @@ namespace blink { -class ScrollingCoordinatorTest : public testing::Test, - public testing::WithParamInterface<bool>, - private ScopedRootLayerScrollingForTest { +class ScrollingCoordinatorTest : public testing::Test { public: - ScrollingCoordinatorTest() - : ScopedRootLayerScrollingForTest(GetParam()), - m_baseURL("http://www.test.com/") { + ScrollingCoordinatorTest() : m_baseURL("http://www.test.com/") { m_helper.initialize(true, nullptr, &m_mockWebViewClient, nullptr, &configureSettings); webViewImpl()->resize(IntSize(320, 240)); @@ -89,11 +84,6 @@ FrameTestHelpers::loadFrame(webViewImpl()->mainFrame(), url); } - void loadHTML(const std::string& html) { - FrameTestHelpers::loadHTMLString(webViewImpl()->mainFrame(), html, - URLTestHelpers::toKURL("about:blank")); - } - void forceFullCompositingUpdate() { webViewImpl()->updateAllLifecyclePhases(); } @@ -105,9 +95,13 @@ } WebLayer* getRootScrollLayer() { - GraphicsLayer* layer = - frame()->view()->layoutViewportScrollableArea()->layerForScrolling(); - return layer ? layer->platformLayer() : nullptr; + PaintLayerCompositor* compositor = + frame()->contentLayoutItem().compositor(); + DCHECK(compositor); + DCHECK(compositor->scrollLayer()); + + WebLayer* webScrollLayer = compositor->scrollLayer()->platformLayer(); + return webScrollLayer; } WebViewImpl* webViewImpl() const { return m_helper.webView(); } @@ -119,6 +113,9 @@ return webViewImpl()->layerTreeView(); } + void styleRelatedMainThreadScrollingReasonTest(const std::string&, + const uint32_t); + protected: std::string m_baseURL; FrameTestHelpers::TestWebViewClient m_mockWebViewClient; @@ -133,11 +130,8 @@ FrameTestHelpers::WebViewHelper m_helper; }; -INSTANTIATE_TEST_CASE_P(All, ScrollingCoordinatorTest, ::testing::Bool()); - -TEST_P(ScrollingCoordinatorTest, fastScrollingByDefault) { - webViewImpl()->resize(WebSize(800, 600)); - loadHTML("<div id='spacer' style='height: 1000px'></div>"); +TEST_F(ScrollingCoordinatorTest, fastScrollingByDefault) { + navigateTo("about:blank"); forceFullCompositingUpdate(); // Make sure the scrolling coordinator is active. @@ -149,7 +143,6 @@ // Fast scrolling should be enabled by default. WebLayer* rootScrollLayer = getRootScrollLayer(); - ASSERT_TRUE(rootScrollLayer); ASSERT_TRUE(rootScrollLayer->scrollable()); ASSERT_FALSE(rootScrollLayer->shouldScrollOnMainThread()); ASSERT_EQ(WebEventListenerProperties::Nothing, @@ -165,9 +158,8 @@ ASSERT_FALSE(innerViewportScrollLayer->shouldScrollOnMainThread()); } -TEST_P(ScrollingCoordinatorTest, fastScrollingCanBeDisabledWithSetting) { - webViewImpl()->resize(WebSize(800, 600)); - loadHTML("<div id='spacer' style='height: 1000px'></div>"); +TEST_F(ScrollingCoordinatorTest, fastScrollingCanBeDisabledWithSetting) { + navigateTo("about:blank"); webViewImpl()->settings()->setThreadedScrollingEnabled(false); forceFullCompositingUpdate(); @@ -180,7 +172,6 @@ // Main scrolling should be enabled with the setting override. WebLayer* rootScrollLayer = getRootScrollLayer(); - ASSERT_TRUE(rootScrollLayer); ASSERT_TRUE(rootScrollLayer->scrollable()); ASSERT_TRUE(rootScrollLayer->shouldScrollOnMainThread()); @@ -191,7 +182,7 @@ ASSERT_TRUE(innerViewportScrollLayer->shouldScrollOnMainThread()); } -TEST_P(ScrollingCoordinatorTest, fastFractionalScrollingDiv) { +TEST_F(ScrollingCoordinatorTest, fastFractionalScrollingDiv) { bool origFractionalOffsetsEnabled = RuntimeEnabledFeatures::fractionalScrollOffsetsEnabled(); RuntimeEnabledFeatures::setFractionalScrollOffsetsEnabled(true); @@ -251,14 +242,13 @@ return graphicsLayer->platformLayer(); } -TEST_P(ScrollingCoordinatorTest, fastScrollingForFixedPosition) { +TEST_F(ScrollingCoordinatorTest, fastScrollingForFixedPosition) { registerMockedHttpURLLoad("fixed-position.html"); navigateTo(m_baseURL + "fixed-position.html"); forceFullCompositingUpdate(); // Fixed position should not fall back to main thread scrolling. WebLayer* rootScrollLayer = getRootScrollLayer(); - ASSERT_TRUE(rootScrollLayer); ASSERT_FALSE(rootScrollLayer->shouldScrollOnMainThread()); Document* document = frame()->document(); @@ -344,14 +334,13 @@ } } -TEST_P(ScrollingCoordinatorTest, fastScrollingForStickyPosition) { +TEST_F(ScrollingCoordinatorTest, fastScrollingForStickyPosition) { registerMockedHttpURLLoad("sticky-position.html"); navigateTo(m_baseURL + "sticky-position.html"); forceFullCompositingUpdate(); // Sticky position should not fall back to main thread scrolling. WebLayer* rootScrollLayer = getRootScrollLayer(); - ASSERT_TRUE(rootScrollLayer); EXPECT_FALSE(rootScrollLayer->shouldScrollOnMainThread()); Document* document = frame()->document(); @@ -451,7 +440,7 @@ } } -TEST_P(ScrollingCoordinatorTest, touchEventHandler) { +TEST_F(ScrollingCoordinatorTest, touchEventHandler) { registerMockedHttpURLLoad("touch-event-handler.html"); navigateTo(m_baseURL + "touch-event-handler.html"); forceFullCompositingUpdate(); @@ -461,7 +450,7 @@ WebEventListenerClass::TouchStartOrMove)); } -TEST_P(ScrollingCoordinatorTest, touchEventHandlerPassive) { +TEST_F(ScrollingCoordinatorTest, touchEventHandlerPassive) { registerMockedHttpURLLoad("touch-event-handler-passive.html"); navigateTo(m_baseURL + "touch-event-handler-passive.html"); forceFullCompositingUpdate(); @@ -471,7 +460,7 @@ WebEventListenerClass::TouchStartOrMove)); } -TEST_P(ScrollingCoordinatorTest, touchEventHandlerBoth) { +TEST_F(ScrollingCoordinatorTest, touchEventHandlerBoth) { registerMockedHttpURLLoad("touch-event-handler-both.html"); navigateTo(m_baseURL + "touch-event-handler-both.html"); forceFullCompositingUpdate(); @@ -481,7 +470,7 @@ WebEventListenerClass::TouchStartOrMove)); } -TEST_P(ScrollingCoordinatorTest, wheelEventHandler) { +TEST_F(ScrollingCoordinatorTest, wheelEventHandler) { registerMockedHttpURLLoad("wheel-event-handler.html"); navigateTo(m_baseURL + "wheel-event-handler.html"); forceFullCompositingUpdate(); @@ -491,7 +480,7 @@ WebEventListenerClass::MouseWheel)); } -TEST_P(ScrollingCoordinatorTest, wheelEventHandlerPassive) { +TEST_F(ScrollingCoordinatorTest, wheelEventHandlerPassive) { registerMockedHttpURLLoad("wheel-event-handler-passive.html"); navigateTo(m_baseURL + "wheel-event-handler-passive.html"); forceFullCompositingUpdate(); @@ -501,7 +490,7 @@ WebEventListenerClass::MouseWheel)); } -TEST_P(ScrollingCoordinatorTest, wheelEventHandlerBoth) { +TEST_F(ScrollingCoordinatorTest, wheelEventHandlerBoth) { registerMockedHttpURLLoad("wheel-event-handler-both.html"); navigateTo(m_baseURL + "wheel-event-handler-both.html"); forceFullCompositingUpdate(); @@ -511,7 +500,7 @@ WebEventListenerClass::MouseWheel)); } -TEST_P(ScrollingCoordinatorTest, scrollEventHandler) { +TEST_F(ScrollingCoordinatorTest, scrollEventHandler) { registerMockedHttpURLLoad("scroll-event-handler.html"); navigateTo(m_baseURL + "scroll-event-handler.html"); forceFullCompositingUpdate(); @@ -519,7 +508,7 @@ ASSERT_TRUE(webLayerTreeView()->haveScrollEventHandlers()); } -TEST_P(ScrollingCoordinatorTest, updateEventHandlersDuringTeardown) { +TEST_F(ScrollingCoordinatorTest, updateEventHandlersDuringTeardown) { registerMockedHttpURLLoad("scroll-event-handler-window.html"); navigateTo(m_baseURL + "scroll-event-handler-window.html"); forceFullCompositingUpdate(); @@ -529,17 +518,16 @@ frame()->document()->shutdown(); } -TEST_P(ScrollingCoordinatorTest, clippedBodyTest) { +TEST_F(ScrollingCoordinatorTest, clippedBodyTest) { registerMockedHttpURLLoad("clipped-body.html"); navigateTo(m_baseURL + "clipped-body.html"); forceFullCompositingUpdate(); WebLayer* rootScrollLayer = getRootScrollLayer(); - ASSERT_TRUE(rootScrollLayer); ASSERT_EQ(0u, rootScrollLayer->nonFastScrollableRegion().size()); } -TEST_P(ScrollingCoordinatorTest, overflowScrolling) { +TEST_F(ScrollingCoordinatorTest, overflowScrolling) { registerMockedHttpURLLoad("overflow-scrolling.html"); navigateTo(m_baseURL + "overflow-scrolling.html"); forceFullCompositingUpdate(); @@ -585,7 +573,7 @@ #endif } -TEST_P(ScrollingCoordinatorTest, overflowHidden) { +TEST_F(ScrollingCoordinatorTest, overflowHidden) { registerMockedHttpURLLoad("overflow-hidden.html"); navigateTo(m_baseURL + "overflow-hidden.html"); forceFullCompositingUpdate(); @@ -646,7 +634,7 @@ ASSERT_TRUE(webScrollLayer->userScrollableVertical()); } -TEST_P(ScrollingCoordinatorTest, iframeScrolling) { +TEST_F(ScrollingCoordinatorTest, iframeScrolling) { registerMockedHttpURLLoad("iframe-scrolling.html"); registerMockedHttpURLLoad("iframe-scrolling-inner.html"); navigateTo(m_baseURL + "iframe-scrolling.html"); @@ -672,12 +660,10 @@ PaintLayerCompositor* innerCompositor = innerLayoutViewItem.compositor(); ASSERT_TRUE(innerCompositor->inCompositingMode()); + ASSERT_TRUE(innerCompositor->scrollLayer()); - GraphicsLayer* scrollLayer = - innerFrameView->layoutViewportScrollableArea()->layerForScrolling(); - ASSERT_TRUE(scrollLayer); - ASSERT_EQ(innerFrameView->layoutViewportScrollableArea(), - scrollLayer->getScrollableArea()); + GraphicsLayer* scrollLayer = innerCompositor->scrollLayer(); + ASSERT_EQ(innerFrameView, scrollLayer->getScrollableArea()); WebLayer* webScrollLayer = scrollLayer->platformLayer(); ASSERT_TRUE(webScrollLayer->scrollable()); @@ -692,7 +678,7 @@ #endif } -TEST_P(ScrollingCoordinatorTest, rtlIframe) { +TEST_F(ScrollingCoordinatorTest, rtlIframe) { registerMockedHttpURLLoad("rtl-iframe.html"); registerMockedHttpURLLoad("rtl-iframe-inner.html"); navigateTo(m_baseURL + "rtl-iframe.html"); @@ -718,26 +704,21 @@ PaintLayerCompositor* innerCompositor = innerLayoutViewItem.compositor(); ASSERT_TRUE(innerCompositor->inCompositingMode()); + ASSERT_TRUE(innerCompositor->scrollLayer()); - GraphicsLayer* scrollLayer = - innerFrameView->layoutViewportScrollableArea()->layerForScrolling(); - ASSERT_TRUE(scrollLayer); - ASSERT_EQ(innerFrameView->layoutViewportScrollableArea(), - scrollLayer->getScrollableArea()); + GraphicsLayer* scrollLayer = innerCompositor->scrollLayer(); + ASSERT_EQ(innerFrameView, scrollLayer->getScrollableArea()); WebLayer* webScrollLayer = scrollLayer->platformLayer(); ASSERT_TRUE(webScrollLayer->scrollable()); int expectedScrollPosition = - 958 + (innerFrameView->layoutViewportScrollableArea() - ->verticalScrollbar() - ->isOverlayScrollbar() - ? 0 - : 15); + 958 + + (innerFrameView->verticalScrollbar()->isOverlayScrollbar() ? 0 : 15); ASSERT_EQ(expectedScrollPosition, webScrollLayer->scrollPositionDouble().x); } -TEST_P(ScrollingCoordinatorTest, setupScrollbarLayerShouldNotCrash) { +TEST_F(ScrollingCoordinatorTest, setupScrollbarLayerShouldNotCrash) { registerMockedHttpURLLoad("setup_scrollbar_layer_crash.html"); navigateTo(m_baseURL + "setup_scrollbar_layer_crash.html"); forceFullCompositingUpdate(); @@ -745,7 +726,7 @@ // an empty document by javascript. } -TEST_P(ScrollingCoordinatorTest, +TEST_F(ScrollingCoordinatorTest, scrollbarsForceMainThreadOrHaveWebScrollbarLayer) { registerMockedHttpURLLoad("trivial-scroller.html"); navigateTo(m_baseURL + "trivial-scroller.html"); @@ -772,10 +753,10 @@ } #if OS(MACOSX) || OS(ANDROID) -TEST_P(ScrollingCoordinatorTest, +TEST_F(ScrollingCoordinatorTest, DISABLED_setupScrollbarLayerShouldSetScrollLayerOpaque) #else -TEST_P(ScrollingCoordinatorTest, setupScrollbarLayerShouldSetScrollLayerOpaque) +TEST_F(ScrollingCoordinatorTest, setupScrollbarLayerShouldSetScrollLayerOpaque) #endif { registerMockedHttpURLLoad("wide_document.html"); @@ -786,7 +767,7 @@ ASSERT_TRUE(frameView); GraphicsLayer* scrollbarGraphicsLayer = - frameView->layoutViewportScrollableArea()->layerForHorizontalScrollbar(); + frameView->layerForHorizontalScrollbar(); ASSERT_TRUE(scrollbarGraphicsLayer); WebLayer* platformLayer = scrollbarGraphicsLayer->platformLayer(); @@ -801,16 +782,19 @@ ASSERT_EQ(platformLayer->opaque(), contentsLayer->opaque()); } -TEST_P(ScrollingCoordinatorTest, +TEST_F(ScrollingCoordinatorTest, FixedPositionLosingBackingShouldTriggerMainThreadScroll) { webViewImpl()->settings()->setPreferCompositingToLCDTextEnabled(false); registerMockedHttpURLLoad("fixed-position-losing-backing.html"); navigateTo(m_baseURL + "fixed-position-losing-backing.html"); forceFullCompositingUpdate(); - WebLayer* scrollLayer = getRootScrollLayer(); - ASSERT_TRUE(scrollLayer); - + WebLayer* scrollLayer = frame() + ->page() + ->deprecatedLocalMainFrame() + ->view() + ->layerForScrolling() + ->platformLayer(); Document* document = frame()->document(); Element* fixedPos = document->getElementById("fixed"); @@ -828,7 +812,7 @@ EXPECT_TRUE(scrollLayer->shouldScrollOnMainThread()); } -TEST_P(ScrollingCoordinatorTest, CustomScrollbarShouldTriggerMainThreadScroll) { +TEST_F(ScrollingCoordinatorTest, CustomScrollbarShouldTriggerMainThreadScroll) { webViewImpl()->settings()->setPreferCompositingToLCDTextEnabled(true); webViewImpl()->setDeviceScaleFactor(2.f); registerMockedHttpURLLoad("custom_scrollbar.html"); @@ -869,7 +853,7 @@ MainThreadScrollingReason::kCustomScrollbarScrolling); } -TEST_P(ScrollingCoordinatorTest, +TEST_F(ScrollingCoordinatorTest, BackgroundAttachmentFixedShouldTriggerMainThreadScroll) { registerMockedHttpURLLoad("iframe-background-attachment-fixed.html"); registerMockedHttpURLLoad("iframe-background-attachment-fixed-inner.html"); @@ -895,12 +879,10 @@ PaintLayerCompositor* innerCompositor = innerLayoutViewItem.compositor(); ASSERT_TRUE(innerCompositor->inCompositingMode()); + ASSERT_TRUE(innerCompositor->scrollLayer()); - GraphicsLayer* scrollLayer = - innerFrameView->layoutViewportScrollableArea()->layerForScrolling(); - ASSERT_TRUE(scrollLayer); - ASSERT_EQ(innerFrameView->layoutViewportScrollableArea(), - scrollLayer->getScrollableArea()); + GraphicsLayer* scrollLayer = innerCompositor->scrollLayer(); + ASSERT_EQ(innerFrameView, scrollLayer->getScrollableArea()); WebLayer* webScrollLayer = scrollLayer->platformLayer(); ASSERT_TRUE(webScrollLayer->scrollable()); @@ -919,9 +901,7 @@ layoutObject = iframe->layoutObject(); ASSERT_TRUE(layoutObject); - scrollLayer = layoutObject->frameView() - ->layoutViewportScrollableArea() - ->layerForScrolling(); + scrollLayer = layoutObject->frameView()->layerForScrolling(); ASSERT_TRUE(scrollLayer); webScrollLayer = scrollLayer->platformLayer(); @@ -942,9 +922,7 @@ layoutObject = iframe->layoutObject(); ASSERT_TRUE(layoutObject); - scrollLayer = layoutObject->frameView() - ->layoutViewportScrollableArea() - ->layerForScrolling(); + scrollLayer = layoutObject->frameView()->layerForScrolling(); ASSERT_TRUE(scrollLayer); webScrollLayer = scrollLayer->platformLayer(); @@ -955,7 +933,7 @@ // Upon resizing the content size, the main thread scrolling reason // kHasNonLayerViewportConstrainedObject should be updated on all frames -TEST_P(ScrollingCoordinatorTest, +TEST_F(ScrollingCoordinatorTest, RecalculateMainThreadScrollingReasonsUponResize) { webViewImpl()->settings()->setPreferCompositingToLCDTextEnabled(false); registerMockedHttpURLLoad("has-non-layer-viewport-constrained-objects.html"); @@ -969,23 +947,29 @@ LayoutObject* layoutObject = element->layoutObject(); ASSERT_TRUE(layoutObject); - GraphicsLayer* scrollLayer = layoutObject->frameView() - ->layoutViewportScrollableArea() - ->layerForScrolling(); - WebLayer* webScrollLayer; + GraphicsLayer* scrollLayer = layoutObject->frameView()->layerForScrolling(); + ASSERT_TRUE(scrollLayer); - if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { - // When RLS is enabled, the LayoutView won't have a scrolling contents - // because it does not overflow. - ASSERT_FALSE(scrollLayer); - } else { - ASSERT_TRUE(scrollLayer); - webScrollLayer = scrollLayer->platformLayer(); - ASSERT_TRUE(webScrollLayer->scrollable()); - ASSERT_FALSE( - webScrollLayer->mainThreadScrollingReasons() & - MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects); - } + WebLayer* webScrollLayer = scrollLayer->platformLayer(); + ASSERT_TRUE(webScrollLayer->scrollable()); + ASSERT_FALSE( + webScrollLayer->mainThreadScrollingReasons() & + MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects); + + Element* iframe = frame()->document()->getElementById("iframe"); + ASSERT_TRUE(iframe); + + layoutObject = iframe->layoutObject(); + ASSERT_TRUE(layoutObject); + + scrollLayer = layoutObject->frameView()->layerForScrolling(); + ASSERT_TRUE(scrollLayer); + + webScrollLayer = scrollLayer->platformLayer(); + ASSERT_TRUE(webScrollLayer->scrollable()); + ASSERT_FALSE( + webScrollLayer->mainThreadScrollingReasons() & + MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects); // When the div becomes to scrollable it should scroll on main thread element->setAttribute("style", @@ -996,9 +980,19 @@ layoutObject = element->layoutObject(); ASSERT_TRUE(layoutObject); - scrollLayer = layoutObject->frameView() - ->layoutViewportScrollableArea() - ->layerForScrolling(); + scrollLayer = layoutObject->frameView()->layerForScrolling(); + ASSERT_TRUE(scrollLayer); + + webScrollLayer = scrollLayer->platformLayer(); + ASSERT_TRUE(webScrollLayer->scrollable()); + ASSERT_TRUE( + webScrollLayer->mainThreadScrollingReasons() & + MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects); + + layoutObject = iframe->layoutObject(); + ASSERT_TRUE(layoutObject); + + scrollLayer = layoutObject->frameView()->layerForScrolling(); ASSERT_TRUE(scrollLayer); webScrollLayer = scrollLayer->platformLayer(); @@ -1016,21 +1010,26 @@ layoutObject = element->layoutObject(); ASSERT_TRUE(layoutObject); - scrollLayer = layoutObject->frameView() - ->layoutViewportScrollableArea() - ->layerForScrolling(); - if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { - // When RLS is enabled, the LayoutView won't have a scrolling contents - // because it does not overflow. - ASSERT_FALSE(scrollLayer); - } else { - ASSERT_TRUE(scrollLayer); - webScrollLayer = scrollLayer->platformLayer(); - ASSERT_TRUE(webScrollLayer->scrollable()); - ASSERT_FALSE( - webScrollLayer->mainThreadScrollingReasons() & - MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects); - } + scrollLayer = layoutObject->frameView()->layerForScrolling(); + ASSERT_TRUE(scrollLayer); + + webScrollLayer = scrollLayer->platformLayer(); + ASSERT_TRUE(webScrollLayer->scrollable()); + ASSERT_FALSE( + webScrollLayer->mainThreadScrollingReasons() & + MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects); + + layoutObject = iframe->layoutObject(); + ASSERT_TRUE(layoutObject); + + scrollLayer = layoutObject->frameView()->layerForScrolling(); + ASSERT_TRUE(scrollLayer); + + webScrollLayer = scrollLayer->platformLayer(); + ASSERT_TRUE(webScrollLayer->scrollable()); + ASSERT_FALSE( + webScrollLayer->mainThreadScrollingReasons() & + MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects); } class StyleRelatedMainThreadScrollingReasonTest @@ -1093,32 +1092,28 @@ } }; -INSTANTIATE_TEST_CASE_P(All, - StyleRelatedMainThreadScrollingReasonTest, - ::testing::Bool()); - -TEST_P(StyleRelatedMainThreadScrollingReasonTest, TransparentTest) { +TEST_F(StyleRelatedMainThreadScrollingReasonTest, TransparentTest) { testStyle("transparent", MainThreadScrollingReason::kHasOpacityAndLCDText); } -TEST_P(StyleRelatedMainThreadScrollingReasonTest, TransformTest) { +TEST_F(StyleRelatedMainThreadScrollingReasonTest, TransformTest) { testStyle("transform", MainThreadScrollingReason::kHasTransformAndLCDText); } -TEST_P(StyleRelatedMainThreadScrollingReasonTest, BackgroundNotOpaqueTest) { +TEST_F(StyleRelatedMainThreadScrollingReasonTest, BackgroundNotOpaqueTest) { testStyle("background-not-opaque", MainThreadScrollingReason::kBackgroundNotOpaqueInRectAndLCDText); } -TEST_P(StyleRelatedMainThreadScrollingReasonTest, BorderRadiusTest) { +TEST_F(StyleRelatedMainThreadScrollingReasonTest, BorderRadiusTest) { testStyle("border-radius", MainThreadScrollingReason::kHasBorderRadius); } -TEST_P(StyleRelatedMainThreadScrollingReasonTest, ClipTest) { +TEST_F(StyleRelatedMainThreadScrollingReasonTest, ClipTest) { testStyle("clip", MainThreadScrollingReason::kHasClipRelatedProperty); } -TEST_P(StyleRelatedMainThreadScrollingReasonTest, ClipPathTest) { +TEST_F(StyleRelatedMainThreadScrollingReasonTest, ClipPathTest) { uint32_t reason = MainThreadScrollingReason::kHasClipRelatedProperty; webViewImpl()->settings()->setPreferCompositingToLCDTextEnabled(false); Document* document = frame()->document(); @@ -1153,13 +1148,13 @@ ASSERT_FALSE(frameView->mainThreadScrollingReasons() & reason); } -TEST_P(StyleRelatedMainThreadScrollingReasonTest, LCDTextEnabledTest) { +TEST_F(StyleRelatedMainThreadScrollingReasonTest, LCDTextEnabledTest) { testStyle("transparent border-radius", MainThreadScrollingReason::kHasOpacityAndLCDText | MainThreadScrollingReason::kHasBorderRadius); } -TEST_P(StyleRelatedMainThreadScrollingReasonTest, BoxShadowTest) { +TEST_F(StyleRelatedMainThreadScrollingReasonTest, BoxShadowTest) { testStyle("box-shadow", MainThreadScrollingReason::kHasBoxShadowFromNonRootLayer); }
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp index bc04711ad..d123a03 100644 --- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -7761,16 +7761,6 @@ webViewHelper.resize(WebSize(viewportWidth, viewportHeight)); webViewImpl->updateAllLifecyclePhases(); - WebLayer* webScrollLayer = webViewImpl->mainFrameImpl() - ->frame() - ->view() - ->layoutViewportScrollableArea() - ->layerForScrolling() - ->platformLayer(); - ASSERT_TRUE(webScrollLayer->scrollable()); - ASSERT_TRUE(webScrollLayer->userScrollableHorizontal()); - ASSERT_TRUE(webScrollLayer->userScrollableVertical()); - Document* document = webViewImpl->mainFrameImpl()->frame()->document(); UserGestureIndicator gesture(DocumentUserGestureToken::create(document)); Fullscreen::requestFullscreen(*document->documentElement()); @@ -7790,12 +7780,8 @@ Fullscreen::fullscreenElementFrom(*document)); // Verify that the main frame is still scrollable. - webScrollLayer = webViewImpl->mainFrameImpl() - ->frame() - ->view() - ->layoutViewportScrollableArea() - ->layerForScrolling() - ->platformLayer(); + WebLayer* webScrollLayer = + webViewImpl->compositor()->scrollLayer()->platformLayer(); ASSERT_TRUE(webScrollLayer->scrollable()); ASSERT_TRUE(webScrollLayer->userScrollableHorizontal()); ASSERT_TRUE(webScrollLayer->userScrollableVertical());
diff --git a/third_party/WebKit/Source/web/tests/data/has-non-layer-viewport-constrained-objects.html b/third_party/WebKit/Source/web/tests/data/has-non-layer-viewport-constrained-objects.html index f2919be..50796f6 100644 --- a/third_party/WebKit/Source/web/tests/data/has-non-layer-viewport-constrained-objects.html +++ b/third_party/WebKit/Source/web/tests/data/has-non-layer-viewport-constrained-objects.html
@@ -1,2 +1,4 @@ <div style="position:fixed;">Fixed obj</div> -<div id="scrollable" style="overflow: scroll; height:200px; will-change:transform;"></div> +<div id="scrollable" style="overflow: scroll; height:200px; will-change:transform;"> + <iframe id="iframe"></iframe> +</div>
diff --git a/third_party/WebKit/Source/web/tests/data/iframe-background-attachment-fixed-inner.html b/third_party/WebKit/Source/web/tests/data/iframe-background-attachment-fixed-inner.html index 5dc4b2d..38843967 100644 --- a/third_party/WebKit/Source/web/tests/data/iframe-background-attachment-fixed-inner.html +++ b/third_party/WebKit/Source/web/tests/data/iframe-background-attachment-fixed-inner.html
@@ -3,7 +3,8 @@ .background-attachment-fixed { background-image: url("white-1x1.png"); background-attachment: fixed; + height: 2000px; } </style> -<div id="scrollable" style="will-change:transform; height: 2000px;" class="background-attachment-fixed" /> +<div id="scrollable" style="will-change:transform;" class="background-attachment-fixed" />
diff --git a/third_party/libaddressinput/chromium/chrome_storage_impl.cc b/third_party/libaddressinput/chromium/chrome_storage_impl.cc index e901c2f..4daab33 100644 --- a/third_party/libaddressinput/chromium/chrome_storage_impl.cc +++ b/third_party/libaddressinput/chromium/chrome_storage_impl.cc
@@ -7,6 +7,7 @@ #include <memory> #include <utility> +#include "base/memory/ptr_util.h" #include "base/values.h" #include "components/prefs/writeable_pref_store.h" #include "third_party/libaddressinput/chromium/fallback_data_store.h" @@ -24,11 +25,9 @@ void ChromeStorageImpl::Put(const std::string& key, std::string* data) { DCHECK(data); std::unique_ptr<std::string> owned_data(data); - std::unique_ptr<base::StringValue> string_value( - new base::StringValue(std::string())); - string_value->GetString()->swap(*owned_data); - backing_store_->SetValue(key, std::move(string_value), - WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); + backing_store_->SetValue( + key, base::MakeUnique<base::StringValue>(std::move(*owned_data)), + WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); } void ChromeStorageImpl::Get(const std::string& key,