Merge from Chromium at DEPS revision 30.0.1599.24

This commit was generated by merge_to_master.py.

Change-Id: I47a298aa10fc926ad89054fcefe14a7938feddb8
diff --git a/android_webview/browser/renderer_host/aw_render_view_host_ext.cc b/android_webview/browser/renderer_host/aw_render_view_host_ext.cc
index 95f2358..78d6cf4 100644
--- a/android_webview/browser/renderer_host/aw_render_view_host_ext.cc
+++ b/android_webview/browser/renderer_host/aw_render_view_host_ext.cc
@@ -96,6 +96,10 @@
   }
 }
 
+void AwRenderViewHostExt::SetJsOnlineProperty(bool network_up) {
+  Send(new AwViewMsg_SetJsOnlineProperty(network_up));
+}
+
 void AwRenderViewHostExt::RenderViewCreated(
     content::RenderViewHost* render_view_host) {
   Send(new AwViewMsg_SetBackgroundColor(web_contents()->GetRoutingID(),
diff --git a/android_webview/browser/renderer_host/aw_render_view_host_ext.h b/android_webview/browser/renderer_host/aw_render_view_host_ext.h
index da9bcac..3007f15 100644
--- a/android_webview/browser/renderer_host/aw_render_view_host_ext.h
+++ b/android_webview/browser/renderer_host/aw_render_view_host_ext.h
@@ -72,6 +72,7 @@
   // the meta viewport tag.
   void SetInitialPageScale(double page_scale_factor);
   void SetBackgroundColor(SkColor c);
+  void SetJsOnlineProperty(bool network_up);
 
  private:
   // content::WebContentsObserver implementation.
diff --git a/android_webview/common/render_view_messages.h b/android_webview/common/render_view_messages.h
index 69f826c..96d1758 100644
--- a/android_webview/common/render_view_messages.h
+++ b/android_webview/common/render_view_messages.h
@@ -71,6 +71,9 @@
 IPC_MESSAGE_ROUTED1(AwViewMsg_SetBackgroundColor,
                     SkColor);
 
+IPC_MESSAGE_CONTROL1(AwViewMsg_SetJsOnlineProperty,
+                     bool /* network_up */)
+
 //-----------------------------------------------------------------------------
 // RenderView messages
 // These are messages sent from the renderer to the browser process.
@@ -87,4 +90,3 @@
 // Sent whenever the page scale factor (as seen by RenderView) is changed.
 IPC_MESSAGE_ROUTED1(AwViewHostMsg_PageScaleFactorChanged,
                     float /* page_scale_factor */)
-
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java
index 061a6ff..4dc3c67 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -1656,6 +1656,11 @@
             mAwAutofillManagerDelegate.hideAutofillPopup();
     }
 
+    public void setNetworkAvailable(boolean networkUp) {
+        if (mNativeAwContents == 0) return;
+        nativeSetJsOnlineProperty(mNativeAwContents, networkUp);
+    }
+
     //--------------------------------------------------------------------------------------------
     //  Methods called from native via JNI
     //--------------------------------------------------------------------------------------------
@@ -1934,4 +1939,6 @@
 
     private native void nativeInvokeGeolocationCallback(
             int nativeAwContents, boolean value, String requestingFrame);
+
+    private native void nativeSetJsOnlineProperty(int nativeAwContents, boolean networkUp);
 }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java
index 455d30b..6d508ed 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java
@@ -392,4 +392,29 @@
             if (webServer != null) webServer.shutdown();
         }
     }
+
+    @Feature({"AndroidWebView", "setNetworkAvailable"})
+    @SmallTest
+    public void testSetNetworkAvailable() throws Throwable {
+        AwTestContainerView testView = createAwTestContainerViewOnMainSync(mContentsClient);
+        AwContents awContents = testView.getAwContents();
+        String SCRIPT = "navigator.onLine";
+
+        enableJavaScriptOnUiThread(awContents);
+        loadUrlSync(awContents, mContentsClient.getOnPageFinishedHelper(), "about:blank");
+
+        // Default to "online".
+        assertEquals("true", executeJavaScriptAndWaitForResult(awContents, mContentsClient,
+              SCRIPT));
+
+        // Forcing "offline".
+        awContents.setNetworkAvailable(false);
+        assertEquals("false", executeJavaScriptAndWaitForResult(awContents, mContentsClient,
+              SCRIPT));
+
+        // Forcing "online".
+        awContents.setNetworkAvailable(true);
+        assertEquals("true", executeJavaScriptAndWaitForResult(awContents, mContentsClient,
+              SCRIPT));
+    }
 }
diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc
index eb2975c..b46ff9e 100644
--- a/android_webview/native/aw_contents.cc
+++ b/android_webview/native/aw_contents.cc
@@ -793,4 +793,10 @@
   browser_view_renderer_->EnableOnNewPicture(enabled);
 }
 
+void AwContents::SetJsOnlineProperty(JNIEnv* env,
+                                     jobject obj,
+                                     jboolean network_up) {
+  render_view_host_ext_->SetJsOnlineProperty(network_up);
+}
+
 }  // namespace android_webview
diff --git a/android_webview/native/aw_contents.h b/android_webview/native/aw_contents.h
index 245a085..054249b 100644
--- a/android_webview/native/aw_contents.h
+++ b/android_webview/native/aw_contents.h
@@ -182,6 +182,9 @@
 
   // Sets the java delegate
   void SetAwAutofillManagerDelegate(jobject delegate);
+
+  void SetJsOnlineProperty(JNIEnv* env, jobject obj, jboolean network_up);
+
  private:
   void InitAutofillIfNecessary(bool enabled);
 
diff --git a/android_webview/renderer/aw_render_process_observer.cc b/android_webview/renderer/aw_render_process_observer.cc
index 5e3ecca..561580c 100644
--- a/android_webview/renderer/aw_render_process_observer.cc
+++ b/android_webview/renderer/aw_render_process_observer.cc
@@ -7,6 +7,7 @@
 #include "android_webview/common/render_view_messages.h"
 #include "ipc/ipc_message_macros.h"
 #include "third_party/WebKit/public/web/WebCache.h"
+#include "third_party/WebKit/public/web/WebNetworkStateNotifier.h"
 
 namespace android_webview {
 
@@ -22,6 +23,7 @@
   bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(AwRenderProcessObserver, message)
     IPC_MESSAGE_HANDLER(AwViewMsg_ClearCache, OnClearCache)
+    IPC_MESSAGE_HANDLER(AwViewMsg_SetJsOnlineProperty, OnSetJsOnlineProperty)
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   return handled;
@@ -36,4 +38,9 @@
     WebKit::WebCache::clear();
 }
 
+void AwRenderProcessObserver::OnSetJsOnlineProperty(bool network_up) {
+  if (webkit_initialized_)
+    WebKit::WebNetworkStateNotifier::setOnLine(network_up);
+}
+
 }  // nanemspace android_webview
diff --git a/android_webview/renderer/aw_render_process_observer.h b/android_webview/renderer/aw_render_process_observer.h
index 5a5a8f9..2cb4d2f 100644
--- a/android_webview/renderer/aw_render_process_observer.h
+++ b/android_webview/renderer/aw_render_process_observer.h
@@ -24,6 +24,7 @@
 
  private:
   void OnClearCache();
+  void OnSetJsOnlineProperty(bool network_up);
 
   bool webkit_initialized_;
 };
diff --git a/ash/wm/window_animations.cc b/ash/wm/window_animations.cc
index a3c0ca8..73deafd 100644
--- a/ash/wm/window_animations.cc
+++ b/ash/wm/window_animations.cc
@@ -295,6 +295,9 @@
     // Triggers OnImplicitAnimationsCompleted() to be called and deletes us.
     layer_->GetAnimator()->StopAnimating();
   }
+  virtual void OnWindowRemovingFromRootWindow(aura::Window* window) OVERRIDE {
+    layer_->GetAnimator()->StopAnimating();
+  }
 
   // ui::ImplicitAnimationObserver overrides:
   virtual void OnImplicitAnimationsCompleted() OVERRIDE {
diff --git a/build/util/LASTCHANGE b/build/util/LASTCHANGE
index a542ae0..2591325 100644
--- a/build/util/LASTCHANGE
+++ b/build/util/LASTCHANGE
@@ -1 +1 @@
-LASTCHANGE=219849
+LASTCHANGE=220120
diff --git a/chrome/VERSION b/chrome/VERSION
index e74d12a..38514d5 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=30
 MINOR=0
 BUILD=1599
-PATCH=22
+PATCH=23
diff --git a/chrome/browser/chromeos/audio/audio_devices_pref_handler_impl.cc b/chrome/browser/chromeos/audio/audio_devices_pref_handler_impl.cc
index e208979..2d25fb8 100644
--- a/chrome/browser/chromeos/audio/audio_devices_pref_handler_impl.cc
+++ b/chrome/browser/chromeos/audio/audio_devices_pref_handler_impl.cc
@@ -45,7 +45,6 @@
 
 void AudioDevicesPrefHandlerImpl::SetVolumeGainValue(
     const AudioDevice& device, double value) {
-  value = std::min(std::max(value, 0.0), 100.0);
   device_volume_settings_->SetDouble(GetDeviceIdString(device), value);
 
   SaveDevicesVolumePref();
diff --git a/chrome/browser/printing/printing_message_filter.cc b/chrome/browser/printing/printing_message_filter.cc
index 2f8eb10..7c66ae8 100644
--- a/chrome/browser/printing/printing_message_filter.cc
+++ b/chrome/browser/printing/printing_message_filter.cc
@@ -361,6 +361,11 @@
     scoped_refptr<printing::PrinterQuery> printer_query,
     IPC::Message* reply_msg) {
   PrintMsg_PrintPages_Params params;
+#if defined(OS_ANDROID)
+  // We need to save the routing ID here because Send method below deletes the
+  // |reply_msg| before we can get the routing ID for the Android code.
+  int routing_id = reply_msg->routing_id();
+#endif
   if (printer_query->last_status() != printing::PrintingContext::OK ||
       !printer_query->settings().dpi()) {
     params.Reset();
@@ -380,7 +385,7 @@
       BrowserThread::PostTask(
           BrowserThread::UI, FROM_HERE,
           base::Bind(&PrintingMessageFilter::UpdateFileDescriptor, this,
-                     reply_msg->routing_id(), file_descriptor));
+                     routing_id, file_descriptor));
     }
 #endif
     print_job_manager_->QueuePrinterQuery(printer_query.get());
diff --git a/chrome/browser/resources/file_manager/css/file_manager.css b/chrome/browser/resources/file_manager/css/file_manager.css
index a8da017..3aa28b9 100644
--- a/chrome/browser/resources/file_manager/css/file_manager.css
+++ b/chrome/browser/resources/file_manager/css/file_manager.css
@@ -476,6 +476,7 @@
   -webkit-box-orient: horizontal;
   border-top: 1px solid rgb(225, 225, 225);
   display: -webkit-box;
+  outline: none;
   padding: 10px;
 }
 
diff --git a/chrome/browser/resources/file_manager/js/file_manager.js b/chrome/browser/resources/file_manager/js/file_manager.js
index 9ef23dc..32e7da6 100644
--- a/chrome/browser/resources/file_manager/js/file_manager.js
+++ b/chrome/browser/resources/file_manager/js/file_manager.js
@@ -563,6 +563,11 @@
     CommandUtil.registerCommand(this.dialogContainer_, 'newfolder',
         Commands.newFolderCommand, this, this.directoryModel_);
 
+    // Required to handle the command outside of the container, on the footer.
+    // TODO(mtomasz): Remove after fixing crbug.com/275235.
+    CommandUtil.registerCommand(this.dialogDom_.querySelector('.dialog-footer'),
+        'newfolder', Commands.newFolderCommand, this, this.directoryModel_);
+
     CommandUtil.registerCommand(this.dialogContainer_, 'newwindow',
         Commands.newWindowCommand, this, this.directoryModel_);
 
@@ -1209,7 +1214,10 @@
    */
   FileManager.prototype.updateMiddleBarVisibility_ = function() {
     var currentPath = this.directoryModel_.getCurrentDirPath();
-    var visible = DirectoryTreeUtil.isEligiblePathForDirectoryTree(currentPath);
+    var driveStatus = this.volumeManager_.getDriveStatus();
+    var visible =
+        DirectoryTreeUtil.isEligiblePathForDirectoryTree(currentPath) &&
+        driveStatus == VolumeManager.DriveStatus.MOUNTED;
     this.dialogDom_.
         querySelector('.dialog-middlebar-contents').hidden = !visible;
     this.dialogDom_.querySelector('#middlebar-splitter').hidden = !visible;
diff --git a/chrome/browser/resources/file_manager/main.html b/chrome/browser/resources/file_manager/main.html
index d2b05db..c292925 100644
--- a/chrome/browser/resources/file_manager/main.html
+++ b/chrome/browser/resources/file_manager/main.html
@@ -363,7 +363,8 @@
             <div class=progress-bar>
               <div class=progress-track></div>
             </div>
-            <div class="right buttonbar" id="open-panel" visibleif="open-file open-multi-file">
+            <div class="right buttonbar" id="open-panel"
+                 visibleif="open-file open-multi-file">
               <select class="file-type"></select>
               <button class=ok disabled tabindex="7"></button>
               <button class=cancel i18n-content=CANCEL_LABEL tabindex="8"></button>
@@ -377,7 +378,8 @@
         </div>
       </div>
     </div>
-    <div class="dialog-footer progressable" visibleif="saveas-file folder">
+    <div class="dialog-footer progressable" tabindex="-1"
+         visibleif="saveas-file folder">
       <div class="left">
         <button id="new-folder" i18n-content=NEW_FOLDER_BUTTON_LABEL
                 visibleif="saveas-file folder" command="#newfolder"
diff --git a/chrome/browser/resources/history/history.css b/chrome/browser/resources/history/history.css
index 6d41422..61bddb3 100644
--- a/chrome/browser/resources/history/history.css
+++ b/chrome/browser/resources/history/history.css
@@ -572,6 +572,10 @@
   outline: none;
 }
 
+body:not(.has-results) #results-pagination {
+  display: none;
+}
+
 #older-button {
   float: right;
 }
diff --git a/chrome/browser/resources/history/history.js b/chrome/browser/resources/history/history.js
index 9d8ceba..1227c99 100644
--- a/chrome/browser/resources/history/history.js
+++ b/chrome/browser/resources/history/history.js
@@ -929,14 +929,15 @@
  */
 HistoryView.prototype.onModelReady = function(doneLoading) {
   this.displayResults_(doneLoading);
-  this.updateNavBar_();
 
-  if (isMobileVersion()) {
-    // Hide the search field if it is empty and there are no results.
-    var hasResults = this.model_.visits_.length > 0;
-    var isSearch = this.model_.getSearchText().length > 0;
-    $('search-field').hidden = !(hasResults || isSearch);
-  }
+  // Allow custom styling based on whether there are any results on the page.
+  // To make this easier, add a class to the body if there are any results.
+  if (this.model_.visits_.length)
+    document.body.classList.add('has-results');
+  else
+    document.body.classList.remove('has-results');
+
+  this.updateNavBar_();
 };
 
 /**
@@ -1297,6 +1298,7 @@
           createElementWithClassName('div', 'no-results-message'));
       noResults.textContent = loadTimeData.getString('noResults');
       this.resultDiv_.appendChild(resultsFragment);
+      this.updateNavBar_();
       return;
     }
 
@@ -1324,6 +1326,7 @@
     // Add all the days and their visits to the page.
     this.resultDiv_.appendChild(resultsFragment);
   }
+  this.updateNavBar_();
 };
 
 /**
@@ -1332,10 +1335,9 @@
  */
 HistoryView.prototype.updateNavBar_ = function() {
   this.updateRangeButtons_();
-
-  // Managed users have the control bar on top, don't show it on the bottom
-  // as well.
   if (!loadTimeData.getBoolean('isManagedProfile')) {
+    // Managed users have the control bar on top, don't show it on the bottom
+    // as well.
     $('newest-button').hidden = this.pageIndex_ == 0;
     $('newer-button').hidden = this.pageIndex_ == 0;
     $('older-button').hidden =
diff --git a/chrome/browser/resources/history/history_mobile.css b/chrome/browser/resources/history/history_mobile.css
index 3011289..41268f5 100644
--- a/chrome/browser/resources/history/history_mobile.css
+++ b/chrome/browser/resources/history/history_mobile.css
@@ -66,6 +66,11 @@
   background-position: right 16px center;
 }
 
+/* Hide the search field if it is empty (!valid) and there are no results. */
+body:not(.has-results) #search-field:not(:valid) {
+  display: none;
+}
+
 .no-results-message {
   margin-bottom: 1em;
   padding-left: 16px;
diff --git a/chrome/browser/resources/options/managed_user_create_confirm.css b/chrome/browser/resources/options/managed_user_create_confirm.css
index 37b3770..a1e8af8 100644
--- a/chrome/browser/resources/options/managed_user_create_confirm.css
+++ b/chrome/browser/resources/options/managed_user_create_confirm.css
@@ -7,18 +7,31 @@
 }
 
 #managed-user-created-title {
+  padding: 20px;
   word-wrap: break-word;
 }
 
+@media only screen and (max-height:400px) {
+
+/* Omit the image on very small screens. */
 #managed-user-created-image {
+  display: none;
+}
+
+} /* @media only screen and (max-height:400px) */
+
+#managed-user-created-image {
+  -webkit-border-radius: 3px 3px 0 0;
+  -webkit-box-flex: 5;
   background-image: -webkit-image-set(
       url('../../../../ui/resources/default_100_percent/supervised_illustration_done.png') 1x,
       url('../../../../ui/resources/default_200_percent/supervised_illustration_done.png') 2x);
+  background-position: center;
   height: 344px;
 }
 
 #managed-user-created-text {
-  margin-top: 10px;
+  padding: 0 20px 0 20px;
   white-space: pre-wrap;
   word-wrap: break-word;
 }
@@ -27,3 +40,7 @@
   max-width: 600px;
   word-wrap: break-word;
 }
+
+#managed-user-created-action-area {
+  padding: 20px;
+}
diff --git a/chrome/browser/resources/options/managed_user_create_confirm.html b/chrome/browser/resources/options/managed_user_create_confirm.html
index c7c9b90..346b9f0 100644
--- a/chrome/browser/resources/options/managed_user_create_confirm.html
+++ b/chrome/browser/resources/options/managed_user_create_confirm.html
@@ -1,12 +1,10 @@
 <div id="managed-user-created" class="page" hidden>
   <div class="close-button"></div>
   <!-- Overlay for the confirmation after creating a supervised user. -->
+  <div id="managed-user-created-image"></div>
   <h1 id="managed-user-created-title"></h1>
-  <div class="content-area">
-    <div id="managed-user-created-image"></div>
-    <div id="managed-user-created-text"></div>
-  </div>
-  <div class="action-area button-strip">
+  <div id="managed-user-created-text" class="content-area"></div>
+  <div id="managed-user-created-action-area" class="action-area button-strip">
     <button id="managed-user-created-done"
         i18n-content="managedUserCreatedDone">
     </button>
diff --git a/chrome/browser/resources/options/managed_user_learn_more.css b/chrome/browser/resources/options/managed_user_learn_more.css
index 79878ee..d22a9a7 100644
--- a/chrome/browser/resources/options/managed_user_learn_more.css
+++ b/chrome/browser/resources/options/managed_user_learn_more.css
@@ -6,15 +6,35 @@
   width: 722px;
 }
 
+#managed-user-learn-more-title {
+  padding: 20px;
+}
+
 #managed-user-learn-more-text {
-  margin-top: 10px;
+  padding: 0 20px 0 20px;
   white-space: pre-wrap;
   word-wrap: break-word;
 }
 
+@media only screen and (max-height:500px) {
+
+/* Omit the image on very small screens. */
 #managed-user-learn-more-image {
+  display: none;
+}
+
+} /* @media only screen and (max-height:500px) */
+
+#managed-user-learn-more-image {
+  -webkit-border-radius: 3px 3px 0 0;
+  -webkit-box-flex: 1;
   background-image: -webkit-image-set(
       url('../../../../ui/resources/default_100_percent/supervised_illustration_start.png') 1x,
       url('../../../../ui/resources/default_200_percent/supervised_illustration_start.png') 2x);
+  background-position: center;
   height: 344px;
 }
+
+#managed-user-learn-more-action-area {
+  padding: 20px;
+}
diff --git a/chrome/browser/resources/options/managed_user_learn_more.html b/chrome/browser/resources/options/managed_user_learn_more.html
index e0b2c62..0698546 100644
--- a/chrome/browser/resources/options/managed_user_learn_more.html
+++ b/chrome/browser/resources/options/managed_user_learn_more.html
@@ -1,14 +1,15 @@
 <div id="managed-user-learn-more" class="page" hidden>
   <div class="close-button"></div>
   <!-- Overlay for the 'Learn more' link when creating a supervised user. -->
-  <h1 i18n-content="managedUserLearnMoreTitle"></h1>
-  <div class="content-area">
-    <div id="managed-user-learn-more-image"></div>
-    <div id="managed-user-learn-more-text"
-        i18n-content="managedUserLearnMoreText">
-    </div>
+  <div id="managed-user-learn-more-image"></div>
+  <h1 id="managed-user-learn-more-title"
+      i18n-content="managedUserLearnMoreTitle">
+  </h1>
+  <div id="managed-user-learn-more-text" class="content-area"
+      i18n-content="managedUserLearnMoreText">
   </div>
-  <div class="action-area button-strip">
+  <div id="managed-user-learn-more-action-area"
+      class="action-area button-strip">
     <button id="managed-user-learn-more-done"
         i18n-content="managedUserLearnMoreDone">
     </button>
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.cc b/chrome/browser/ui/webui/options/browser_options_handler.cc
index 32b0823..5ddfd2b 100644
--- a/chrome/browser/ui/webui/options/browser_options_handler.cc
+++ b/chrome/browser/ui/webui/options/browser_options_handler.cc
@@ -510,7 +510,7 @@
 
   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
   values->SetBoolean("enableStickyKeys",
-                     !command_line.HasSwitch(switches::kDisableStickyKeys));
+                     command_line.HasSwitch(switches::kEnableStickyKeys));
 #endif
 
 #if defined(OS_MACOSX)
diff --git a/chromeos/audio/cras_audio_handler.cc b/chromeos/audio/cras_audio_handler.cc
index 15911ed..3fa81cb 100644
--- a/chromeos/audio/cras_audio_handler.cc
+++ b/chromeos/audio/cras_audio_handler.cc
@@ -199,10 +199,10 @@
   FOR_EACH_OBSERVER(AudioObserver, observers_, OnOutputVolumeChanged());
 }
 
+// TODO: Rename the 'Percent' to something more meaningful.
 void CrasAudioHandler::SetInputGainPercent(int gain_percent) {
-  gain_percent = min(max(gain_percent, 0), 100);
-  if (gain_percent <= kMuteThresholdPercent)
-    gain_percent = 0;
+  // NOTE: We do not sanitize input gain values since the range is completely
+  // dependent on the device.
   input_gain_ = gain_percent;
 
   if (const AudioDevice* device = GetDeviceFromId(active_input_node_id_))
@@ -268,12 +268,14 @@
     return;
   }
 
-  value = min(max(value, 0), 100);
-  if (value <= kMuteThresholdPercent)
-    value = 0;
-
-  if (const AudioDevice* device = GetDeviceFromId(device_id))
+  if (const AudioDevice* device = GetDeviceFromId(device_id)) {
+    if (!device->is_input) {
+      value = min(max(value, 0), 100);
+      if (value <= kMuteThresholdPercent)
+        value = 0;
+    }
     audio_pref_handler_->SetVolumeGainValue(*device, value);
+  }
 }
 
 void CrasAudioHandler::SetMuteForDevice(uint64 device_id, bool mute_on) {
@@ -379,7 +381,8 @@
   input_mute_on_ = audio_pref_handler_->GetMuteValue(*device);
   input_gain_ = audio_pref_handler_->GetVolumeGainValue(*device);
   SetInputMuteInternal(input_mute_on_);
-  SetInputNodeGain(active_input_node_id_, input_gain_);
+  // TODO(rkc,jennyz): Set input gain once we decide on how to store
+  // the gain values since the range and step are both device specific.
 }
 
 void CrasAudioHandler::SetupAudioOutputState() {
@@ -391,6 +394,7 @@
   }
   output_mute_on_ = audio_pref_handler_->GetMuteValue(*device);
   output_volume_ = audio_pref_handler_->GetVolumeGainValue(*device);
+
   SetOutputMuteInternal(output_mute_on_);
   SetOutputNodeVolume(active_output_node_id_, output_volume_);
 }
diff --git a/content/browser/android/web_contents_observer_android.cc b/content/browser/android/web_contents_observer_android.cc
index 67d8482..eac49b2 100644
--- a/content/browser/android/web_contents_observer_android.cc
+++ b/content/browser/android/web_contents_observer_android.cc
@@ -15,6 +15,7 @@
 #include "content/browser/renderer_host/render_widget_host_impl.h"
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/public/browser/navigation_details.h"
+#include "content/public/browser/navigation_entry.h"
 #include "jni/WebContentsObserverAndroid_jni.h"
 
 using base::android::AttachCurrentThread;
@@ -78,8 +79,19 @@
   ScopedJavaLocalRef<jobject> obj(weak_java_observer_.get(env));
   if (obj.is_null())
     return;
+
+  std::string url_string;
+  NavigationEntry* entry =
+    web_contents()->GetController().GetLastCommittedEntry();
+  // Not that GetBaseURLForDataURL is only used by the Android WebView
+  if (entry && !entry->GetBaseURLForDataURL().is_empty()) {
+    url_string = entry->GetBaseURLForDataURL().possibly_invalid_spec();
+  } else {
+    url_string = web_contents()->GetURL().spec();
+  }
+
   ScopedJavaLocalRef<jstring> jstring_url(
-      ConvertUTF8ToJavaString(env, web_contents()->GetURL().spec()));
+      ConvertUTF8ToJavaString(env, url_string));
   Java_WebContentsObserverAndroid_didStopLoading(
       env, obj.obj(), jstring_url.obj());
 }
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index 25804ae..120c128 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -29,7 +29,10 @@
 #endif  // !defined(GOOGLE_TV)
   bool enable_webaudio = false;
 #if defined(ARCH_CPU_ARMEL)
+  // WebAudio needs Android MediaCodec API that was introduced in
+  // JellyBean, and also currently needs NEON support for the FFT.
   enable_webaudio =
+      (base::android::BuildInfo::GetInstance()->sdk_int() >= 16) &&
       ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0);
 #endif  // defined(ARCH_CPU_ARMEL)
   WebRuntimeFeatures::enableWebAudio(enable_webaudio);
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java
index 37fd170..0580af0 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java
@@ -9,6 +9,7 @@
 import android.os.Handler;
 import android.os.SystemClock;
 import android.util.Log;
+import android.view.InputDevice;
 import android.view.MotionEvent;
 import android.view.ViewConfiguration;
 
@@ -814,16 +815,11 @@
      * FrameLoader::transitionToCommitted iff the page ever had touch handlers.
      */
     void resetGestureHandlers() {
-        {
-            MotionEvent me = obtainActionCancelMotionEvent();
-            mGestureDetector.onTouchEvent(me);
-            me.recycle();
-        }
-        {
-            MotionEvent me = obtainActionCancelMotionEvent();
-            mZoomManager.processTouchEvent(me);
-            me.recycle();
-        }
+        MotionEvent me = obtainActionCancelMotionEvent();
+        me.setSource(InputDevice.SOURCE_CLASS_POINTER);
+        mGestureDetector.onTouchEvent(me);
+        mZoomManager.processTouchEvent(me);
+        me.recycle();
         mLongPressDetector.cancelLongPress();
     }
 
diff --git a/media/audio/android/audio_manager_android.cc b/media/audio/android/audio_manager_android.cc
index 69bd2b8..164344a 100644
--- a/media/audio/android/audio_manager_android.cc
+++ b/media/audio/android/audio_manager_android.cc
@@ -59,11 +59,16 @@
 
 AudioParameters AudioManagerAndroid::GetInputStreamParameters(
     const std::string& device_id) {
+  // Use mono as preferred number of input channels on Android to save
+  // resources. Using mono also avoids a driver issue seen on Samsung
+  // Galaxy S3 and S4 devices. See http://crbug.com/256851 for details.
+  ChannelLayout channel_layout = CHANNEL_LAYOUT_MONO;
   int buffer_size = Java_AudioManagerAndroid_getMinInputFrameSize(
-      base::android::AttachCurrentThread(), GetNativeOutputSampleRate(), 2);
+      base::android::AttachCurrentThread(), GetNativeOutputSampleRate(),
+      ChannelLayoutToChannelCount(channel_layout));
 
   return AudioParameters(
-      AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO,
+      AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout,
       GetNativeOutputSampleRate(), 16,
       buffer_size <= 0 ? kDefaultInputBufferSize : buffer_size);
 }
diff --git a/net/disk_cache/simple/simple_index_file.cc b/net/disk_cache/simple/simple_index_file.cc
index 7bcea7c..0136be1 100644
--- a/net/disk_cache/simple/simple_index_file.cc
+++ b/net/disk_cache/simple/simple_index_file.cc
@@ -7,7 +7,6 @@
 #include <vector>
 
 #include "base/file_util.h"
-#include "base/files/file_enumerator.h"
 #include "base/files/memory_mapped_file.h"
 #include "base/hash.h"
 #include "base/logging.h"
@@ -22,11 +21,17 @@
 #include "net/disk_cache/simple/simple_util.h"
 #include "third_party/zlib/zlib.h"
 
-
+namespace disk_cache {
 namespace {
 
+const int kEntryFilesHashLength = 16;
+const int kEntryFilesSuffixLength = 2;
+
 const uint64 kMaxEntiresInIndex = 100000000;
 
+const char kIndexFileName[] = "the-real-index";
+const char kTempIndexFileName[] = "temp-index";
+
 uint32 CalculatePickleCRC(const Pickle& pickle) {
   return crc32(crc32(0, Z_NULL, 0),
                reinterpret_cast<const Bytef*>(pickle.payload()),
@@ -67,9 +72,54 @@
   }
 }
 
-}  // namespace
+// Called for each cache directory traversal iteration.
+void ProcessEntryFile(SimpleIndex::EntrySet* entries,
+                      const base::FilePath& file_path) {
+  static const size_t kEntryFilesLength =
+      kEntryFilesHashLength + kEntryFilesSuffixLength;
+  // Converting to std::string is OK since we never use UTF8 wide chars in our
+  // file names.
+  const base::FilePath::StringType base_name = file_path.BaseName().value();
+  const std::string file_name(base_name.begin(), base_name.end());
+  if (file_name.size() != kEntryFilesLength)
+    return;
+  const base::StringPiece hash_string(
+      file_name.begin(), file_name.begin() + kEntryFilesHashLength);
+  uint64 hash_key = 0;
+  if (!simple_util::GetEntryHashKeyFromHexString(hash_string, &hash_key)) {
+    LOG(WARNING) << "Invalid entry hash key filename while restoring index from"
+                 << " disk: " << file_name;
+    return;
+  }
 
-namespace disk_cache {
+  base::PlatformFileInfo file_info;
+  if (!file_util::GetFileInfo(file_path, &file_info)) {
+    LOG(ERROR) << "Could not get file info for " << file_path.value();
+    return;
+  }
+  base::Time last_used_time;
+#if defined(OS_POSIX)
+  // For POSIX systems, a last access time is available. However, it's not
+  // guaranteed to be more accurate than mtime. It is no worse though.
+  last_used_time = file_info.last_accessed;
+#endif
+  if (last_used_time.is_null())
+    last_used_time = file_info.last_modified;
+
+  int64 file_size = file_info.size;
+  SimpleIndex::EntrySet::iterator it = entries->find(hash_key);
+  if (it == entries->end()) {
+    SimpleIndex::InsertInEntrySet(
+        hash_key,
+        EntryMetadata(last_used_time, file_size),
+        entries);
+  } else {
+    // Summing up the total size of the entry through all the *_[0-2] files
+    it->second.SetEntrySize(it->second.GetEntrySize() + file_size);
+  }
+}
+
+}  // namespace
 
 SimpleIndexLoadResult::SimpleIndexLoadResult() : did_load(false),
                                                  flush_required(false) {
@@ -84,11 +134,6 @@
   entries.clear();
 }
 
-// static
-const char SimpleIndexFile::kIndexFileName[] = "the-real-index";
-// static
-const char SimpleIndexFile::kTempIndexFileName[] = "temp-index";
-
 SimpleIndexFile::IndexMetadata::IndexMetadata() :
     magic_number_(kSimpleIndexMagicNumber),
     version_(kSimpleVersion),
@@ -350,7 +395,6 @@
     const base::FilePath& index_file_path,
     SimpleIndexLoadResult* out_result) {
   LOG(INFO) << "Simple Cache Index is being restored from disk.";
-
   base::DeleteFile(index_file_path, /* recursive = */ false);
   out_result->Reset();
   SimpleIndex::EntrySet* entries = &out_result->entries;
@@ -359,53 +403,13 @@
   COMPILE_ASSERT(kSimpleEntryFileCount == 3,
                  file_pattern_must_match_file_count);
 
-  const int kFileSuffixLength = sizeof("_0") - 1;
-  const base::FilePath::StringType file_pattern = FILE_PATH_LITERAL("*_[0-2]");
-  base::FileEnumerator enumerator(cache_directory,
-                                  false /* recursive */,
-                                  base::FileEnumerator::FILES,
-                                  file_pattern);
-  for (base::FilePath file_path = enumerator.Next(); !file_path.empty();
-       file_path = enumerator.Next()) {
-    const base::FilePath::StringType base_name = file_path.BaseName().value();
-    // Converting to std::string is OK since we never use UTF8 wide chars in our
-    // file names.
-    const std::string hash_key_string(base_name.begin(),
-                                      base_name.end() - kFileSuffixLength);
-    uint64 hash_key = 0;
-    if (!simple_util::GetEntryHashKeyFromHexString(
-            hash_key_string, &hash_key)) {
-      LOG(WARNING) << "Invalid Entry Hash Key filename while restoring "
-                   << "Simple Index from disk: " << base_name;
-      // TODO(felipeg): Should we delete the invalid file here ?
-      continue;
-    }
-
-    base::FileEnumerator::FileInfo info = enumerator.GetInfo();
-    base::Time last_used_time;
-#if defined(OS_POSIX)
-    // For POSIX systems, a last access time is available. However, it's not
-    // guaranteed to be more accurate than mtime. It is no worse though.
-    last_used_time = base::Time::FromTimeT(info.stat().st_atime);
-#endif
-    if (last_used_time.is_null())
-      last_used_time = info.GetLastModifiedTime();
-
-    int64 file_size = info.GetSize();
-    SimpleIndex::EntrySet::iterator it = entries->find(hash_key);
-    if (it == entries->end()) {
-      SimpleIndex::InsertInEntrySet(
-          hash_key,
-          EntryMetadata(last_used_time, file_size),
-          entries);
-    } else {
-      // Summing up the total size of the entry through all the *_[0-2] files
-      it->second.SetEntrySize(it->second.GetEntrySize() + file_size);
-    }
+  const bool did_succeed = TraverseCacheDirectory(
+      cache_directory, base::Bind(&ProcessEntryFile, entries));
+  if (!did_succeed) {
+    LOG(ERROR) << "Could not reconstruct index from disk";
+    return;
   }
-
   out_result->did_load = true;
-
   // When we restore from disk we write the merged index file to disk right
   // away, this might save us from having to restore again next time.
   out_result->flush_required = true;
diff --git a/net/disk_cache/simple/simple_index_file.h b/net/disk_cache/simple/simple_index_file.h
index b536df9..e5fc85d 100644
--- a/net/disk_cache/simple/simple_index_file.h
+++ b/net/disk_cache/simple/simple_index_file.h
@@ -97,6 +97,9 @@
  private:
   friend class WrappedSimpleIndexFile;
 
+  // Used for cache directory traversal.
+  typedef base::Callback<void (const base::FilePath&)> EntryFileCallback;
+
   // When loading the entries from disk, add this many extra hash buckets to
   // prevent reallocation on the IO thread when merging in new live entries.
   static const int kExtraSizeForMerge = 512;
@@ -123,6 +126,15 @@
   static void Deserialize(const char* data, int data_len,
                           SimpleIndexLoadResult* out_result);
 
+  // Implemented either in simple_index_file_posix.cc or
+  // simple_index_file_win.cc. base::FileEnumerator turned out to be very
+  // expensive in terms of memory usage therefore it's used only on non-POSIX
+  // environments for convenience (for now). Returns whether the traversal
+  // succeeded.
+  static bool TraverseCacheDirectory(
+      const base::FilePath& cache_path,
+      const EntryFileCallback& entry_file_callback);
+
   // Scan the index directory for entries, returning an EntrySet of all entries
   // found.
   static void SyncRestoreFromDisk(const base::FilePath& cache_directory,
@@ -144,9 +156,6 @@
   const base::FilePath index_file_;
   const base::FilePath temp_index_file_;
 
-  static const char kIndexFileName[];
-  static const char kTempIndexFileName[];
-
   DISALLOW_COPY_AND_ASSIGN(SimpleIndexFile);
 };
 
diff --git a/net/disk_cache/simple/simple_index_file_posix.cc b/net/disk_cache/simple/simple_index_file_posix.cc
new file mode 100644
index 0000000..586699d
--- /dev/null
+++ b/net/disk_cache/simple/simple_index_file_posix.cc
@@ -0,0 +1,52 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/disk_cache/simple/simple_index_file.h"
+
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <string>
+
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+
+namespace disk_cache {
+namespace {
+
+struct DirCloser {
+  void operator()(DIR* dir) { closedir(dir); }
+};
+
+typedef scoped_ptr<DIR, DirCloser> ScopedDir;
+
+}  // namespace
+
+// static
+bool SimpleIndexFile::TraverseCacheDirectory(
+    const base::FilePath& cache_path,
+    const EntryFileCallback& entry_file_callback) {
+  const ScopedDir dir(opendir(cache_path.value().c_str()));
+  if (!dir) {
+    PLOG(ERROR) << "opendir " << cache_path.value();
+    return false;
+  }
+  dirent entry, *result;
+  while (readdir_r(dir.get(), &entry, &result) == 0) {
+    if (!result)
+      return true;  // The traversal completed successfully.
+    const std::string file_name(result->d_name);
+    if (file_name == "." || file_name == "..")
+      continue;
+    const base::FilePath file_path = cache_path.Append(
+        base::FilePath(file_name));
+    entry_file_callback.Run(file_path);
+  }
+  PLOG(ERROR) << "readdir_r " << cache_path.value();
+  return false;
+}
+
+}  // namespace disk_cache
diff --git a/net/disk_cache/simple/simple_index_file_win.cc b/net/disk_cache/simple/simple_index_file_win.cc
new file mode 100644
index 0000000..051d12d
--- /dev/null
+++ b/net/disk_cache/simple/simple_index_file_win.cc
@@ -0,0 +1,33 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/disk_cache/simple/simple_index_file.h"
+
+#include <string>
+
+#include "base/files/file_enumerator.h"
+#include "base/files/file_path.h"
+
+namespace disk_cache {
+
+// static
+bool SimpleIndexFile::TraverseCacheDirectory(
+    const base::FilePath& cache_path,
+    const EntryFileCallback& entry_file_callback) {
+  const base::FilePath current_directory(FILE_PATH_LITERAL("."));
+  const base::FilePath parent_directory(FILE_PATH_LITERAL(".."));
+  const base::FilePath::StringType file_pattern = FILE_PATH_LITERAL("*");
+  base::FileEnumerator enumerator(
+      cache_path, false /* recursive */, base::FileEnumerator::FILES,
+      file_pattern);
+  for (base::FilePath file_path = enumerator.Next(); !file_path.empty();
+       file_path = enumerator.Next()) {
+    if (file_path == current_directory || file_path == parent_directory)
+      continue;
+    entry_file_callback.Run(file_path);
+  }
+  return true;
+}
+
+}  // namespace disk_cache
diff --git a/net/disk_cache/simple/simple_util.cc b/net/disk_cache/simple/simple_util.cc
index 72a4612..e9ec067 100644
--- a/net/disk_cache/simple/simple_util.cc
+++ b/net/disk_cache/simple/simple_util.cc
@@ -40,7 +40,7 @@
   return hash_key_str;
 }
 
-bool GetEntryHashKeyFromHexString(const std::string& hash_key,
+bool GetEntryHashKeyFromHexString(const base::StringPiece& hash_key,
                                   uint64* hash_key_out) {
   if (hash_key.size() != kEntryHashKeyAsHexStringSize) {
     return false;
diff --git a/net/disk_cache/simple/simple_util.h b/net/disk_cache/simple/simple_util.h
index 2e92b4a..3bb80b9 100644
--- a/net/disk_cache/simple/simple_util.h
+++ b/net/disk_cache/simple/simple_util.h
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "base/basictypes.h"
+#include "base/strings/string_piece.h"
 #include "net/base/net_export.h"
 
 namespace base {
@@ -33,7 +34,7 @@
 // Parses the |hash_key| string into a uint64 buffer.
 // |hash_key| string must be of the form: FFFFFFFFFFFFFFFF .
 NET_EXPORT_PRIVATE bool GetEntryHashKeyFromHexString(
-    const std::string& hash_key,
+    const base::StringPiece& hash_key,
     uint64* hash_key_out);
 
 // Given a |key| for a (potential) entry in the simple backend and the |index|
diff --git a/net/net.gyp b/net/net.gyp
index cedc05b..9443da6 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -399,6 +399,8 @@
         'disk_cache/simple/simple_index.h',
         'disk_cache/simple/simple_index_file.cc',
         'disk_cache/simple/simple_index_file.h',
+        'disk_cache/simple/simple_index_file_posix.cc',
+        'disk_cache/simple/simple_index_file_win.cc',
         'disk_cache/simple/simple_net_log_parameters.cc',
         'disk_cache/simple/simple_net_log_parameters.h',
         'disk_cache/simple/simple_synchronous_entry.cc',
diff --git a/net/net.target.darwin-arm.mk b/net/net.target.darwin-arm.mk
index 36ad05d..ea59c26 100644
--- a/net/net.target.darwin-arm.mk
+++ b/net/net.target.darwin-arm.mk
@@ -153,6 +153,7 @@
 	net/disk_cache/simple/simple_entry_operation.cc \
 	net/disk_cache/simple/simple_index.cc \
 	net/disk_cache/simple/simple_index_file.cc \
+	net/disk_cache/simple/simple_index_file_posix.cc \
 	net/disk_cache/simple/simple_net_log_parameters.cc \
 	net/disk_cache/simple/simple_synchronous_entry.cc \
 	net/disk_cache/simple/simple_util.cc \
diff --git a/net/net.target.darwin-mips.mk b/net/net.target.darwin-mips.mk
index 203e38d..66c7dc9 100644
--- a/net/net.target.darwin-mips.mk
+++ b/net/net.target.darwin-mips.mk
@@ -153,6 +153,7 @@
 	net/disk_cache/simple/simple_entry_operation.cc \
 	net/disk_cache/simple/simple_index.cc \
 	net/disk_cache/simple/simple_index_file.cc \
+	net/disk_cache/simple/simple_index_file_posix.cc \
 	net/disk_cache/simple/simple_net_log_parameters.cc \
 	net/disk_cache/simple/simple_synchronous_entry.cc \
 	net/disk_cache/simple/simple_util.cc \
diff --git a/net/net.target.darwin-x86.mk b/net/net.target.darwin-x86.mk
index e8410cd..a7a01b5 100644
--- a/net/net.target.darwin-x86.mk
+++ b/net/net.target.darwin-x86.mk
@@ -153,6 +153,7 @@
 	net/disk_cache/simple/simple_entry_operation.cc \
 	net/disk_cache/simple/simple_index.cc \
 	net/disk_cache/simple/simple_index_file.cc \
+	net/disk_cache/simple/simple_index_file_posix.cc \
 	net/disk_cache/simple/simple_net_log_parameters.cc \
 	net/disk_cache/simple/simple_synchronous_entry.cc \
 	net/disk_cache/simple/simple_util.cc \
diff --git a/net/net.target.linux-arm.mk b/net/net.target.linux-arm.mk
index 36ad05d..ea59c26 100644
--- a/net/net.target.linux-arm.mk
+++ b/net/net.target.linux-arm.mk
@@ -153,6 +153,7 @@
 	net/disk_cache/simple/simple_entry_operation.cc \
 	net/disk_cache/simple/simple_index.cc \
 	net/disk_cache/simple/simple_index_file.cc \
+	net/disk_cache/simple/simple_index_file_posix.cc \
 	net/disk_cache/simple/simple_net_log_parameters.cc \
 	net/disk_cache/simple/simple_synchronous_entry.cc \
 	net/disk_cache/simple/simple_util.cc \
diff --git a/net/net.target.linux-mips.mk b/net/net.target.linux-mips.mk
index 203e38d..66c7dc9 100644
--- a/net/net.target.linux-mips.mk
+++ b/net/net.target.linux-mips.mk
@@ -153,6 +153,7 @@
 	net/disk_cache/simple/simple_entry_operation.cc \
 	net/disk_cache/simple/simple_index.cc \
 	net/disk_cache/simple/simple_index_file.cc \
+	net/disk_cache/simple/simple_index_file_posix.cc \
 	net/disk_cache/simple/simple_net_log_parameters.cc \
 	net/disk_cache/simple/simple_synchronous_entry.cc \
 	net/disk_cache/simple/simple_util.cc \
diff --git a/net/net.target.linux-x86.mk b/net/net.target.linux-x86.mk
index e8410cd..a7a01b5 100644
--- a/net/net.target.linux-x86.mk
+++ b/net/net.target.linux-x86.mk
@@ -153,6 +153,7 @@
 	net/disk_cache/simple/simple_entry_operation.cc \
 	net/disk_cache/simple/simple_index.cc \
 	net/disk_cache/simple/simple_index_file.cc \
+	net/disk_cache/simple/simple_index_file_posix.cc \
 	net/disk_cache/simple/simple_net_log_parameters.cc \
 	net/disk_cache/simple/simple_synchronous_entry.cc \
 	net/disk_cache/simple/simple_util.cc \
diff --git a/printing/printing_context_android.h b/printing/printing_context_android.h
index e38fff9..1803825 100644
--- a/printing/printing_context_android.h
+++ b/printing/printing_context_android.h
@@ -28,7 +28,7 @@
 
   // Called from Java, when printing settings from the user are ready or the
   // printing operation is canceled.
-  void AskUserForSettingsReply(bool success);
+  void AskUserForSettingsReply(JNIEnv* env, jobject obj, jboolean success);
 
   // PrintingContext implementation.
   virtual void AskUserForSettings(