diff --git a/DEPS b/DEPS
index fca9343..def57b9 100644
--- a/DEPS
+++ b/DEPS
@@ -44,7 +44,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '248b789e106abdf7b0a92d11a43f038307403358',
+  'v8_revision': '4b582195168e4b62ea38c88c206c664a06fb4b2a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 88e31e6..910fc9b1 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -256,6 +256,8 @@
 
       <if expr="not is_android and not is_ios">
         <!-- MD Bookmarks. -->
+        <include name="IDR_MD_BOOKMARKS_IMAGES_FOLDER_OPEN_SVG" file="resources\md_bookmarks\images\folder_open.svg" type="BINDATA" />
+        <include name="IDR_MD_BOOKMARKS_IMAGES_FOLDER_SVG" file="resources\md_bookmarks\images\folder.svg" type="BINDATA" />
         <if expr="use_vulcanize">
           <then>
             <include name="IDR_MD_BOOKMARKS_VULCANIZED_HTML" file="${root_gen_dir}\chrome\browser\resources\md_bookmarks\vulcanized.html" use_base_dir="false" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" />
@@ -283,7 +285,6 @@
             <include name="IDR_MD_BOOKMARKS_EDIT_DIALOG_JS" file="resources\md_bookmarks\edit_dialog.js" type="BINDATA" />
             <include name="IDR_MD_BOOKMARKS_FOLDER_NODE_HTML" file="resources\md_bookmarks\folder_node.html" type="BINDATA" />
             <include name="IDR_MD_BOOKMARKS_FOLDER_NODE_JS" file="resources\md_bookmarks\folder_node.js" type="BINDATA" />
-            <include name="IDR_MD_BOOKMARKS_ICONS_HTML" file="resources\md_bookmarks\icons.html" type="BINDATA" />
             <include name="IDR_MD_BOOKMARKS_ITEM_HTML" file="resources\md_bookmarks\item.html" type="BINDATA" />
             <include name="IDR_MD_BOOKMARKS_ITEM_JS" file="resources\md_bookmarks\item.js" type="BINDATA" />
             <include name="IDR_MD_BOOKMARKS_LIST_HTML" file="resources\md_bookmarks\list.html" type="BINDATA" />
diff --git a/chrome/browser/permissions/grouped_permission_infobar_delegate_android.cc b/chrome/browser/permissions/grouped_permission_infobar_delegate_android.cc
index a37ce1c..51ba299 100644
--- a/chrome/browser/permissions/grouped_permission_infobar_delegate_android.cc
+++ b/chrome/browser/permissions/grouped_permission_infobar_delegate_android.cc
@@ -21,7 +21,7 @@
 
 // static
 infobars::InfoBar* GroupedPermissionInfoBarDelegate::Create(
-    PermissionPromptAndroid* permission_prompt,
+    const base::WeakPtr<PermissionPromptAndroid>& permission_prompt,
     InfoBarService* infobar_service,
     const GURL& requesting_origin) {
   return infobar_service->AddInfoBar(base::MakeUnique<GroupedPermissionInfoBar>(
@@ -34,6 +34,8 @@
 }
 
 bool GroupedPermissionInfoBarDelegate::ShouldShowPersistenceToggle() const {
+  if (!permission_prompt_)
+    return false;
   return permission_prompt_->ShouldShowPersistenceToggle();
 }
 
@@ -78,7 +80,7 @@
 }
 
 GroupedPermissionInfoBarDelegate::GroupedPermissionInfoBarDelegate(
-    PermissionPromptAndroid* permission_prompt,
+    const base::WeakPtr<PermissionPromptAndroid>& permission_prompt,
     const GURL& requesting_origin)
     : requesting_origin_(requesting_origin),
       persist_(true),
diff --git a/chrome/browser/permissions/grouped_permission_infobar_delegate_android.h b/chrome/browser/permissions/grouped_permission_infobar_delegate_android.h
index 514843d..5ed2657 100644
--- a/chrome/browser/permissions/grouped_permission_infobar_delegate_android.h
+++ b/chrome/browser/permissions/grouped_permission_infobar_delegate_android.h
@@ -24,9 +24,10 @@
   // Public so we can have std::unique_ptr<GroupedPermissionInfoBarDelegate>.
   ~GroupedPermissionInfoBarDelegate() override;
 
-  static infobars::InfoBar* Create(PermissionPromptAndroid* permission_prompt,
-                                   InfoBarService* infobar_service,
-                                   const GURL& requesting_origin);
+  static infobars::InfoBar* Create(
+      const base::WeakPtr<PermissionPromptAndroid>& permission_prompt,
+      InfoBarService* infobar_service,
+      const GURL& requesting_origin);
 
   bool persist() const { return persist_; }
   void set_persist(bool persist) { persist_ = persist; }
@@ -52,8 +53,9 @@
   bool GetAcceptState(size_t position);
 
  private:
-  GroupedPermissionInfoBarDelegate(PermissionPromptAndroid* permission_prompt,
-                                   const GURL& requesting_origin);
+  GroupedPermissionInfoBarDelegate(
+      const base::WeakPtr<PermissionPromptAndroid>& permission_prompt,
+      const GURL& requesting_origin);
 
   // ConfirmInfoBarDelegate:
   InfoBarIdentifier GetIdentifier() const override;
@@ -68,7 +70,7 @@
   const GURL requesting_origin_;
   // Whether the accept/deny decision is persisted.
   bool persist_;
-  PermissionPromptAndroid* permission_prompt_;
+  base::WeakPtr<PermissionPromptAndroid> permission_prompt_;
 
   DISALLOW_COPY_AND_ASSIGN(GroupedPermissionInfoBarDelegate);
 };
diff --git a/chrome/browser/permissions/permission_dialog_delegate.h b/chrome/browser/permissions/permission_dialog_delegate.h
index e1a3ab5..12358bb9 100644
--- a/chrome/browser/permissions/permission_dialog_delegate.h
+++ b/chrome/browser/permissions/permission_dialog_delegate.h
@@ -100,9 +100,9 @@
   // delete the PermissionQueueController.
   std::unique_ptr<PermissionInfoBarDelegate> infobar_delegate_;
 
-  // The PermissionPromptAndroid is alive until the tab navigates or is closed.
-  // We close the prompt on DidFinishNavigation and WebContentsDestroyed, so it
-  // should always be safe to use this pointer.
+  // The PermissionPromptAndroid is deleted when either the dialog is resolved
+  // or the tab is navigated/closed. We close the prompt on DidFinishNavigation
+  // and WebContentsDestroyed, so it should always be safe to use this pointer.
   PermissionPromptAndroid* permission_prompt_;
 
   DISALLOW_COPY_AND_ASSIGN(PermissionDialogDelegate);
diff --git a/chrome/browser/permissions/permission_prompt_android.cc b/chrome/browser/permissions/permission_prompt_android.cc
index b7c8440..baec61e 100644
--- a/chrome/browser/permissions/permission_prompt_android.cc
+++ b/chrome/browser/permissions/permission_prompt_android.cc
@@ -19,7 +19,10 @@
 
 PermissionPromptAndroid::PermissionPromptAndroid(
     content::WebContents* web_contents)
-    : web_contents_(web_contents), delegate_(nullptr), persist_(true) {
+    : web_contents_(web_contents),
+      delegate_(nullptr),
+      persist_(true),
+      weak_factory_(this) {
   DCHECK(web_contents);
 }
 
@@ -46,7 +49,8 @@
     return;
 
   GroupedPermissionInfoBarDelegate::Create(
-      this, infobar_service, delegate_->Requests()[0]->GetOrigin());
+      weak_factory_.GetWeakPtr(), infobar_service,
+      delegate_->Requests()[0]->GetOrigin());
 }
 
 bool PermissionPromptAndroid::CanAcceptRequestUpdate() {
diff --git a/chrome/browser/permissions/permission_prompt_android.h b/chrome/browser/permissions/permission_prompt_android.h
index 80eda10..28d74f7 100644
--- a/chrome/browser/permissions/permission_prompt_android.h
+++ b/chrome/browser/permissions/permission_prompt_android.h
@@ -7,6 +7,7 @@
 
 #include <vector>
 
+#include "base/memory/weak_ptr.h"
 #include "base/strings/string16.h"
 #include "chrome/browser/ui/permission_bubble/permission_prompt.h"
 #include "components/content_settings/core/common/content_settings_types.h"
@@ -56,6 +57,8 @@
 
   bool persist_;
 
+  base::WeakPtrFactory<PermissionPromptAndroid> weak_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(PermissionPromptAndroid);
 };
 
diff --git a/chrome/browser/permissions/permission_request_manager.cc b/chrome/browser/permissions/permission_request_manager.cc
index 843dd53..8d967f4 100644
--- a/chrome/browser/permissions/permission_request_manager.cc
+++ b/chrome/browser/permissions/permission_request_manager.cc
@@ -112,12 +112,12 @@
       view_factory_(base::Bind(&PermissionPrompt::Create)),
       view_(nullptr),
       main_frame_has_fully_loaded_(false),
+      tab_can_show_prompts_(false),
       persist_(true),
       auto_response_for_test_(NONE),
       weak_factory_(this) {
 #if defined(OS_ANDROID)
-  view_ = view_factory_.Run(web_contents);
-  view_->SetDelegate(this);
+  tab_can_show_prompts_ = true;
 #endif
 }
 
@@ -195,16 +195,18 @@
 
     // We can simply erase the current entry in the request table if we aren't
     // showing the dialog, or if we are showing it and it can accept the update.
-    bool can_erase = !view_ || view_->CanAcceptRequestUpdate();
+    bool can_erase = view_->CanAcceptRequestUpdate();
     if (can_erase) {
+      DeleteBubble();
+
       RequestFinishedIncludingDuplicates(*requests_iter);
       requests_.erase(requests_iter);
 
-      if (view_) {
-        view_->Hide();
-        // Will redraw the bubble if it is being shown.
+      if (requests_.empty())
         DequeueRequestsAndShowBubble();
-      }
+      else
+        ShowBubble();
+
       return;
     }
 
@@ -234,22 +236,14 @@
 }
 
 void PermissionRequestManager::HideBubble() {
-  // Disengage from the existing view if there is one and it doesn't manage
-  // its own visibility.
-  if (!view_ || view_->HidesAutomatically())
-    return;
+  tab_can_show_prompts_ = false;
 
-  view_->SetDelegate(nullptr);
-  view_->Hide();
-  view_.reset();
+  if (view_)
+    DeleteBubble();
 }
 
 void PermissionRequestManager::DisplayPendingRequests() {
-  if (IsBubbleVisible())
-    return;
-
-  view_ = view_factory_.Run(web_contents());
-  view_->SetDelegate(this);
+  tab_can_show_prompts_ = true;
 
   if (!main_frame_has_fully_loaded_)
     return;
@@ -294,8 +288,7 @@
     return;
   }
 
-  CancelPendingQueues();
-  FinalizeBubble();
+  CleanUpRequests();
   main_frame_has_fully_loaded_ = false;
 }
 
@@ -316,8 +309,7 @@
 
 void PermissionRequestManager::WebContentsDestroyed() {
   // If the web contents has been destroyed, treat the bubble as cancelled.
-  CancelPendingQueues();
-  FinalizeBubble();
+  CleanUpRequests();
 
   // The WebContents is going away; be aggressively paranoid and delete
   // ourselves lest other parts of the system attempt to add permission bubbles
@@ -359,6 +351,11 @@
 }
 
 void PermissionRequestManager::Closing() {
+#if defined(OS_MACOSX)
+  // Mac calls this whenever you press Esc.
+  if (!view_)
+    return;
+#endif
   std::vector<PermissionRequest*>::iterator requests_iter;
   for (requests_iter = requests_.begin();
        requests_iter != requests_.end();
@@ -381,15 +378,14 @@
 }
 
 void PermissionRequestManager::DequeueRequestsAndShowBubble() {
-  if (!view_)
+  if (view_)
     return;
-  if (!requests_.empty())
-    return;
-  if (!main_frame_has_fully_loaded_)
+  if (!main_frame_has_fully_loaded_ || !tab_can_show_prompts_)
     return;
   if (queued_requests_.empty())
     return;
 
+  DCHECK(requests_.empty());
   requests_.push_back(queued_requests_.front());
   queued_requests_.pop_front();
 
@@ -403,10 +399,13 @@
 }
 
 void PermissionRequestManager::ShowBubble() {
-  DCHECK(view_);
+  DCHECK(!view_);
   DCHECK(!requests_.empty());
   DCHECK(main_frame_has_fully_loaded_);
+  DCHECK(tab_can_show_prompts_);
 
+  view_ = view_factory_.Run(web_contents());
+  view_->SetDelegate(this);
   view_->Show();
   PermissionUmaUtil::PermissionPromptShown(requests_);
   NotifyBubbleAdded();
@@ -416,9 +415,19 @@
     DoAutoResponseForTesting();
 }
 
-void PermissionRequestManager::FinalizeBubble() {
-  if (view_ && !view_->HidesAutomatically())
+void PermissionRequestManager::DeleteBubble() {
+  DCHECK(view_);
+  if (!view_->HidesAutomatically())
     view_->Hide();
+  view_->SetDelegate(nullptr);
+  view_.reset();
+}
+
+void PermissionRequestManager::FinalizeBubble() {
+  DCHECK(view_);
+  DCHECK(!requests_.empty());
+
+  DeleteBubble();
 
   std::vector<PermissionRequest*>::iterator requests_iter;
   for (requests_iter = requests_.begin();
@@ -431,7 +440,7 @@
     DequeueRequestsAndShowBubble();
 }
 
-void PermissionRequestManager::CancelPendingQueues() {
+void PermissionRequestManager::CleanUpRequests() {
   std::deque<PermissionRequest*>::iterator requests_iter;
   for (requests_iter = queued_requests_.begin();
        requests_iter != queued_requests_.end();
@@ -439,6 +448,9 @@
     RequestFinishedIncludingDuplicates(*requests_iter);
   }
   queued_requests_.clear();
+
+  if (view_)
+    FinalizeBubble();
 }
 
 PermissionRequest* PermissionRequestManager::GetExistingRequest(
diff --git a/chrome/browser/permissions/permission_request_manager.h b/chrome/browser/permissions/permission_request_manager.h
index f768823..3a1be984 100644
--- a/chrome/browser/permissions/permission_request_manager.h
+++ b/chrome/browser/permissions/permission_request_manager.h
@@ -77,6 +77,7 @@
   // Temporarily hides the bubble, and destroys the prompt UI surface. Any
   // existing requests will be reshown when DisplayPendingRequests is called
   // (e.g. when switching tabs away and back to a page with a prompt).
+  // TODO(timloh): Rename this to something more fitting (e.g. TabSwitchedAway).
   void HideBubble();
 
   // Will show a permission bubble if there is a pending permission request on
@@ -152,13 +153,17 @@
   // bubble after switching tabs away and back.
   void ShowBubble();
 
-  // Finalize the pending permissions request.
+  // Delete the view object
+  void DeleteBubble();
+
+  // Delete the view object, finalize requests, asynchronously show a queued
+  // request if present.
   void FinalizeBubble();
 
-  // Cancel any pending requests. This is called if the WebContents
-  // on which permissions calls are pending is destroyed or navigated away
-  // from the requesting page.
-  void CancelPendingQueues();
+  // Cancel all pending or active requests and destroy the PermissionPrompt if
+  // one exists. This is called if the WebContents is destroyed or navigates its
+  // main frame.
+  void CleanUpRequests();
 
   // Searches |requests_|, |queued_requests_| and |queued_frame_requests_| - but
   // *not* |duplicate_requests_| - for a request matching |request|, and returns
@@ -182,8 +187,13 @@
   // Factory to be used to create views when needed.
   PermissionPrompt::Factory view_factory_;
 
-  // The UI surface to be used to display the permissions requests.
+  // The UI surface for an active permission prompt if we're displaying one.
   std::unique_ptr<PermissionPrompt> view_;
+  // We only show prompts when both of these are true. On Desktop, we hide any
+  // active prompt on tab switching, while on Android we let the infobar system
+  // handle it.
+  bool main_frame_has_fully_loaded_;
+  bool tab_can_show_prompts_;
 
   std::vector<PermissionRequest*> requests_;
   std::deque<PermissionRequest*> queued_requests_;
@@ -192,8 +202,6 @@
   std::unordered_multimap<PermissionRequest*, PermissionRequest*>
       duplicate_requests_;
 
-  bool main_frame_has_fully_loaded_;
-
   // Whether the response to each request should be persisted.
   bool persist_;
 
diff --git a/chrome/browser/permissions/permission_request_manager_unittest.cc b/chrome/browser/permissions/permission_request_manager_unittest.cc
index 0a3ba3f..1d9f2207 100644
--- a/chrome/browser/permissions/permission_request_manager_unittest.cc
+++ b/chrome/browser/permissions/permission_request_manager_unittest.cc
@@ -9,6 +9,7 @@
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/histogram_tester.h"
+#include "build/build_config.h"
 #include "chrome/browser/permissions/mock_permission_request.h"
 #include "chrome/browser/permissions/permission_request.h"
 #include "chrome/browser/permissions/permission_request_manager.h"
@@ -199,12 +200,14 @@
   EXPECT_FALSE(prompt_factory_->is_visible());
 }
 
-TEST_F(PermissionRequestManagerTest, NoView) {
+#if !defined(OS_ANDROID)
+TEST_F(PermissionRequestManagerTest, PermissionRequestWhileTabSwitchedAway) {
   manager_->AddRequest(&request1_);
-  // Don't display the pending requests.
+  // Don't mark the tab as active.
   WaitForBubbleToBeShown();
   EXPECT_FALSE(prompt_factory_->is_visible());
 }
+#endif
 
 TEST_F(PermissionRequestManagerTest, TwoRequestsDoNotCoalesce) {
   manager_->DisplayPendingRequests();
diff --git a/chrome/browser/resources/md_bookmarks/dnd_chip.html b/chrome/browser/resources/md_bookmarks/dnd_chip.html
index cac03f1a..c077500 100644
--- a/chrome/browser/resources/md_bookmarks/dnd_chip.html
+++ b/chrome/browser/resources/md_bookmarks/dnd_chip.html
@@ -64,13 +64,6 @@
         width: 24px;
       }
 
-      #icon {
-        background-repeat: no-repeat;
-        height: 16px;
-        margin: 2px;
-        width: 16px;
-      }
-
       .centered {
         align-items: center;
         display: flex;
@@ -99,9 +92,7 @@
     </div>
     <div id="primary" class="chip-container centered">
       <div id="icon-wrapper" class="centered">
-        <iron-icon id="folder-icon" icon="cr:folder" hidden$="[[!isFolder_]]">
-        </iron-icon>
-        <div id="icon" hidden$="[[isFolder_]]"></div>
+        <div id="icon"></div>
       </div>
       <div id="title"></div>
     </div>
diff --git a/chrome/browser/resources/md_bookmarks/dnd_chip.js b/chrome/browser/resources/md_bookmarks/dnd_chip.js
index 238aa35..a4108e320 100644
--- a/chrome/browser/resources/md_bookmarks/dnd_chip.js
+++ b/chrome/browser/resources/md_bookmarks/dnd_chip.js
@@ -13,9 +13,6 @@
     },
 
     /** @private */
-    isFolder_: Boolean,
-
-    /** @private */
     isMultiItem_: Boolean,
   },
 
@@ -32,10 +29,12 @@
     if (this.showing_)
       return;
 
-    this.isFolder_ = !dragItem.url;
+    var isFolder = !dragItem.url;
     this.isMultiItem_ = items.length > 1;
-    if (dragItem.url)
-      this.$.icon.style.backgroundImage = cr.icon.getFavicon(dragItem.url);
+
+    this.$.icon.className = isFolder ? 'folder-icon' : 'website-icon';
+    this.$.icon.style.backgroundImage =
+        isFolder ? null : cr.icon.getFavicon(assert(dragItem.url));
 
     this.$.title.textContent = dragItem.title;
     this.$.count.textContent = items.length;
diff --git a/chrome/browser/resources/md_bookmarks/folder_node.html b/chrome/browser/resources/md_bookmarks/folder_node.html
index 0bbd908..e94af3f3 100644
--- a/chrome/browser/resources/md_bookmarks/folder_node.html
+++ b/chrome/browser/resources/md_bookmarks/folder_node.html
@@ -5,7 +5,6 @@
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html">
 <link rel="import" href="chrome://bookmarks/actions.html">
 <link rel="import" href="chrome://bookmarks/command_manager.html">
-<link rel="import" href="chrome://bookmarks/icons.html">
 <link rel="import" href="chrome://bookmarks/shared_style.html">
 <link rel="import" href="chrome://bookmarks/store_client.html">
 
@@ -75,7 +74,7 @@
       }
 
       [no-children] {
-        -webkit-padding-start: 52px; /* The width of the arrow and its margin */
+        -webkit-margin-start: 52px; /* The width of the arrow and its margin */
       }
     </style>
 
@@ -95,9 +94,10 @@
         </button>
       </template>
       <div id="folder-label" class="v-centered">
-        <iron-icon icon="[[getFolderIcon_(isSelectedFolder_)]]"
+        <div class="folder-icon"
+            open$="[[isSelectedFolder_]]"
             no-children$="[[!hasChildFolder_]]">
-        </iron-icon>
+        </div>
         <div class="menu-label">[[item_.title]]</div>
       </div>
     </div>
diff --git a/chrome/browser/resources/md_bookmarks/folder_node.js b/chrome/browser/resources/md_bookmarks/folder_node.js
index 799a0f7..df6ac01 100644
--- a/chrome/browser/resources/md_bookmarks/folder_node.js
+++ b/chrome/browser/resources/md_bookmarks/folder_node.js
@@ -258,14 +258,6 @@
     return children.pop().getLastVisibleDescendant_();
   },
 
-  /**
-   * @private
-   * @return {string}
-   */
-  getFolderIcon_: function() {
-    return this.isSelectedFolder_ ? 'bookmarks:folder-open' : 'cr:folder';
-  },
-
   /** @private */
   selectFolder_: function() {
     if (!this.isSelectedFolder_) {
diff --git a/chrome/browser/resources/md_bookmarks/icons.html b/chrome/browser/resources/md_bookmarks/icons.html
deleted file mode 100644
index 8f96ef8..0000000
--- a/chrome/browser/resources/md_bookmarks/icons.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-iconset-svg/iron-iconset-svg.html">
-
-<iron-iconset-svg size="24" name="bookmarks">
-  <svg>
-    <defs>
-      <!--
-      These icons are copied from Polymer's iron-icons and kept in sorted order.
-      See http://goo.gl/Y1OdAq for instructions on adding additional icons.
-      -->
-      <g id="folder-open"><path d="M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 12H4V8h16v10z"></path></g>
-    </defs>
-  </svg>
-</iron-iconset-svg>
diff --git a/chrome/browser/resources/md_bookmarks/images/folder.svg b/chrome/browser/resources/md_bookmarks/images/folder.svg
new file mode 100644
index 0000000..d9c1426
--- /dev/null
+++ b/chrome/browser/resources/md_bookmarks/images/folder.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#757575">
+  <path d="M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"></path>
+</svg>
diff --git a/chrome/browser/resources/md_bookmarks/images/folder_open.svg b/chrome/browser/resources/md_bookmarks/images/folder_open.svg
new file mode 100644
index 0000000..0ad4331c
--- /dev/null
+++ b/chrome/browser/resources/md_bookmarks/images/folder_open.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#4285F4">
+  <path d="M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 12H4V8h16v10z"></path>
+</svg>
diff --git a/chrome/browser/resources/md_bookmarks/item.html b/chrome/browser/resources/md_bookmarks/item.html
index 06ba2df..398affb 100644
--- a/chrome/browser/resources/md_bookmarks/item.html
+++ b/chrome/browser/resources/md_bookmarks/item.html
@@ -1,8 +1,6 @@
 <link rel="import" href="chrome://resources/html/polymer.html">
 
-<link rel="import" href="chrome://resources/cr_elements/icons.html">
 <link rel="import" href="chrome://resources/html/icon.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html">
 <link rel="import" href="chrome://bookmarks/actions.html">
 <link rel="import" href="chrome://bookmarks/shared_style.html">
@@ -32,6 +30,7 @@
       }
 
       #website-title {
+        -webkit-margin-start: 20px;
         flex: 1;
         overflow: hidden;
         text-decoration: none;
@@ -39,19 +38,8 @@
         white-space: nowrap;
       }
 
-      #icon-wrapper {
-        -webkit-margin-end: 20px;
-        color: var(--secondary-text-color);
-        display: flex;
-        height: 20px;
-        width: 20px;
-      }
-
       #icon {
-        background-repeat: no-repeat;
-        height: 16px;
-        margin: 2px;
-        width: 16px;
+        color: var(--secondary-text-color);
       }
 
       button.more-vert-button {
@@ -59,11 +47,7 @@
       }
     </style>
     <div id="url">
-      <div id="icon-wrapper">
-        <iron-icon id="folder-icon" icon="cr:folder" hidden$="[[!isFolder_]]">
-        </iron-icon>
-        <div id="icon" hidden$="[[isFolder_]]"></div>
-      </div>
+      <div id="icon"></div>
       <div id="website-title">
         [[item_.title]]
       </div>
diff --git a/chrome/browser/resources/md_bookmarks/item.js b/chrome/browser/resources/md_bookmarks/item.js
index 8bec904e..d7103dc 100644
--- a/chrome/browser/resources/md_bookmarks/item.js
+++ b/chrome/browser/resources/md_bookmarks/item.js
@@ -163,6 +163,7 @@
    * @private
    */
   updateFavicon_: function(url) {
-    this.$.icon.style.backgroundImage = cr.icon.getFavicon(url);
+    this.$.icon.className = url ? 'website-icon' : 'folder-icon';
+    this.$.icon.style.backgroundImage = url ? cr.icon.getFavicon(url) : null;
   },
 });
diff --git a/chrome/browser/resources/md_bookmarks/shared_style.html b/chrome/browser/resources/md_bookmarks/shared_style.html
index 0ccc1dd..790386a 100644
--- a/chrome/browser/resources/md_bookmarks/shared_style.html
+++ b/chrome/browser/resources/md_bookmarks/shared_style.html
@@ -58,6 +58,25 @@
       :host-context([hide-focus-ring]) [tabindex]:focus {
         outline: none;
       }
+
+      .folder-icon {
+        background-image: url(chrome://bookmarks/images/folder.svg);
+        background-size: contain;
+        height: 20px;
+        min-width: 20px;
+        width: 20px;
+      }
+
+      .folder-icon[open] {
+        background-image: url(chrome://bookmarks/images/folder_open.svg);
+      }
+
+      .website-icon {
+        background-repeat: no-repeat;
+        height: 16px;
+        margin: 2px;
+        width: 16px;
+      }
     </style>
   </template>
 </dom-module>
diff --git a/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.cc b/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.cc
index 6bf4e72..12316c4 100644
--- a/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.cc
+++ b/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.cc
@@ -108,10 +108,17 @@
   AddLocalizedString(source, "undo", IDS_BOOKMARK_BAR_UNDO);
 
   // Resources.
+  source->AddResourcePath("images/folder_open.svg",
+                          IDR_MD_BOOKMARKS_IMAGES_FOLDER_OPEN_SVG);
+  source->AddResourcePath("images/folder.svg",
+                          IDR_MD_BOOKMARKS_IMAGES_FOLDER_SVG);
 #if BUILDFLAG(USE_VULCANIZE)
   source->AddResourcePath("crisper.js", IDR_MD_BOOKMARKS_CRISPER_JS);
   source->SetDefaultResource(IDR_MD_BOOKMARKS_VULCANIZED_HTML);
-  source->UseGzip(std::unordered_set<std::string>());
+  std::unordered_set<std::string> exclusions;
+  exclusions.insert("images/folder_open.svg");
+  exclusions.insert("images/folder.svg");
+  source->UseGzip(exclusions);
 #else
   source->AddResourcePath("actions.html", IDR_MD_BOOKMARKS_ACTIONS_HTML);
   source->AddResourcePath("actions.js", IDR_MD_BOOKMARKS_ACTIONS_JS);
@@ -142,7 +149,6 @@
                           IDR_MD_BOOKMARKS_FOLDER_NODE_HTML);
   source->AddResourcePath("folder_node.js",
                           IDR_MD_BOOKMARKS_FOLDER_NODE_JS);
-  source->AddResourcePath("icons.html", IDR_MD_BOOKMARKS_ICONS_HTML);
   source->AddResourcePath("item.html", IDR_MD_BOOKMARKS_ITEM_HTML);
   source->AddResourcePath("item.js", IDR_MD_BOOKMARKS_ITEM_JS);
   source->AddResourcePath("list.html", IDR_MD_BOOKMARKS_LIST_HTML);
diff --git a/chrome/test/data/webui/md_bookmarks/item_test.js b/chrome/test/data/webui/md_bookmarks/item_test.js
index d03968a..903780a 100644
--- a/chrome/test/data/webui/md_bookmarks/item_test.js
+++ b/chrome/test/data/webui/md_bookmarks/item_test.js
@@ -32,14 +32,12 @@
 
   test('changing to folder hides/unhides the folder/icon', function() {
     // Starts test as an item.
-    assertTrue(item.$['folder-icon'].hidden);
-    assertFalse(item.$.icon.hidden);
+    assertEquals('website-icon', item.$.icon.className);
 
     // Change to a folder.
     item.itemId = '1';
 
-    assertFalse(item.$['folder-icon'].hidden);
-    assertTrue(item.$.icon.hidden);
+    assertEquals('folder-icon', item.$.icon.className);
   });
 
   test('pressing the menu button selects the item', function() {
diff --git a/testing/libfuzzer/fuzzers/skia_color_space_fuzzer.cc b/testing/libfuzzer/fuzzers/skia_color_space_fuzzer.cc
index c53f474..af0284f 100644
--- a/testing/libfuzzer/fuzzers/skia_color_space_fuzzer.cc
+++ b/testing/libfuzzer/fuzzers/skia_color_space_fuzzer.cc
@@ -37,10 +37,11 @@
 
   static uint32_t output[kPixels * 4];
 
-  const auto color = SkColorSpaceXform::ColorFormat(hash & 7);
-  const auto alpha = SkAlphaType(hash >> 3 & 3);
+  const auto form1 = SkColorSpaceXform::ColorFormat(hash >> 0 & 7);
+  const auto form2 = SkColorSpaceXform::ColorFormat(hash >> 3 & 7);
+  const auto alpha = SkAlphaType(hash >> 6 & 3);
 
-  transform->apply(color, output, color, pixels, kPixels, alpha);
+  transform->apply(form1, output, form2, pixels, kPixels, alpha);
 }
 
 static sk_sp<SkColorSpace> SelectProfile(size_t hash) {
diff --git a/ui/platform_window/mojo/OWNERS b/ui/platform_window/mojo/OWNERS
index a166098..5d54957 100644
--- a/ui/platform_window/mojo/OWNERS
+++ b/ui/platform_window/mojo/OWNERS
@@ -1,2 +1,5 @@
 per-file *_type_converter*.*=set noparent
 per-file *_type_converter*.*=file://ipc/SECURITY_OWNERS
+
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/ui/platform_window/mojo/ime_type_converters.cc b/ui/platform_window/mojo/ime_type_converters.cc
index 2edc9bb..c256b51 100644
--- a/ui/platform_window/mojo/ime_type_converters.cc
+++ b/ui/platform_window/mojo/ime_type_converters.cc
@@ -29,6 +29,9 @@
 TEXT_INPUT_TYPE_ASSERT(TIME);
 TEXT_INPUT_TYPE_ASSERT(WEEK);
 TEXT_INPUT_TYPE_ASSERT(TEXT_AREA);
+TEXT_INPUT_TYPE_ASSERT(CONTENT_EDITABLE);
+TEXT_INPUT_TYPE_ASSERT(DATE_TIME_FIELD);
+TEXT_INPUT_TYPE_ASSERT(MAX);
 
 #define TEXT_INPUT_FLAG_ASSERT(NAME)                                  \
   static_assert(static_cast<int32_t>(TextInputFlag::NAME) ==          \
diff --git a/ui/platform_window/mojo/text_input_state.mojom b/ui/platform_window/mojo/text_input_state.mojom
index a816929..10a293c 100644
--- a/ui/platform_window/mojo/text_input_state.mojom
+++ b/ui/platform_window/mojo/text_input_state.mojom
@@ -21,7 +21,9 @@
   TIME,
   WEEK,
   TEXT_AREA,
-  LAST = TEXT_AREA,
+  CONTENT_EDITABLE,
+  DATE_TIME_FIELD,
+  MAX = DATE_TIME_FIELD,
 };
 
 // Text input flag which is based on blink::WebTextInputFlags.