diff --git a/cc/paint/paint_op_buffer.cc b/cc/paint/paint_op_buffer.cc index 6f75cc7..e566c3b 100644 --- a/cc/paint/paint_op_buffer.cc +++ b/cc/paint/paint_op_buffer.cc
@@ -336,7 +336,10 @@ const SerializeOptions& options) { auto* op = static_cast<const DrawDRRectOp*>(base_op); PaintOpWriter helper(memory, size); - helper.Write(op->flags); + const auto* serialized_flags = options.flags_to_serialize; + if (!serialized_flags) + serialized_flags = &op->flags; + helper.Write(*serialized_flags); helper.Write(op->outer); helper.Write(op->inner); return helper.size(); @@ -348,7 +351,10 @@ const SerializeOptions& options) { auto* op = static_cast<const DrawImageOp*>(base_op); PaintOpWriter helper(memory, size); - helper.Write(op->flags); + const auto* serialized_flags = options.flags_to_serialize; + if (!serialized_flags) + serialized_flags = &op->flags; + helper.Write(*serialized_flags); helper.Write(op->image, options.image_provider); helper.Write(op->left); helper.Write(op->top); @@ -361,7 +367,10 @@ const SerializeOptions& options) { auto* op = static_cast<const DrawImageRectOp*>(base_op); PaintOpWriter helper(memory, size); - helper.Write(op->flags); + const auto* serialized_flags = options.flags_to_serialize; + if (!serialized_flags) + serialized_flags = &op->flags; + helper.Write(*serialized_flags); helper.Write(op->image, options.image_provider); helper.Write(op->src); helper.Write(op->dst); @@ -375,7 +384,10 @@ const SerializeOptions& options) { auto* op = static_cast<const DrawIRectOp*>(base_op); PaintOpWriter helper(memory, size); - helper.Write(op->flags); + const auto* serialized_flags = options.flags_to_serialize; + if (!serialized_flags) + serialized_flags = &op->flags; + helper.Write(*serialized_flags); helper.Write(op->rect); return helper.size(); } @@ -386,7 +398,10 @@ const SerializeOptions& options) { auto* op = static_cast<const DrawLineOp*>(base_op); PaintOpWriter helper(memory, size); - helper.Write(op->flags); + const auto* serialized_flags = options.flags_to_serialize; + if (!serialized_flags) + serialized_flags = &op->flags; + helper.Write(*serialized_flags); helper.Write(op->x0); helper.Write(op->y0); helper.Write(op->x1); @@ -400,7 +415,10 @@ const SerializeOptions& options) { auto* op = static_cast<const DrawOvalOp*>(base_op); PaintOpWriter helper(memory, size); - helper.Write(op->flags); + const auto* serialized_flags = options.flags_to_serialize; + if (!serialized_flags) + serialized_flags = &op->flags; + helper.Write(*serialized_flags); helper.Write(op->oval); return helper.size(); } @@ -411,7 +429,10 @@ const SerializeOptions& options) { auto* op = static_cast<const DrawPathOp*>(base_op); PaintOpWriter helper(memory, size); - helper.Write(op->flags); + const auto* serialized_flags = options.flags_to_serialize; + if (!serialized_flags) + serialized_flags = &op->flags; + helper.Write(*serialized_flags); helper.Write(op->path); return helper.size(); } @@ -432,7 +453,10 @@ const SerializeOptions& options) { auto* op = static_cast<const DrawRectOp*>(base_op); PaintOpWriter helper(memory, size); - helper.Write(op->flags); + const auto* serialized_flags = options.flags_to_serialize; + if (!serialized_flags) + serialized_flags = &op->flags; + helper.Write(*serialized_flags); helper.Write(op->rect); return helper.size(); } @@ -443,7 +467,10 @@ const SerializeOptions& options) { auto* op = static_cast<const DrawRRectOp*>(base_op); PaintOpWriter helper(memory, size); - helper.Write(op->flags); + const auto* serialized_flags = options.flags_to_serialize; + if (!serialized_flags) + serialized_flags = &op->flags; + helper.Write(*serialized_flags); helper.Write(op->rrect); return helper.size(); } @@ -454,7 +481,10 @@ const SerializeOptions& options) { auto* op = static_cast<const DrawTextBlobOp*>(base_op); PaintOpWriter helper(memory, size); - helper.Write(op->flags); + const auto* serialized_flags = options.flags_to_serialize; + if (!serialized_flags) + serialized_flags = &op->flags; + helper.Write(*serialized_flags); helper.Write(op->x); helper.Write(op->y); helper.Write(op->blob); @@ -495,7 +525,10 @@ const SerializeOptions& options) { auto* op = static_cast<const SaveLayerOp*>(base_op); PaintOpWriter helper(memory, size); - helper.Write(op->flags); + const auto* serialized_flags = options.flags_to_serialize; + if (!serialized_flags) + serialized_flags = &op->flags; + helper.Write(*serialized_flags); helper.Write(op->bounds); return helper.size(); } @@ -1585,6 +1618,11 @@ return g_equals_operator[type](this, &other); } +// static +bool PaintOp::TypeHasFlags(PaintOpType type) { + return g_has_paint_flags[static_cast<uint8_t>(type)]; +} + void PaintOp::Raster(SkCanvas* canvas, const PlaybackParams& params) const { g_raster_functions[type](this, canvas, params); } @@ -2094,7 +2132,6 @@ if (op->IsPaintOpWithFlags()) { const auto* flags_op = static_cast<const PaintOpWithFlags*>(op); - base::Optional<ScopedImageFlags> scoped_flags; const bool needs_flag_override = iter.alpha() != 255 ||
diff --git a/cc/paint/paint_op_buffer.h b/cc/paint/paint_op_buffer.h index d0aa90d..eb34cdce 100644 --- a/cc/paint/paint_op_buffer.h +++ b/cc/paint/paint_op_buffer.h
@@ -123,6 +123,9 @@ ImageProvider* image_provider = nullptr; SkCanvas* canvas = nullptr; SkMatrix original_ctm = SkMatrix::I(); + // The flags to use when serializing this op. This can be used to override + // the flags serialized with the op. Valid only for PaintOpWithFlags. + const PaintFlags* flags_to_serialize = nullptr; }; struct DeserializeOptions {}; @@ -160,6 +163,9 @@ // generated images. static bool OpHasDiscardableImages(const PaintOp* op); + // Returns true if the given op type has PaintFlags. + static bool TypeHasFlags(PaintOpType type); + int CountSlowPaths() const { return 0; } int CountSlowPathsFromFlags() const { return 0; }
diff --git a/cc/paint/paint_op_buffer_serializer.cc b/cc/paint/paint_op_buffer_serializer.cc index a476329..856c09b 100644 --- a/cc/paint/paint_op_buffer_serializer.cc +++ b/cc/paint/paint_op_buffer_serializer.cc
@@ -5,9 +5,26 @@ #include "cc/paint/paint_op_buffer_serializer.h" #include "base/bind.h" +#include "cc/paint/scoped_image_flags.h" #include "ui/gfx/skia_util.h" namespace cc { +namespace { + +class ScopedFlagsOverride { + public: + ScopedFlagsOverride(PaintOp::SerializeOptions* options, + const PaintFlags* flags) + : options_(options) { + options_->flags_to_serialize = flags; + } + ~ScopedFlagsOverride() { options_->flags_to_serialize = nullptr; } + + private: + PaintOp::SerializeOptions* options_; +}; + +} // namespace PaintOpBufferSerializer::PaintOpBufferSerializer(SerializeCallback serialize_cb, ImageProvider* image_provider) @@ -69,9 +86,8 @@ canvas_.getTotalMatrix()); PlaybackParams params(image_provider_, canvas_.getTotalMatrix()); - // TODO(khushalsagar): Use PlaybackFoldingIterator so we do alpha folding - // at serialization. - for (PaintOpBuffer::CompositeIterator iter(buffer, offsets); iter; ++iter) { + for (PaintOpBuffer::PlaybackFoldingIterator iter(buffer, offsets); iter; + ++iter) { const PaintOp* op = *iter; // Skip ops outside the current clip if they have images. This saves @@ -82,7 +98,15 @@ continue; if (op->GetType() != PaintOpType::DrawRecord) { - if (!SerializeOp(op, options, params)) + bool success = false; + if (op->IsPaintOpWithFlags()) { + success = SerializeOpWithFlags(static_cast<const PaintOpWithFlags*>(op), + &options, params, iter.alpha()); + } else { + success = SerializeOp(op, options, params); + } + + if (!success) return; continue; } @@ -95,6 +119,30 @@ } } +bool PaintOpBufferSerializer::SerializeOpWithFlags( + const PaintOpWithFlags* flags_op, + PaintOp::SerializeOptions* options, + const PlaybackParams& params, + uint8_t alpha) { + const bool needs_flag_override = + alpha != 255 || + (flags_op->flags.HasDiscardableImages() && options->image_provider); + + base::Optional<ScopedImageFlags> scoped_flags; + if (needs_flag_override) { + scoped_flags.emplace(options->image_provider, &flags_op->flags, + options->canvas->getTotalMatrix(), alpha); + } + + const PaintFlags* flags_to_serialize = + scoped_flags ? scoped_flags->flags() : &flags_op->flags; + if (!flags_to_serialize) + return true; + + ScopedFlagsOverride override_flags(options, flags_to_serialize); + return SerializeOp(flags_op, *options, params); +} + bool PaintOpBufferSerializer::SerializeOp( const PaintOp* op, const PaintOp::SerializeOptions& options, @@ -112,8 +160,11 @@ DCHECK_EQ(bytes % PaintOpBuffer::PaintOpAlign, 0u); // Only pass state-changing operations to the canvas. - if (!op->IsDrawOp()) + if (!op->IsDrawOp()) { + // Note that we don't need to use overridden flags during raster here since + // the override must not affect any state being tracked by this canvas. op->Raster(&canvas_, params); + } return true; }
diff --git a/cc/paint/paint_op_buffer_serializer.h b/cc/paint/paint_op_buffer_serializer.h index da4908403..1feb7589 100644 --- a/cc/paint/paint_op_buffer_serializer.h +++ b/cc/paint/paint_op_buffer_serializer.h
@@ -38,6 +38,10 @@ const PlaybackParams& params); void SerializeBuffer(const PaintOpBuffer* buffer, const std::vector<size_t>* offsets); + bool SerializeOpWithFlags(const PaintOpWithFlags* flags_op, + PaintOp::SerializeOptions* options, + const PlaybackParams& params, + uint8_t alpha); bool SerializeOp(const PaintOp* op, const PaintOp::SerializeOptions& options, const PlaybackParams& params);
diff --git a/cc/paint/paint_op_buffer_unittest.cc b/cc/paint/paint_op_buffer_unittest.cc index 27691439..f2de6e5 100644 --- a/cc/paint/paint_op_buffer_unittest.cc +++ b/cc/paint/paint_op_buffer_unittest.cc
@@ -1823,6 +1823,49 @@ } } +TEST_P(PaintOpSerializationTest, UsesOverridenFlags) { + if (!PaintOp::TypeHasFlags(GetParamType())) + return; + + PushTestOps(GetParamType()); + ResizeOutputBuffer(); + + PaintOp::SerializeOptions options; + PaintOp::DeserializeOptions deserialize_options; + size_t deserialized_size = sizeof(LargestPaintOp) + PaintOp::kMaxSkip; + std::unique_ptr<char, base::AlignedFreeDeleter> deserialized( + static_cast<char*>( + base::AlignedAlloc(deserialized_size, PaintOpBuffer::PaintOpAlign))); + for (const auto* op : PaintOpBuffer::Iterator(&buffer_)) { + options.flags_to_serialize = + &static_cast<const PaintOpWithFlags*>(op)->flags; + + size_t bytes_written = op->Serialize(output_.get(), output_size_, options); + size_t bytes_read = 0u; + PaintOp* written = PaintOp::Deserialize( + output_.get(), bytes_written, deserialized.get(), deserialized_size, + &bytes_read, deserialize_options); + ASSERT_TRUE(written); + EXPECT_EQ(*op, *written); + written->DestroyThis(); + written = nullptr; + + PaintFlags override_flags = static_cast<const PaintOpWithFlags*>(op)->flags; + override_flags.setAlpha(override_flags.getAlpha() * 0.5); + options.flags_to_serialize = &override_flags; + bytes_written = op->Serialize(output_.get(), output_size_, options); + written = PaintOp::Deserialize(output_.get(), bytes_written, + deserialized.get(), deserialized_size, + &bytes_read, deserialize_options); + ASSERT_TRUE(written); + ASSERT_TRUE(written->IsPaintOpWithFlags()); + EXPECT_EQ(static_cast<const PaintOpWithFlags*>(written)->flags.getAlpha(), + override_flags.getAlpha()); + written->DestroyThis(); + written = nullptr; + } +} + TEST(PaintOpSerializationTest, CompleteBufferSerialization) { PaintOpBuffer buffer; PushDrawIRectOps(&buffer); @@ -2077,6 +2120,65 @@ } } +TEST(PaintOpBufferSerializationTest, AlphaFoldingDuringSerialization) { + PaintOpBuffer buffer; + + uint8_t alpha = 100; + buffer.push<SaveLayerAlphaOp>(nullptr, alpha, false); + + PaintFlags draw_flags; + draw_flags.setColor(SK_ColorMAGENTA); + draw_flags.setAlpha(50); + SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4); + buffer.push<DrawRectOp>(rect, draw_flags); + buffer.push<RestoreOp>(); + + PaintOpBufferSerializer::Preamble preamble; + preamble.playback_rect = gfx::Rect(1000.f, 1000.f); + + std::unique_ptr<char, base::AlignedFreeDeleter> memory( + static_cast<char*>(base::AlignedAlloc(PaintOpBuffer::kInitialBufferSize, + PaintOpBuffer::PaintOpAlign))); + SimpleBufferSerializer serializer(memory.get(), + PaintOpBuffer::kInitialBufferSize, nullptr); + serializer.Serialize(&buffer, nullptr, preamble); + ASSERT_NE(serializer.written(), 0u); + + PaintOp::DeserializeOptions deserialized_options; + auto deserialized_buffer = PaintOpBuffer::MakeFromMemory( + memory.get(), serializer.written(), deserialized_options); + ASSERT_TRUE(deserialized_buffer); + + // 3 additional ops for save, clip and restore. + ASSERT_EQ(deserialized_buffer->size(), 4u); + size_t i = 0; + for (const auto* op : PaintOpBuffer::Iterator(deserialized_buffer.get())) { + ++i; + if (i == 1) { + EXPECT_EQ(op->GetType(), PaintOpType::Save); + continue; + } + + if (i == 2) { + EXPECT_EQ(op->GetType(), PaintOpType::ClipRect); + continue; + } + + if (i == 4) { + EXPECT_EQ(op->GetType(), PaintOpType::Restore); + continue; + } + + ASSERT_EQ(op->GetType(), PaintOpType::DrawRect); + // Expect the alpha from the draw and the save layer to be folded together. + // Since alpha is stored in a uint8_t and gets rounded, so use tolerance. + float expected_alpha = alpha * 50 / 255.f; + EXPECT_LE(std::abs(expected_alpha - + static_cast<const DrawRectOp*>(op)->flags.getAlpha()), + 1.f); + } +} + // Test generic PaintOp deserializing failure cases. TEST(PaintOpBufferTest, PaintOpDeserialize) { static constexpr size_t kSize = sizeof(LargestPaintOp) + 100;
diff --git a/chrome/browser/banners/app_banner_settings_helper.cc b/chrome/browser/banners/app_banner_settings_helper.cc index 3e681a0..b2da6cc 100644 --- a/chrome/browser/banners/app_banner_settings_helper.cc +++ b/chrome/browser/banners/app_banner_settings_helper.cc
@@ -51,7 +51,7 @@ // Dictionary keys to use for the events. Must be kept in sync with // AppBannerEvent. -const char* kBannerEventKeys[] = { +constexpr const char* kBannerEventKeys[] = { "couldShowBannerEvents", "didShowBannerEvent", "didBlockBannerEvent", @@ -87,14 +87,15 @@ return dict; } -base::DictionaryValue* GetAppDict(base::DictionaryValue* origin_dict, - const std::string& key_name) { - base::DictionaryValue* app_dict = nullptr; - if (!origin_dict->GetDictionaryWithoutPathExpansion(key_name, &app_dict)) { +base::Value* GetAppDict(base::DictionaryValue* origin_dict, + const std::string& key_name) { + base::Value* app_dict = + origin_dict->FindKeyOfType(key_name, base::Value::Type::DICTIONARY); + if (!app_dict) { // Don't allow more than kMaxAppsPerSite dictionaries. if (origin_dict->size() < kMaxAppsPerSite) { - app_dict = origin_dict->SetDictionaryWithoutPathExpansion( - key_name, base::MakeUnique<base::DictionaryValue>()); + app_dict = origin_dict->SetKey( + key_name, base::Value(base::Value::Type::DICTIONARY)); } } @@ -211,22 +212,22 @@ if (!origin_dict) return; - base::DictionaryValue* app_dict = + base::Value* app_dict = GetAppDict(origin_dict.get(), package_name_or_start_url); if (!app_dict) return; // Dates are stored in their raw form (i.e. not local dates) to be resilient // to time zone changes. - std::string event_key(kBannerEventKeys[event]); + const char* event_key = kBannerEventKeys[event]; if (event == APP_BANNER_EVENT_COULD_SHOW) { // Do not overwrite a could show event, as this is used for metrics. - double internal_date; - if (app_dict->GetDouble(event_key, &internal_date)) + if (app_dict->FindKeyOfType(event_key, base::Value::Type::DOUBLE)) return; } - app_dict->SetDouble(event_key, time.ToInternalValue()); + app_dict->SetKey(event_key, + base::Value(static_cast<double>(time.ToInternalValue()))); settings->SetWebsiteSettingDefaultScope( origin_url, GURL(), CONTENT_SETTINGS_TYPE_APP_BANNER, std::string(), @@ -300,17 +301,17 @@ if (!origin_dict) return base::Time(); - base::DictionaryValue* app_dict = + base::Value* app_dict = GetAppDict(origin_dict.get(), package_name_or_start_url); if (!app_dict) return base::Time(); - std::string event_key(kBannerEventKeys[event]); - double internal_time; - if (!app_dict->GetDouble(event_key, &internal_time)) + base::Value* internal_time = app_dict->FindKeyOfType( + kBannerEventKeys[event], base::Value::Type::DOUBLE); + if (!internal_time) return base::Time(); - return base::Time::FromInternalValue(internal_time); + return base::Time::FromInternalValue(internal_time->GetDouble()); } bool AppBannerSettingsHelper::HasSufficientEngagement(double total_engagement) { @@ -357,11 +358,11 @@ const base::DictionaryValue* value; it.value().GetAsDictionary(&value); - std::string event_key( - kBannerEventKeys[APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN]); double internal_time; if (it.key() == kInstantAppsKey || - !value->GetDouble(event_key, &internal_time)) { + !value->GetDouble( + kBannerEventKeys[APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN], + &internal_time)) { continue; }
diff --git a/chrome/browser/chromeos/file_system_provider/registry.cc b/chrome/browser/chromeos/file_system_provider/registry.cc index 0748a0cc..5df21cf 100644 --- a/chrome/browser/chromeos/file_system_provider/registry.cc +++ b/chrome/browser/chromeos/file_system_provider/registry.cc
@@ -51,40 +51,40 @@ void Registry::RememberFileSystem( const ProvidedFileSystemInfo& file_system_info, const Watchers& watchers) { - auto file_system = base::MakeUnique<base::DictionaryValue>(); - file_system->SetKey(kPrefKeyFileSystemId, - base::Value(file_system_info.file_system_id())); - file_system->SetKey(kPrefKeyDisplayName, - base::Value(file_system_info.display_name())); - file_system->SetKey(kPrefKeyWritable, - base::Value(file_system_info.writable())); - file_system->SetKey(kPrefKeySupportsNotifyTag, - base::Value(file_system_info.supports_notify_tag())); - file_system->SetKey(kPrefKeyOpenedFilesLimit, - base::Value(file_system_info.opened_files_limit())); + base::Value file_system(base::Value::Type::DICTIONARY); + file_system.SetKey(kPrefKeyFileSystemId, + base::Value(file_system_info.file_system_id())); + file_system.SetKey(kPrefKeyDisplayName, + base::Value(file_system_info.display_name())); + file_system.SetKey(kPrefKeyWritable, + base::Value(file_system_info.writable())); + file_system.SetKey(kPrefKeySupportsNotifyTag, + base::Value(file_system_info.supports_notify_tag())); + file_system.SetKey(kPrefKeyOpenedFilesLimit, + base::Value(file_system_info.opened_files_limit())); - auto watchers_value = base::MakeUnique<base::DictionaryValue>(); + base::Value watchers_value(base::Value::Type::DICTIONARY); for (const auto& it : watchers) { - auto watcher = base::MakeUnique<base::DictionaryValue>(); - watcher->SetKey(kPrefKeyWatcherEntryPath, - base::Value(it.second.entry_path.value())); - watcher->SetKey(kPrefKeyWatcherRecursive, base::Value(it.second.recursive)); - watcher->SetKey(kPrefKeyWatcherLastTag, base::Value(it.second.last_tag)); - auto persistent_origins_value = base::MakeUnique<base::ListValue>(); + base::Value watcher(base::Value::Type::DICTIONARY); + watcher.SetKey(kPrefKeyWatcherEntryPath, + base::Value(it.second.entry_path.value())); + watcher.SetKey(kPrefKeyWatcherRecursive, base::Value(it.second.recursive)); + watcher.SetKey(kPrefKeyWatcherLastTag, base::Value(it.second.last_tag)); + base::Value persistent_origins_value(base::Value::Type::LIST); for (const auto& subscriber_it : it.second.subscribers) { // Only persistent subscribers should be stored in persistent storage. // Other ones should not be restired after a restart. - if (subscriber_it.second.persistent) - persistent_origins_value->AppendString(subscriber_it.first.spec()); + if (subscriber_it.second.persistent) { + persistent_origins_value.GetList().emplace_back( + subscriber_it.first.spec()); + } } - watcher->SetWithoutPathExpansion(kPrefKeyWatcherPersistentOrigins, - std::move(persistent_origins_value)); - watchers_value->SetWithoutPathExpansion(it.second.entry_path.value(), - std::move(watcher)); + watcher.SetKey(kPrefKeyWatcherPersistentOrigins, + std::move(persistent_origins_value)); + watchers_value.SetKey(it.second.entry_path.value(), std::move(watcher)); } - file_system->SetWithoutPathExpansion(kPrefKeyWatchers, - std::move(watchers_value)); + file_system.SetKey(kPrefKeyWatchers, std::move(watchers_value)); PrefService* const pref_service = profile_->GetPrefs(); DCHECK(pref_service); @@ -92,17 +92,16 @@ DictionaryPrefUpdate dict_update(pref_service, prefs::kFileSystemProviderMounted); - base::DictionaryValue* file_systems_per_extension_weak = NULL; - if (!dict_update->GetDictionaryWithoutPathExpansion( - file_system_info.provider_id(), &file_systems_per_extension_weak)) { - file_systems_per_extension_weak = - dict_update->SetDictionaryWithoutPathExpansion( - file_system_info.provider_id(), - base::MakeUnique<base::DictionaryValue>()); + base::Value* file_systems_per_extension = dict_update->FindKeyOfType( + file_system_info.provider_id(), base::Value::Type::DICTIONARY); + if (!file_systems_per_extension) { + file_systems_per_extension = + dict_update->SetKey(file_system_info.provider_id(), + base::Value(base::Value::Type::DICTIONARY)); } - file_systems_per_extension_weak->SetWithoutPathExpansion( - file_system_info.file_system_id(), std::move(file_system)); + file_systems_per_extension->SetKey(file_system_info.file_system_id(), + std::move(file_system)); } void Registry::ForgetFileSystem(const std::string& provider_id,
diff --git a/chrome/browser/component_updater/supervised_user_whitelist_installer.cc b/chrome/browser/component_updater/supervised_user_whitelist_installer.cc index 9413d19..98c7d1a 100644 --- a/chrome/browser/component_updater/supervised_user_whitelist_installer.cc +++ b/chrome/browser/component_updater/supervised_user_whitelist_installer.cc
@@ -24,6 +24,7 @@ #include "base/path_service.h" #include "base/scoped_observer.h" #include "base/sequenced_task_runner.h" +#include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/task_scheduler/post_task.h" #include "base/task_scheduler/task_traits.h" @@ -548,35 +549,34 @@ const std::string& name) { DictionaryPrefUpdate update(local_state_, prefs::kRegisteredSupervisedUserWhitelists); - base::DictionaryValue* pref_dict = update.Get(); - base::DictionaryValue* whitelist_dict_weak = nullptr; - const bool newly_added = !pref_dict->GetDictionaryWithoutPathExpansion( - crx_id, &whitelist_dict_weak); + base::Value* pref_dict = update.Get(); + base::Value* whitelist_dict = + pref_dict->FindKeyOfType(crx_id, base::Value::Type::DICTIONARY); + const bool newly_added = !whitelist_dict; if (newly_added) { - whitelist_dict_weak = pref_dict->SetDictionaryWithoutPathExpansion( - crx_id, std::make_unique<base::DictionaryValue>()); - whitelist_dict_weak->SetString(kName, name); + whitelist_dict = + pref_dict->SetKey(crx_id, base::Value(base::Value::Type::DICTIONARY)); + whitelist_dict->SetKey(kName, base::Value(name)); } if (!client_id.empty()) { - base::ListValue* clients_weak = nullptr; - if (!whitelist_dict_weak->GetList(kClients, &clients_weak)) { + base::Value* clients = + whitelist_dict->FindKeyOfType(kClients, base::Value::Type::LIST); + if (!clients) { DCHECK(newly_added); - auto clients = std::make_unique<base::ListValue>(); - clients_weak = clients.get(); - whitelist_dict_weak->Set(kClients, std::move(clients)); + clients = whitelist_dict->SetKey(kClients, + base::Value(base::Value::Type::LIST)); } - bool success = clients_weak->AppendIfNotPresent( - std::make_unique<base::Value>(client_id)); - DCHECK(success); + + base::Value client(client_id); + DCHECK(!base::ContainsValue(clients->GetList(), client)); + clients->GetList().push_back(std::move(client)); } if (!newly_added) { // Sanity-check that the stored name is equal to the name passed in. // In release builds this is a no-op. - std::string stored_name; - DCHECK(whitelist_dict_weak->GetString(kName, &stored_name)); - DCHECK_EQ(stored_name, name); + DCHECK_EQ(name, whitelist_dict->FindKey(kName)->GetString()); return; }
diff --git a/chrome/browser/permissions/permission_decision_auto_blocker.cc b/chrome/browser/permissions/permission_decision_auto_blocker.cc index 09c4fee..40916655 100644 --- a/chrome/browser/permissions/permission_decision_auto_blocker.cc +++ b/chrome/browser/permissions/permission_decision_auto_blocker.cc
@@ -5,6 +5,8 @@ #include "chrome/browser/permissions/permission_decision_auto_blocker.h" #include <memory> +#include <string> +#include <utility> #include "base/feature_list.h" #include "base/memory/ptr_util.h" @@ -69,17 +71,14 @@ return dict; } -base::DictionaryValue* GetOrCreatePermissionDict( - base::DictionaryValue* origin_dict, - const std::string& permission) { - base::DictionaryValue* permission_dict = nullptr; - if (!origin_dict->GetDictionaryWithoutPathExpansion(permission, - &permission_dict)) { - permission_dict = origin_dict->SetDictionaryWithoutPathExpansion( - permission, base::MakeUnique<base::DictionaryValue>()); - } - - return permission_dict; +base::Value* GetOrCreatePermissionDict(base::Value* origin_dict, + const std::string& permission) { + base::Value* permission_dict = + origin_dict->FindKeyOfType(permission, base::Value::Type::DICTIONARY); + if (permission_dict) + return permission_dict; + return origin_dict->SetKey(permission, + base::Value(base::Value::Type::DICTIONARY)); } int RecordActionInWebsiteSettings(const GURL& url, @@ -90,12 +89,13 @@ HostContentSettingsMapFactory::GetForProfile(profile); std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(map, url); - base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( + base::Value* permission_dict = GetOrCreatePermissionDict( dict.get(), PermissionUtil::GetPermissionString(permission)); - int current_count = 0; - permission_dict->GetInteger(key, ¤t_count); - permission_dict->SetInteger(key, ++current_count); + base::Value* value = + permission_dict->FindKeyOfType(key, base::Value::Type::INTEGER); + int current_count = value ? value->GetInt() : 0; + permission_dict->SetKey(key, base::Value(++current_count)); map->SetWebsiteSettingDefaultScope( url, GURL(), CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA, @@ -111,25 +111,25 @@ HostContentSettingsMap* map = HostContentSettingsMapFactory::GetForProfile(profile); std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(map, url); - base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( + base::Value* permission_dict = GetOrCreatePermissionDict( dict.get(), PermissionUtil::GetPermissionString(permission)); - int current_count = 0; - permission_dict->GetInteger(key, ¤t_count); - return current_count; + base::Value* value = + permission_dict->FindKeyOfType(key, base::Value::Type::INTEGER); + return value ? value->GetInt() : 0; } -bool IsUnderEmbargo(base::DictionaryValue* permission_dict, +bool IsUnderEmbargo(base::Value* permission_dict, const base::Feature& feature, const char* key, base::Time current_time, base::TimeDelta offset) { - double embargo_date = -1; - - if (base::FeatureList::IsEnabled(feature) && - permission_dict->GetDouble(key, &embargo_date)) { - if (current_time < base::Time::FromInternalValue(embargo_date) + offset) - return true; + base::Value* found = + permission_dict->FindKeyOfType(key, base::Value::Type::DOUBLE); + if (found && base::FeatureList::IsEnabled(feature) && + current_time < + base::Time::FromInternalValue(found->GetDouble()) + offset) { + return true; } return false; @@ -218,7 +218,7 @@ DCHECK(settings_map); std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(settings_map, request_origin); - base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( + base::Value* permission_dict = GetOrCreatePermissionDict( dict.get(), PermissionUtil::GetPermissionString(permission)); if (IsUnderEmbargo(permission_dict, features::kPermissionsBlacklist, @@ -379,18 +379,16 @@ HostContentSettingsMap* map = HostContentSettingsMapFactory::GetForProfile(profile_); std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(map, url); - base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( + base::Value* permission_dict = GetOrCreatePermissionDict( dict.get(), PermissionUtil::GetPermissionString(permission)); // Deleting non-existent entries will return a false value. Since it should be // impossible for a permission to have been embargoed for two different // reasons at the same time, check that exactly one deletion was successful. const bool dismissal_key_deleted = - permission_dict->RemoveWithoutPathExpansion( - kPermissionDismissalEmbargoKey, nullptr); + permission_dict->RemoveKey(kPermissionDismissalEmbargoKey); const bool blacklist_key_deleted = - permission_dict->RemoveWithoutPathExpansion( - kPermissionBlacklistEmbargoKey, nullptr); + permission_dict->RemoveKey(kPermissionBlacklistEmbargoKey); DCHECK(dismissal_key_deleted != blacklist_key_deleted); map->SetWebsiteSettingDefaultScope( @@ -454,9 +452,10 @@ HostContentSettingsMapFactory::GetForProfile(profile_); std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(map, request_origin); - base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( + base::Value* permission_dict = GetOrCreatePermissionDict( dict.get(), PermissionUtil::GetPermissionString(permission)); - permission_dict->SetDouble(key, clock_->Now().ToInternalValue()); + permission_dict->SetKey( + key, base::Value(static_cast<double>(clock_->Now().ToInternalValue()))); map->SetWebsiteSettingDefaultScope( request_origin, GURL(), CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA, std::string(), std::move(dict));
diff --git a/chrome/browser/safe_browsing/incident_reporting/platform_state_store.cc b/chrome/browser/safe_browsing/incident_reporting/platform_state_store.cc index c7fcb54..0f771880 100644 --- a/chrome/browser/safe_browsing/incident_reporting/platform_state_store.cc +++ b/chrome/browser/safe_browsing/incident_reporting/platform_state_store.cc
@@ -93,7 +93,7 @@ void RestoreOfTypeFromProtobuf( const RepeatedPtrField<StateStoreData::Incidents::KeyDigestMapFieldEntry>& key_digest_pairs, - base::DictionaryValue* type_dict) { + base::Value* type_dict) { for (const auto& key_digest : key_digest_pairs) { if (!key_digest.has_key() || !key_digest.has_digest()) continue; @@ -106,18 +106,18 @@ void RestoreFromProtobuf( const RepeatedPtrField<StateStoreData::TypeIncidentsMapFieldEntry>& type_incidents_pairs, - base::DictionaryValue* value_dict) { + base::Value* value_dict) { for (const auto& type_incidents : type_incidents_pairs) { if (!type_incidents.has_type() || !type_incidents.has_incidents() || type_incidents.incidents().key_to_digest_size() == 0) { continue; } std::string type_string(base::IntToString(type_incidents.type())); - base::DictionaryValue* type_dict = nullptr; - if (!value_dict->GetDictionaryWithoutPathExpansion(type_string, - &type_dict)) { - type_dict = value_dict->SetDictionaryWithoutPathExpansion( - type_string, base::MakeUnique<base::DictionaryValue>()); + base::Value* type_dict = + value_dict->FindKeyOfType(type_string, base::Value::Type::DICTIONARY); + if (!type_dict) { + type_dict = value_dict->SetKey( + type_string, base::Value(base::Value::Type::DICTIONARY)); } RestoreOfTypeFromProtobuf(type_incidents.incidents().key_to_digest(), type_dict);
diff --git a/chrome/browser/safe_browsing/incident_reporting/state_store.cc b/chrome/browser/safe_browsing/incident_reporting/state_store.cc index 90a5135..aad4d603 100644 --- a/chrome/browser/safe_browsing/incident_reporting/state_store.cc +++ b/chrome/browser/safe_browsing/incident_reporting/state_store.cc
@@ -40,11 +40,11 @@ IncidentDigest digest) { std::string type_string(base::IntToString(static_cast<int32_t>(type))); base::DictionaryValue* incidents_sent = GetPrefDict(); - base::DictionaryValue* type_dict = nullptr; - if (!incidents_sent->GetDictionaryWithoutPathExpansion(type_string, - &type_dict)) { - type_dict = incidents_sent->SetDictionaryWithoutPathExpansion( - type_string, base::MakeUnique<base::DictionaryValue>()); + base::Value* type_dict = + incidents_sent->FindKeyOfType(type_string, base::Value::Type::DICTIONARY); + if (!type_dict) { + type_dict = incidents_sent->SetKey( + type_string, base::Value(base::Value::Type::DICTIONARY)); } type_dict->SetKey(key, base::Value(base::UintToString(digest))); }
diff --git a/chrome/browser/supervised_user/legacy/supervised_user_shared_settings_service.cc b/chrome/browser/supervised_user/legacy/supervised_user_shared_settings_service.cc index 8cc09bf..27006ad 100644 --- a/chrome/browser/supervised_user/legacy/supervised_user_shared_settings_service.cc +++ b/chrome/browser/supervised_user/legacy/supervised_user_shared_settings_service.cc
@@ -41,14 +41,11 @@ const char kAcknowledged[] = "acknowledged"; const char kValue[] = "value"; -DictionaryValue* FindOrCreateDictionary(DictionaryValue* parent, - const std::string& key) { - DictionaryValue* dict = nullptr; - if (!parent->GetDictionaryWithoutPathExpansion(key, &dict)) { - dict = parent->SetDictionaryWithoutPathExpansion( - key, base::MakeUnique<base::DictionaryValue>()); - } - return dict; +Value* FindOrCreateDictionary(Value* parent, const std::string& key) { + Value* dict = parent->FindKeyOfType(key, base::Value::Type::DICTIONARY); + if (dict) + return dict; + return parent->SetKey(key, base::Value(base::Value::Type::DICTIONARY)); } class ScopedSupervisedUserSharedSettingsUpdate { @@ -63,9 +60,7 @@ DCHECK(id.empty() || id == su_id); } - DictionaryValue* Get() { - return FindOrCreateDictionary(update_.Get(), su_id_); - } + Value* Get() { return FindOrCreateDictionary(update_.Get(), su_id_); } private: DictionaryPrefUpdate update_; @@ -106,13 +101,12 @@ const Value& value, bool acknowledged) { ScopedSupervisedUserSharedSettingsUpdate update(prefs_, su_id); - DictionaryValue* update_dict = update.Get(); + Value* update_dict = update.Get(); - DictionaryValue* dict = nullptr; - bool has_key = update_dict->GetDictionaryWithoutPathExpansion(key, &dict); + Value* dict = update_dict->FindKeyOfType(key, base::Value::Type::DICTIONARY); + bool has_key = static_cast<bool>(dict); if (!has_key) { - dict = update_dict->SetDictionaryWithoutPathExpansion( - key, base::MakeUnique<base::DictionaryValue>()); + dict = update_dict->SetKey(key, base::Value(base::Value::Type::DICTIONARY)); } dict->SetKey(kValue, value.Clone()); dict->SetKey(kAcknowledged, base::Value(acknowledged)); @@ -230,8 +224,8 @@ const std::string& su_id = supervised_user_shared_setting.mu_id(); ScopedSupervisedUserSharedSettingsUpdate update(prefs_, su_id); const std::string& key = supervised_user_shared_setting.key(); - DictionaryValue* dict = FindOrCreateDictionary(update.Get(), key); - dict->SetWithoutPathExpansion(kValue, std::move(value)); + Value* dict = FindOrCreateDictionary(update.Get(), key); + dict->SetKey(kValue, base::Value::FromUniquePtrValue(std::move(value))); // Every setting we get from the server should have the acknowledged flag // set. @@ -325,9 +319,9 @@ const std::string& key = supervised_user_shared_setting.key(); const std::string& su_id = supervised_user_shared_setting.mu_id(); ScopedSupervisedUserSharedSettingsUpdate update(prefs_, su_id); - DictionaryValue* update_dict = update.Get(); - DictionaryValue* dict = nullptr; - bool has_key = update_dict->GetDictionaryWithoutPathExpansion(key, &dict); + Value* update_dict = update.Get(); + Value* dict = + update_dict->FindKeyOfType(key, base::Value::Type::DICTIONARY); switch (sync_change.change_type()) { case SyncChange::ACTION_ADD: case SyncChange::ACTION_UPDATE: { @@ -335,29 +329,28 @@ // flag set. DCHECK(supervised_user_shared_setting.acknowledged()); - if (has_key) { + if (dict) { // If the supervised user already exists, it should be an update // action. DCHECK_EQ(SyncChange::ACTION_UPDATE, sync_change.change_type()); } else { // Otherwise, it should be an add action. DCHECK_EQ(SyncChange::ACTION_ADD, sync_change.change_type()); - dict = update_dict->SetDictionaryWithoutPathExpansion( - key, base::MakeUnique<base::DictionaryValue>()); + dict = update_dict->SetKey( + key, base::Value(base::Value::Type::DICTIONARY)); } - std::unique_ptr<Value> value = - base::JSONReader::Read(supervised_user_shared_setting.value()); - dict->SetWithoutPathExpansion(kValue, std::move(value)); + dict->SetKey(kValue, + base::Value::FromUniquePtrValue(base::JSONReader::Read( + supervised_user_shared_setting.value()))); dict->SetKey( kAcknowledged, base::Value(supervised_user_shared_setting.acknowledged())); break; } case SyncChange::ACTION_DELETE: { - if (has_key) - update_dict->RemoveWithoutPathExpansion(key, nullptr); - else + if (!update_dict->RemoveKey(key)) { NOTREACHED() << "Trying to delete nonexistent key " << key; + } break; } case SyncChange::ACTION_INVALID: {
diff --git a/chrome/browser/supervised_user/legacy/supervised_user_sync_service.cc b/chrome/browser/supervised_user/legacy/supervised_user_sync_service.cc index 7c07522..584732d2 100644 --- a/chrome/browser/supervised_user/legacy/supervised_user_sync_service.cc +++ b/chrome/browser/supervised_user/legacy/supervised_user_sync_service.cc
@@ -207,17 +207,17 @@ observers_.RemoveObserver(observer); } -std::unique_ptr<base::DictionaryValue> -SupervisedUserSyncService::CreateDictionary(const std::string& name, - const std::string& master_key, - const std::string& signature_key, - const std::string& encryption_key, - int avatar_index) { - std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue()); - result->SetString(kName, name); - result->SetString(kMasterKey, master_key); - result->SetString(kPasswordSignatureKey, signature_key); - result->SetString(kPasswordEncryptionKey, encryption_key); +base::Value SupervisedUserSyncService::CreateDictionary( + const std::string& name, + const std::string& master_key, + const std::string& signature_key, + const std::string& encryption_key, + int avatar_index) { + base::Value result(base::Value::Type::DICTIONARY); + result.SetKey(kName, base::Value(name)); + result.SetKey(kMasterKey, base::Value(master_key)); + result.SetKey(kPasswordSignatureKey, base::Value(signature_key)); + result.SetKey(kPasswordEncryptionKey, base::Value(encryption_key)); // TODO(akuegel): Get rid of the avatar stuff here when Chrome OS switches // to the avatar index that is stored as a shared setting. std::string chrome_avatar; @@ -227,8 +227,8 @@ #else chrome_avatar = BuildAvatarString(avatar_index); #endif - result->SetString(kChromeAvatar, chrome_avatar); - result->SetString(kChromeOsAvatar, chromeos_avatar); + result.SetKey(kChromeAvatar, base::Value(std::move(chrome_avatar))); + result.SetKey(kChromeOsAvatar, base::Value(std::move(chromeos_avatar))); return result; } @@ -274,12 +274,11 @@ bool add_user) { DictionaryPrefUpdate update(prefs_, prefs::kSupervisedUsers); base::DictionaryValue* dict = update.Get(); - std::unique_ptr<base::DictionaryValue> value = CreateDictionary( - name, master_key, signature_key, encryption_key, avatar_index); - DCHECK_EQ(add_user, !dict->HasKey(id)); - base::DictionaryValue* entry = - dict->SetDictionaryWithoutPathExpansion(id, std::move(value)); + + base::Value* entry = + dict->SetKey(id, CreateDictionary(name, master_key, signature_key, + encryption_key, avatar_index)); if (!sync_processor_) return;
diff --git a/chrome/browser/supervised_user/legacy/supervised_user_sync_service.h b/chrome/browser/supervised_user/legacy/supervised_user_sync_service.h index 50e59f2..6969848 100644 --- a/chrome/browser/supervised_user/legacy/supervised_user_sync_service.h +++ b/chrome/browser/supervised_user/legacy/supervised_user_sync_service.h
@@ -135,12 +135,11 @@ void GoogleSignedOut(const std::string& account_id, const std::string& username) override; - std::unique_ptr<base::DictionaryValue> CreateDictionary( - const std::string& name, - const std::string& master_key, - const std::string& signature_key, - const std::string& encryption_key, - int avatar_index); + base::Value CreateDictionary(const std::string& name, + const std::string& master_key, + const std::string& signature_key, + const std::string& encryption_key, + int avatar_index); void UpdateSupervisedUserImpl(const std::string& id, const std::string& name,
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service.cc b/chrome/browser/ui/app_list/app_list_syncable_service.cc index 72f7de7..03ad643bb 100644 --- a/chrome/browser/ui/app_list/app_list_syncable_service.cc +++ b/chrome/browser/ui/app_list/app_list_syncable_service.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ui/app_list/app_list_syncable_service.h" +#include <set> #include <utility> #include "base/command_line.h" @@ -184,20 +185,26 @@ const AppListSyncableService::SyncItem* sync_item) { DictionaryPrefUpdate pref_update(profile->GetPrefs(), prefs::kAppListLocalState); - base::DictionaryValue* dict_item = nullptr; - if (!pref_update->GetDictionaryWithoutPathExpansion(sync_item->item_id, - &dict_item)) { - dict_item = pref_update->SetDictionaryWithoutPathExpansion( - sync_item->item_id, base::MakeUnique<base::DictionaryValue>()); + base::Value* dict_item = pref_update->FindKeyOfType( + sync_item->item_id, base::Value::Type::DICTIONARY); + if (!dict_item) { + dict_item = pref_update->SetKey(sync_item->item_id, + base::Value(base::Value::Type::DICTIONARY)); } - dict_item->SetString(kNameKey, sync_item->item_name); - dict_item->SetString(kParentIdKey, sync_item->parent_id); - dict_item->SetString(kPositionKey,sync_item->item_ordinal.IsValid() ? - sync_item->item_ordinal.ToInternalValue() : std::string()); - dict_item->SetString(kPinPositionKey, sync_item->item_pin_ordinal.IsValid() ? - sync_item->item_pin_ordinal.ToInternalValue() : std::string()); - dict_item->SetInteger(kTypeKey, static_cast<int>(sync_item->item_type)); + dict_item->SetKey(kNameKey, base::Value(sync_item->item_name)); + dict_item->SetKey(kParentIdKey, base::Value(sync_item->parent_id)); + dict_item->SetKey(kPositionKey, + base::Value(sync_item->item_ordinal.IsValid() + ? sync_item->item_ordinal.ToInternalValue() + : std::string())); + dict_item->SetKey( + kPinPositionKey, + base::Value(sync_item->item_pin_ordinal.IsValid() + ? sync_item->item_pin_ordinal.ToInternalValue() + : std::string())); + dict_item->SetKey(kTypeKey, + base::Value(static_cast<int>(sync_item->item_type))); } bool IsDefaultSyncItem(const AppListSyncableService::SyncItem* sync_item) {
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service.h b/chrome/browser/ui/app_list/app_list_syncable_service.h index c95ab4c4..e42236c 100644 --- a/chrome/browser/ui/app_list/app_list_syncable_service.h +++ b/chrome/browser/ui/app_list/app_list_syncable_service.h
@@ -9,6 +9,7 @@ #include <map> #include <memory> +#include <string> #include "base/macros.h" #include "base/memory/weak_ptr.h"
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc index b9cd2ee..5a34126c 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc +++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
@@ -7,6 +7,7 @@ #include <stddef.h> #include <string> +#include <utility> #include "base/files/file_util.h" #include "base/memory/ptr_util.h" @@ -75,12 +76,12 @@ // DictionaryPrefUpdate overrides: base::DictionaryValue* Get() override { base::DictionaryValue* dict = DictionaryPrefUpdate::Get(); - base::DictionaryValue* dict_item = nullptr; - if (!dict->GetDictionaryWithoutPathExpansion(id_, &dict_item)) { - dict_item = dict->SetDictionaryWithoutPathExpansion( - id_, base::MakeUnique<base::DictionaryValue>()); + base::Value* dict_item = + dict->FindKeyOfType(id_, base::Value::Type::DICTIONARY); + if (!dict_item) { + dict_item = dict->SetKey(id_, base::Value(base::Value::Type::DICTIONARY)); } - return dict_item; + return static_cast<base::DictionaryValue*>(dict_item); } private:
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc index ade10a3..f41ac3d 100644 --- a/ui/accessibility/platform/ax_platform_node_auralinux.cc +++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -271,10 +271,27 @@ obj->GetSize(width, height); } +static AtkObject* ax_platform_node_auralinux_ref_accessible_at_point( + AtkComponent* atk_component, + gint x, + gint y, + AtkCoordType coord_type) { + g_return_val_if_fail(ATK_IS_COMPONENT(atk_component), nullptr); + AtkObject* atk_object = ATK_OBJECT(atk_component); + ui::AXPlatformNodeAuraLinux* obj = + AtkObjectToAXPlatformNodeAuraLinux(atk_object); + if (!obj) + return nullptr; + + return obj->HitTestSync(x, y, coord_type); +} + void ax_component_interface_base_init(AtkComponentIface* iface) { iface->get_extents = ax_platform_node_auralinux_get_extents; iface->get_position = ax_platform_node_auralinux_get_position; iface->get_size = ax_platform_node_auralinux_get_size; + iface->ref_accessible_at_point = + ax_platform_node_auralinux_ref_accessible_at_point; } static const GInterfaceInfo ComponentInfo = { @@ -747,4 +764,17 @@ *height = rect_size.height(); } +gfx::NativeViewAccessible +AXPlatformNodeAuraLinux::HitTestSync(gint x, gint y, AtkCoordType coord_type) { + if (coord_type == ATK_XY_WINDOW) { + if (AtkObject* atk_object = GetParent()) { + gfx::Point window_coords = FindAtkObjectParentCoords(atk_object); + x += window_coords.x(); + y += window_coords.y(); + } + } + + return delegate_->HitTestSync(x, y); +} + } // namespace ui
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.h b/ui/accessibility/platform/ax_platform_node_auralinux.h index cacb7e6..015487be 100644 --- a/ui/accessibility/platform/ax_platform_node_auralinux.h +++ b/ui/accessibility/platform/ax_platform_node_auralinux.h
@@ -33,6 +33,9 @@ AtkCoordType coord_type); void GetPosition(gint* x, gint* y, AtkCoordType coord_type); void GetSize(gint* width, gint* height); + gfx::NativeViewAccessible HitTestSync(gint x, + gint y, + AtkCoordType coord_type); void SetExtentsRelativeToAtkCoordinateType( gint* x, gint* y, gint* width, gint* height,