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, &current_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, &current_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,