Version 1.24.1

Cherry-pick b3a90540f11b2bc6b96d512b28473b8b5f602dc1 to stable
Cherry-pick b5717a77ae79121b7b97335bcc040bbef9115d8f to stable
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 74e1453..422e59d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,17 @@
+## 1.24.1 - 14-06-2017
+
+* Bug fixes for dartdevc support in `pub serve`.
+  * Fixed module config invalidation logic so modules are properly
+    recalculated when package layout changes.
+  * Fixed exception when handling require.js errors that aren't script load
+    errors.
+  * Fixed an issue where requesting the bootstrap.js file before the dart.js
+    file would result in a 404.
+  * Fixed a Safari issue during bootstrapping (note that Safari is still not
+    officially supported but does work for trivial examples).
+* Fix for a Dartium issue where there was no sound in checked mode
+    (https://github.com/dart-lang/sdk/issues/29810)
+
 ## 1.24.0 - 12-06-2017
 
 ### Language
@@ -136,7 +150,7 @@
 * Pub
 
   * `pub build` and `pub serve`
-  
+
     * Added support for the Dart Development Compiler.
 
       Unlike dart2js, this new compiler is modular, which allows pub to do
@@ -182,7 +196,7 @@
       transformer.
 
   * `pub publish`
-  
+
     * Added support for the UNLICENSE file.
 
     * Packages that depend on the Flutter SDK may be published.
diff --git a/DEPS b/DEPS
index a8ee25a..a2e13f7 100644
--- a/DEPS
+++ b/DEPS
@@ -95,7 +95,7 @@
   "ply_rev": "@604b32590ffad5cbb82e4afef1d305512d06ae93",
   "pool_tag": "@1.3.0",
   "protobuf_tag": "@0.5.4",
-  "pub_rev": "@a8781274e3a38c34a49d4c5bffb98557c6022a75",
+  "pub_rev": "@0713718a83054fcc1c0a4b163e036f7c39ea4790",
   "pub_semver_tag": "@1.3.2",
   "quiver_tag": "@0.22.0",
   "resource_rev":"@a49101ba2deb29c728acba6fb86000a8f730f4b1",
diff --git a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
index e725018..73493c5 100644
--- a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
+++ b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
@@ -361,13 +361,6 @@
   @DocsEditable()
   WaveShaperNode createWaveShaper() native;
 
-  @JSName('decodeAudioData')
-  @DomName('AudioContext.decodeAudioData')
-  @DocsEditable()
-  Future _decodeAudioData(ByteBuffer audioData,
-      [AudioBufferCallback successCallback,
-      AudioBufferCallback errorCallback]) native;
-
   @DomName('AudioContext.resume')
   @DocsEditable()
   @Experimental() // untriaged
@@ -409,6 +402,13 @@
     }
   }
 
+  @JSName('decodeAudioData')
+  @DomName('AudioContext.decodeAudioData')
+  @DocsEditable()
+  Future _decodeAudioData(ByteBuffer audioData,
+      [AudioBufferCallback successCallback,
+      AudioBufferCallback errorCallback]) native;
+
   @DomName('AudioContext.decodeAudioData')
   Future<AudioBuffer> decodeAudioData(ByteBuffer audioData) {
     var completer = new Completer<AudioBuffer>();
diff --git a/sdk/lib/web_audio/dartium/web_audio_dartium.dart b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
index 2c6c79c..e00f2d2 100644
--- a/sdk/lib/web_audio/dartium/web_audio_dartium.dart
+++ b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
@@ -546,21 +546,6 @@
   WaveShaperNode createWaveShaper() =>
       _blink.BlinkAudioContext.instance.createWaveShaper_Callback_0_(this);
 
-  Future _decodeAudioData(ByteBuffer audioData,
-      [AudioBufferCallback successCallback,
-      AudioBufferCallback errorCallback]) {
-    if (errorCallback != null) {
-      return _blink.BlinkAudioContext.instance.decodeAudioData_Callback_3_(
-          this, audioData, successCallback, errorCallback);
-    }
-    if (successCallback != null) {
-      return _blink.BlinkAudioContext.instance
-          .decodeAudioData_Callback_2_(this, audioData, successCallback);
-    }
-    return _blink.BlinkAudioContext.instance
-        .decodeAudioData_Callback_1_(this, audioData);
-  }
-
   @DomName('AudioContext.resume')
   @DocsEditable()
   @Experimental() // untriaged
@@ -574,18 +559,20 @@
       _blink.BlinkAudioContext.instance.suspend_Callback_0_(this));
 
   @DomName('AudioContext.decodeAudioData')
-  Future<AudioBuffer> decodeAudioData(ByteBuffer audioData) {
-    var completer = new Completer<AudioBuffer>();
-    _decodeAudioData(audioData, (value) {
-      completer.complete(value);
-    }, (error) {
-      if (error == null) {
-        completer.completeError('');
-      } else {
-        completer.completeError(error);
-      }
-    });
-    return completer.future;
+  Future<AudioBuffer> decodeAudioData(ByteBuffer audioData,
+      [AudioBufferCallback successCallback,
+      AudioBufferCallback errorCallback]) {
+    if (errorCallback != null) {
+      return convertNativePromiseToDartFuture(_blink.BlinkAudioContext.instance
+          .decodeAudioData_Callback_3_(
+              this, audioData, successCallback, errorCallback));
+    }
+    if (successCallback != null) {
+      return convertNativePromiseToDartFuture(_blink.BlinkAudioContext.instance
+          .decodeAudioData_Callback_2_(this, audioData, successCallback));
+    }
+    return convertNativePromiseToDartFuture(_blink.BlinkAudioContext.instance
+        .decodeAudioData_Callback_1_(this, audioData));
   }
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
diff --git a/tools/VERSION b/tools/VERSION
index dacb132..0d21e3c 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -26,6 +26,6 @@
 CHANNEL stable
 MAJOR 1
 MINOR 24
-PATCH 0
+PATCH 1
 PRERELEASE 0
 PRERELEASE_PATCH 0
diff --git a/tools/dom/idl/dart/dart.idl b/tools/dom/idl/dart/dart.idl
index 58632fa..77f0680 100644
--- a/tools/dom/idl/dart/dart.idl
+++ b/tools/dom/idl/dart/dart.idl
@@ -1,13 +1,5 @@
 // This file introduces / supplements and forces Dart declarations.
 
-[DartSupplemental,
- Constructor]
-interface AudioContext {
-  // TODO(ager): Auto-generate this custom method when the info about retaining
-  // typed arrays is in the IDL.
-  [Custom] void decodeAudioData(ArrayBuffer audioData, AudioBufferCallback successCallback, AudioBufferCallback errorCallback);
-};
-
 [DartSupplemental]
 interface WaveShaperNode {
   // TODO(ager): Auto-generate this custom method when the info about retaining
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
index 850b022..aa5a311 100644
--- a/tools/dom/scripts/htmlrenamer.py
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -222,7 +222,6 @@
 # browser. They are exposed simply by placing an underscore in front of the
 # name.
 private_html_members = monitored.Set('htmlrenamer.private_html_members', [
-  'AudioContext.decodeAudioData',
   'AudioNode.connect',
   'Cache.add',
   'Cache.delete',
@@ -534,6 +533,7 @@
 # TODO(jacobr): cleanup and augment this list.
 removed_html_members = monitored.Set('htmlrenamer.removed_html_members', [
     'Attr.textContent', # Not needed as it is the same as Node.textContent.
+    'AudioContext.decodeAudioData',
     'AudioBufferSourceNode.looping', # TODO(vsm): Use deprecated IDL annotation
     'CSSStyleDeclaration.getPropertyCSSValue',
     'CanvasRenderingContext2D.clearShadow',
diff --git a/tools/dom/templates/html/impl/impl_AudioContext.darttemplate b/tools/dom/templates/html/impl/impl_AudioContext.darttemplate
index 603c643..d83acc5 100644
--- a/tools/dom/templates/html/impl/impl_AudioContext.darttemplate
+++ b/tools/dom/templates/html/impl/impl_AudioContext.darttemplate
@@ -34,6 +34,15 @@
     }
   }
 $endif
+
+$if DART2JS
+  @JSName('decodeAudioData')
+  @DomName('AudioContext.decodeAudioData')
+  @DocsEditable()
+  Future _decodeAudioData(ByteBuffer audioData,
+      [AudioBufferCallback successCallback,
+      AudioBufferCallback errorCallback]) native;
+
   @DomName('AudioContext.decodeAudioData')
   Future<AudioBuffer> decodeAudioData(ByteBuffer audioData) {
     var completer = new Completer<AudioBuffer>();
@@ -48,4 +57,21 @@
         });
     return completer.future;
   }
+$else
+  @DomName('AudioContext.decodeAudioData')
+  Future<AudioBuffer> decodeAudioData(ByteBuffer audioData,
+      [AudioBufferCallback successCallback,
+      AudioBufferCallback errorCallback]) {
+    if (errorCallback != null) {
+      return convertNativePromiseToDartFuture(_blink.BlinkAudioContext.instance.decodeAudioData_Callback_3_(
+          this, audioData, successCallback, errorCallback));
+    }
+    if (successCallback != null) {
+      return convertNativePromiseToDartFuture(_blink.BlinkAudioContext.instance
+          .decodeAudioData_Callback_2_(this, audioData, successCallback));
+    }
+    return convertNativePromiseToDartFuture(_blink.BlinkAudioContext.instance
+        .decodeAudioData_Callback_1_(this, audioData));
+  }
+$endif
 }