Backed out changeset ac06eacc2206 (bug 987064) for B2G ICS Emulator Debug Bustage on a CLOSED TREE
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Thu, 10 Apr 2014 13:18:18 +0200
changeset 189993 c239ac3cf5d3c817f1964b8c33b2cea10d70f081
parent 189992 76fc69c85f284c417bfdc0874e58aad5871f50af
child 189994 327f7441a1648d29a7eaa5b9a4c8dc67fd8ad5e2
push idunknown
push userunknown
push dateunknown
bugs987064
milestone31.0a1
backs outac06eacc22068523dfc8f5e0d2813e1e3ce085aa
Backed out changeset ac06eacc2206 (bug 987064) for B2G ICS Emulator Debug Bustage on a CLOSED TREE
content/base/src/nsAttrValue.h
content/html/content/public/HTMLMediaElement.h
content/html/content/src/HTMLMediaElement.cpp
content/media/AudioStream.cpp
content/media/AudioStream.h
content/media/MediaDecoder.cpp
content/media/MediaDecoder.h
content/media/MediaDecoderStateMachine.cpp
content/media/MediaStreamGraph.cpp
content/media/webaudio/AudioDestinationNode.cpp
content/svg/content/src/SVGAttrValueWrapper.h
dom/audiochannel/AudioChannelAgent.cpp
dom/audiochannel/AudioChannelCommon.h
dom/audiochannel/AudioChannelService.cpp
dom/audiochannel/AudioChannelService.h
dom/audiochannel/AudioChannelServiceChild.cpp
dom/audiochannel/AudioChannelServiceChild.h
dom/audiochannel/tests/TestAudioChannelService.cpp
dom/audiochannel/tests/moz.build
dom/camera/DOMCameraControl.cpp
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
dom/ipc/TabMessageUtils.h
dom/system/gonk/AudioChannelManager.cpp
dom/system/gonk/AudioChannelManager.h
dom/system/gonk/AudioManager.cpp
--- a/content/base/src/nsAttrValue.h
+++ b/content/base/src/nsAttrValue.h
@@ -7,17 +7,17 @@
  * A struct that represents the value (type and actual data) of an
  * attribute.
  */
 
 #ifndef nsAttrValue_h___
 #define nsAttrValue_h___
 
 #include "nscore.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsStringBuffer.h"
 #include "nsColor.h"
 #include "nsCaseTreatment.h"
 #include "nsMargin.h"
 #include "nsCOMPtr.h"
 #include "SVGAttrValueWrapper.h"
 #include "nsTArrayForwardDeclare.h"
 #include "nsIAtom.h"
--- a/content/html/content/public/HTMLMediaElement.h
+++ b/content/html/content/public/HTMLMediaElement.h
@@ -491,21 +491,17 @@ public:
   {
     return mAudioCaptured;
   }
 
   JSObject* MozGetMetadata(JSContext* aCx, ErrorResult& aRv);
 
   double MozFragmentEnd();
 
-  AudioChannel MozAudioChannelType() const
-  {
-    return mAudioChannel;
-  }
-
+  AudioChannel MozAudioChannelType() const;
   void SetMozAudioChannelType(AudioChannel aValue, ErrorResult& aRv);
 
   TextTrackList* TextTracks();
 
   already_AddRefed<TextTrack> AddTextTrack(TextTrackKind aKind,
                                            const nsAString& aLabel,
                                            const nsAString& aLanguage);
 
@@ -1121,18 +1117,18 @@ protected:
   CORSMode mCORSMode;
 
   // True if the media has an audio track
   bool mHasAudio;
 
   // True if the media's channel's download has been suspended.
   bool mDownloadSuspendedByCache;
 
-  // Audio Channel.
-  AudioChannel mAudioChannel;
+  // Audio Channel Type.
+  AudioChannelType mAudioChannelType;
 
   // The audio channel has been faded.
   bool mAudioChannelFaded;
 
   // Is this media element playing?
   bool mPlayingThroughTheAudioChannel;
 
   // An agent used to join audio channel service.
--- a/content/html/content/src/HTMLMediaElement.cpp
+++ b/content/html/content/src/HTMLMediaElement.cpp
@@ -1999,30 +1999,29 @@ HTMLMediaElement::HTMLMediaElement(alrea
     mHasPlayedOrSeeked(false),
     mHasSelfReference(false),
     mShuttingDown(false),
     mSuspendedForPreloadNone(false),
     mMediaSecurityVerified(false),
     mCORSMode(CORS_NONE),
     mHasAudio(false),
     mDownloadSuspendedByCache(false),
+    mAudioChannelType(AUDIO_CHANNEL_NORMAL),
     mAudioChannelFaded(false),
     mPlayingThroughTheAudioChannel(false)
 {
 #ifdef PR_LOGGING
   if (!gMediaElementLog) {
     gMediaElementLog = PR_NewLogModule("nsMediaElement");
   }
   if (!gMediaElementEventsLog) {
     gMediaElementEventsLog = PR_NewLogModule("nsMediaElementEvents");
   }
 #endif
 
-  mAudioChannel = AudioChannelService::GetDefaultAudioChannel();
-
   mPaused.SetOuter(this);
 
   RegisterFreezableElement();
   NotifyOwnerDocumentActivityChanged();
 }
 
 HTMLMediaElement::~HTMLMediaElement()
 {
@@ -2278,44 +2277,53 @@ bool HTMLMediaElement::ParseAttribute(in
   static const nsAttrValue::EnumTable kPreloadTable[] = {
     { "",         HTMLMediaElement::PRELOAD_ATTR_EMPTY },
     { "none",     HTMLMediaElement::PRELOAD_ATTR_NONE },
     { "metadata", HTMLMediaElement::PRELOAD_ATTR_METADATA },
     { "auto",     HTMLMediaElement::PRELOAD_ATTR_AUTO },
     { 0 }
   };
 
+  // Mappings from 'mozaudiochannel' attribute strings to an enumeration.
+  static const nsAttrValue::EnumTable kMozAudioChannelAttributeTable[] = {
+    { "normal",             AUDIO_CHANNEL_NORMAL },
+    { "content",            AUDIO_CHANNEL_CONTENT },
+    { "notification",       AUDIO_CHANNEL_NOTIFICATION },
+    { "alarm",              AUDIO_CHANNEL_ALARM },
+    { "telephony",          AUDIO_CHANNEL_TELEPHONY },
+    { "ringer",             AUDIO_CHANNEL_RINGER },
+    { "publicnotification", AUDIO_CHANNEL_PUBLICNOTIFICATION },
+    { 0 }
+  };
+
   if (aNamespaceID == kNameSpaceID_None) {
     if (ParseImageAttribute(aAttribute, aValue, aResult)) {
       return true;
     }
     if (aAttribute == nsGkAtoms::crossorigin) {
       ParseCORSValue(aValue, aResult);
       return true;
     }
     if (aAttribute == nsGkAtoms::preload) {
       return aResult.ParseEnumValue(aValue, kPreloadTable, false);
     }
 
     if (aAttribute == nsGkAtoms::mozaudiochannel) {
-      const nsAttrValue::EnumTable* table =
-        AudioChannelService::GetAudioChannelTable();
-      MOZ_ASSERT(table);
-
-      bool parsed = aResult.ParseEnumValue(aValue, table, false, &table[0]);
+      bool parsed = aResult.ParseEnumValue(aValue, kMozAudioChannelAttributeTable, false,
+                                           &kMozAudioChannelAttributeTable[0]);
       if (!parsed) {
         return false;
       }
 
-      AudioChannel audioChannel = static_cast<AudioChannel>(aResult.GetEnumValue());
-
-      if (audioChannel != mAudioChannel &&
+      AudioChannelType audioChannelType = static_cast<AudioChannelType>(aResult.GetEnumValue());
+
+      if (audioChannelType != mAudioChannelType &&
           !mDecoder &&
           CheckAudioChannelPermissions(aValue)) {
-        mAudioChannel = audioChannel;
+        mAudioChannelType = audioChannelType;
       }
 
       return true;
     }
   }
 
   return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
                                               aResult);
@@ -2591,17 +2599,17 @@ nsresult HTMLMediaElement::FinishDecoder
   mPendingEvents.Clear();
   // Set mDecoder now so if methods like GetCurrentSrc get called between
   // here and Load(), they work.
   mDecoder = aDecoder;
 
   // Tell the decoder about its MediaResource now so things like principals are
   // available immediately.
   mDecoder->SetResource(aStream);
-  aDecoder->SetAudioChannel(mAudioChannel);
+  mDecoder->SetAudioChannelType(mAudioChannelType);
   mDecoder->SetAudioCaptured(mAudioCaptured);
   mDecoder->SetVolume(mMuted ? 0.0 : mVolume);
   mDecoder->SetPreservesPitch(mPreservesPitch);
   mDecoder->SetPlaybackRate(mPlaybackRate);
 
   if (mPreloadAction == HTMLMediaElement::PRELOAD_METADATA) {
     mDecoder->SetMinimizePrerollUntilPlaybackStarts();
   }
@@ -3833,24 +3841,22 @@ void HTMLMediaElement::UpdateAudioChanne
     if (!mAudioChannelAgent) {
       nsresult rv;
       mAudioChannelAgent = do_CreateInstance("@mozilla.org/audiochannelagent;1", &rv);
       if (!mAudioChannelAgent) {
         return;
       }
       nsCOMPtr<nsIDOMHTMLVideoElement> video = do_QueryObject(this);
       // Use a weak ref so the audio channel agent can't leak |this|.
-      if (AudioChannel::Normal == mAudioChannel && video) {
+      if (AUDIO_CHANNEL_NORMAL == mAudioChannelType && video) {
         mAudioChannelAgent->InitWithVideo(OwnerDoc()->GetWindow(),
-                                          static_cast<int32_t>(mAudioChannel),
-                                          this, true);
+                                          mAudioChannelType, this, true);
       } else {
         mAudioChannelAgent->InitWithWeakCallback(OwnerDoc()->GetWindow(),
-                                                 static_cast<int32_t>(mAudioChannel),
-                                                 this);
+                                                 mAudioChannelType, this);
       }
       mAudioChannelAgent->SetVisibilityState(!OwnerDoc()->Hidden());
     }
 
     if (mPlayingThroughTheAudioChannel) {
       int32_t canPlay;
       mAudioChannelAgent->StartPlaying(&canPlay);
       CanPlayChanged(canPlay);
@@ -3920,16 +3926,43 @@ TextTrackManager*
 HTMLMediaElement::GetOrCreateTextTrackManager()
 {
   if (!mTextTrackManager) {
     mTextTrackManager = new TextTrackManager(this);
   }
   return mTextTrackManager;
 }
 
+AudioChannel
+HTMLMediaElement::MozAudioChannelType() const
+{
+  switch (mAudioChannelType) {
+    case AUDIO_CHANNEL_CONTENT:
+      return AudioChannel::Content;
+
+    case AUDIO_CHANNEL_NOTIFICATION:
+      return AudioChannel::Notification;
+
+    case AUDIO_CHANNEL_ALARM:
+      return AudioChannel::Alarm;
+
+    case AUDIO_CHANNEL_TELEPHONY:
+      return AudioChannel::Telephony;
+
+    case AUDIO_CHANNEL_RINGER:
+      return AudioChannel::Ringer;
+
+    case AUDIO_CHANNEL_PUBLICNOTIFICATION:
+      return AudioChannel::Publicnotification;
+
+    default:
+      return AudioChannelService::GetDefaultAudioChannel();
+  }
+}
+
 void
 HTMLMediaElement::SetMozAudioChannelType(AudioChannel aValue, ErrorResult& aRv)
 {
   nsString channel;
   channel.AssignASCII(AudioChannelValues::strings[uint32_t(aValue)].value,
                       AudioChannelValues::strings[uint32_t(aValue)].length);
   SetHTMLAttr(nsGkAtoms::mozaudiochannel, channel, aRv);
 }
--- a/content/media/AudioStream.cpp
+++ b/content/media/AudioStream.cpp
@@ -105,35 +105,35 @@ bool AudioStream::sCubebLatencyPrefSet;
 
 /*static*/ bool AudioStream::CubebLatencyPrefSet()
 {
   StaticMutexAutoLock lock(sMutex);
   return sCubebLatencyPrefSet;
 }
 
 #if defined(__ANDROID__) && defined(MOZ_B2G)
-static cubeb_stream_type ConvertChannelToCubebType(dom::AudioChannel aChannel)
+static cubeb_stream_type ConvertChannelToCubebType(dom::AudioChannelType aType)
 {
-  switch(aChannel) {
-    case dom::AudioChannel::Normal:
+  switch(aType) {
+    case dom::AUDIO_CHANNEL_NORMAL:
       return CUBEB_STREAM_TYPE_SYSTEM;
-    case dom::AudioChannel::Content:
+    case dom::AUDIO_CHANNEL_CONTENT:
       return CUBEB_STREAM_TYPE_MUSIC;
-    case dom::AudioChannel::Notification:
+    case dom::AUDIO_CHANNEL_NOTIFICATION:
       return CUBEB_STREAM_TYPE_NOTIFICATION;
-    case dom::AudioChannel::Alarm:
+    case dom::AUDIO_CHANNEL_ALARM:
       return CUBEB_STREAM_TYPE_ALARM;
-    case dom::AudioChannel::Telephony:
+    case dom::AUDIO_CHANNEL_TELEPHONY:
       return CUBEB_STREAM_TYPE_VOICE_CALL;
-    case dom::AudioChannel::Ringer:
+    case dom::AUDIO_CHANNEL_RINGER:
       return CUBEB_STREAM_TYPE_RING;
     // Currently Android openSLES library doesn't support FORCE_AUDIBLE yet.
-    case dom::AudioChannel::Publicnotification:
+    case dom::AUDIO_CHANNEL_PUBLICNOTIFICATION:
     default:
-      NS_ERROR("The value of AudioChannel is invalid");
+      NS_ERROR("The value of AudioChannelType is invalid");
       return CUBEB_STREAM_TYPE_MAX;
   }
 }
 #endif
 
 AudioStream::AudioStream()
   : mMonitor("AudioStream")
   , mInRate(0)
@@ -344,17 +344,17 @@ WriteDumpFile(FILE* aDumpFile, AudioStre
     SetUint16LE(output + i*2, int16_t(input[i]*32767.0f));
   }
   fwrite(output, 2, samples, aDumpFile);
   fflush(aDumpFile);
 }
 
 nsresult
 AudioStream::Init(int32_t aNumChannels, int32_t aRate,
-                  const dom::AudioChannel aAudioChannel,
+                  const dom::AudioChannelType aAudioChannelType,
                   LatencyRequest aLatencyRequest)
 {
   cubeb* cubebContext = GetCubebContext();
 
   if (!cubebContext || aNumChannels < 0 || aRate < 0) {
     return NS_ERROR_FAILURE;
   }
 
@@ -367,17 +367,17 @@ AudioStream::Init(int32_t aNumChannels, 
 
   mDumpFile = OpenDumpFile(this);
 
   cubeb_stream_params params;
   params.rate = aRate;
   params.channels = mOutChannels;
 #if defined(__ANDROID__)
 #if defined(MOZ_B2G)
-  params.stream_type = ConvertChannelToCubebType(aAudioChannel);
+  params.stream_type = ConvertChannelToCubebType(aAudioChannelType);
 #else
   params.stream_type = CUBEB_STREAM_TYPE_MUSIC;
 #endif
 
   if (params.stream_type == CUBEB_STREAM_TYPE_MAX) {
     return NS_ERROR_INVALID_ARG;
   }
 #endif
--- a/content/media/AudioStream.h
+++ b/content/media/AudioStream.h
@@ -2,21 +2,21 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #if !defined(AudioStream_h_)
 #define AudioStream_h_
 
 #include "AudioSampleFormat.h"
+#include "AudioChannelCommon.h"
 #include "nsAutoPtr.h"
 #include "nsAutoRef.h"
 #include "nsCOMPtr.h"
 #include "Latency.h"
-#include "mozilla/dom/AudioChannelBinding.h"
 #include "mozilla/StaticMutex.h"
 
 #include "cubeb/cubeb.h"
 
 template <>
 class nsAutoRefTraits<cubeb_stream> : public nsPointerRefTraits<cubeb_stream>
 {
 public:
@@ -193,17 +193,17 @@ public:
     HighLatency,
     LowLatency
   };
 
   // Initialize the audio stream. aNumChannels is the number of audio
   // channels (1 for mono, 2 for stereo, etc) and aRate is the sample rate
   // (22050Hz, 44100Hz, etc).
   nsresult Init(int32_t aNumChannels, int32_t aRate,
-                const dom::AudioChannel aAudioStreamChannel,
+                const dom::AudioChannelType aAudioStreamType,
                 LatencyRequest aLatencyRequest);
 
   // Closes the stream. All future use of the stream is an error.
   void Shutdown();
 
   // Write audio data to the audio hardware.  aBuf is an array of AudioDataValues
   // AudioDataValue of length aFrames*mChannels.  If aFrames is larger
   // than the result of Available(), the write will block until sufficient
--- a/content/media/MediaDecoder.cpp
+++ b/content/media/MediaDecoder.cpp
@@ -18,17 +18,16 @@
 #include "nsError.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/StaticPtr.h"
 #include "nsIMemoryReporter.h"
 #include "nsComponentManagerUtils.h"
 #include "nsITimer.h"
 #include <algorithm>
 #include "MediaShutdownManager.h"
-#include "AudioChannelService.h"
 
 #ifdef MOZ_WMF
 #include "WMFDecoder.h"
 #endif
 
 using namespace mozilla::layers;
 using namespace mozilla::dom;
 
@@ -423,28 +422,27 @@ MediaDecoder::MediaDecoder() :
   mNextState(PLAY_STATE_PAUSED),
   mCalledResourceLoaded(false),
   mIgnoreProgressData(false),
   mInfiniteStream(false),
   mOwner(nullptr),
   mPinnedForSeek(false),
   mShuttingDown(false),
   mPausedForPlaybackRateNull(false),
+  mAudioChannelType(AUDIO_CHANNEL_NORMAL),
   mMinimizePreroll(false)
 {
   MOZ_COUNT_CTOR(MediaDecoder);
   MOZ_ASSERT(NS_IsMainThread());
   MediaMemoryTracker::AddMediaDecoder(this);
 #ifdef PR_LOGGING
   if (!gMediaDecoderLog) {
     gMediaDecoderLog = PR_NewLogModule("MediaDecoder");
   }
 #endif
-
-  mAudioChannel = AudioChannelService::GetDefaultAudioChannel();
 }
 
 bool MediaDecoder::Init(MediaDecoderOwner* aOwner)
 {
   MOZ_ASSERT(NS_IsMainThread());
   mOwner = aOwner;
   mVideoFrameContainer = aOwner->GetVideoFrameContainer();
   MediaShutdownManager::Instance().Register(this);
--- a/content/media/MediaDecoder.h
+++ b/content/media/MediaDecoder.h
@@ -178,21 +178,21 @@ destroying the MediaDecoder object.
 #if !defined(MediaDecoder_h_)
 #define MediaDecoder_h_
 
 #include "nsISupports.h"
 #include "nsCOMPtr.h"
 #include "nsIObserver.h"
 #include "nsAutoPtr.h"
 #include "MediaResource.h"
-#include "mozilla/dom/AudioChannelBinding.h"
 #include "mozilla/gfx/Rect.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "mozilla/TimeStamp.h"
 #include "MediaStreamGraph.h"
+#include "AudioChannelCommon.h"
 #include "AbstractMediaDecoder.h"
 #include "necko-config.h"
 
 class nsIStreamListener;
 class nsIPrincipal;
 class nsITimer;
 
 namespace mozilla {
@@ -734,18 +734,18 @@ public:
   bool CanPlayThrough();
 
   // Make the decoder state machine update the playback position. Called by
   // the reader on the decoder thread (Assertions for this checked by
   // mDecoderStateMachine). This must be called with the decode monitor
   // held.
   void UpdatePlaybackPosition(int64_t aTime) MOZ_FINAL MOZ_OVERRIDE;
 
-  void SetAudioChannel(dom::AudioChannel aChannel) { mAudioChannel = aChannel; }
-  dom::AudioChannel GetAudioChannel() { return mAudioChannel; }
+  void SetAudioChannelType(dom::AudioChannelType aType) { mAudioChannelType = aType; }
+  dom::AudioChannelType GetAudioChannelType() { return mAudioChannelType; }
 
   // Send a new set of metadata to the state machine, to be dispatched to the
   // main thread to be presented when the |currentTime| of the media is greater
   // or equal to aPublishTime.
   void QueueMetadata(int64_t aPublishTime,
                      int aChannels,
                      int aRate,
                      bool aHasAudio,
@@ -1200,17 +1200,17 @@ protected:
   // Read/Write from the main thread only.
   bool mShuttingDown;
 
   // True if the playback is paused because the playback rate member is 0.0.
   bool mPausedForPlaybackRateNull;
 
   // Be assigned from media element during the initialization and pass to
   // AudioStream Class.
-  dom::AudioChannel mAudioChannel;
+  dom::AudioChannelType mAudioChannelType;
 
   // True if the decoder has been directed to minimize its preroll before
   // playback starts. After the first time playback starts, we don't attempt
   // to minimize preroll, as we assume the user is likely to keep playing,
   // or play the media again.
   bool mMinimizePreroll;
 };
 
--- a/content/media/MediaDecoderStateMachine.cpp
+++ b/content/media/MediaDecoderStateMachine.cpp
@@ -758,38 +758,38 @@ void MediaDecoderStateMachine::AudioLoop
   int64_t audioStartTime = -1;
   uint32_t channels, rate;
   double volume = -1;
   bool setVolume;
   double playbackRate = -1;
   bool setPlaybackRate;
   bool preservesPitch;
   bool setPreservesPitch;
-  AudioChannel audioChannel;
+  AudioChannelType audioChannelType;
 
   {
     ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
     mAudioCompleted = false;
     audioStartTime = mAudioStartTime;
     NS_ASSERTION(audioStartTime != -1, "Should have audio start time by now");
     channels = mInfo.mAudio.mChannels;
     rate = mInfo.mAudio.mRate;
 
-    audioChannel = mDecoder->GetAudioChannel();
+    audioChannelType = mDecoder->GetAudioChannelType();
     volume = mVolume;
     preservesPitch = mPreservesPitch;
     playbackRate = mPlaybackRate;
   }
 
   {
     // AudioStream initialization can block for extended periods in unusual
     // circumstances, so we take care to drop the decoder monitor while
     // initializing.
     nsAutoPtr<AudioStream> audioStream(new AudioStream());
-    audioStream->Init(channels, rate, audioChannel, AudioStream::HighLatency);
+    audioStream->Init(channels, rate, audioChannelType, AudioStream::HighLatency);
     audioStream->SetVolume(volume);
     if (audioStream->SetPreservesPitch(preservesPitch) != NS_OK) {
       NS_WARNING("Setting the pitch preservation failed at AudioLoop start.");
     }
     if (playbackRate != 1.0) {
       NS_ASSERTION(playbackRate != 0,
                    "Don't set the playbackRate to 0 on an AudioStream.");
       if (audioStream->SetPlaybackRate(playbackRate) != NS_OK) {
--- a/content/media/MediaStreamGraph.cpp
+++ b/content/media/MediaStreamGraph.cpp
@@ -13,17 +13,17 @@
 #include "nsIAppShell.h"
 #include "nsIObserver.h"
 #include "nsServiceManagerUtils.h"
 #include "nsWidgetsCID.h"
 #include "prlog.h"
 #include "mozilla/Attributes.h"
 #include "TrackUnionStream.h"
 #include "ImageContainer.h"
-#include "AudioChannelService.h"
+#include "AudioChannelCommon.h"
 #include "AudioNodeEngine.h"
 #include "AudioNodeStream.h"
 #include "AudioNodeExternalInputStream.h"
 #include <algorithm>
 #include "DOMMediaStream.h"
 #include "GeckoProfiler.h"
 #include "mozilla/unused.h"
 
@@ -806,19 +806,17 @@ MediaStreamGraphImpl::CreateOrDestroyAud
         // stream ...
         MediaStream::AudioOutputStream* audioOutputStream =
           aStream->mAudioOutputStreams.AppendElement();
         audioOutputStream->mAudioPlaybackStartTime = aAudioOutputStartTime;
         audioOutputStream->mBlockedAudioTime = 0;
         audioOutputStream->mStream = new AudioStream();
         // XXX for now, allocate stereo output. But we need to fix this to
         // match the system's ideal channel configuration.
-        audioOutputStream->mStream->Init(2, tracks->GetRate(),
-                                         AudioChannel::Normal,
-                                         AudioStream::LowLatency);
+        audioOutputStream->mStream->Init(2, tracks->GetRate(), AUDIO_CHANNEL_NORMAL, AudioStream::LowLatency);
         audioOutputStream->mTrackID = tracks->GetID();
 
         LogLatency(AsyncLatencyLogger::AudioStreamCreate,
                    reinterpret_cast<uint64_t>(aStream),
                    reinterpret_cast<int64_t>(audioOutputStream->mStream.get()));
       }
     }
   }
--- a/content/media/webaudio/AudioDestinationNode.cpp
+++ b/content/media/webaudio/AudioDestinationNode.cpp
@@ -472,20 +472,50 @@ AudioDestinationNode::CheckAudioChannelP
 
 void
 AudioDestinationNode::CreateAudioChannelAgent()
 {
   if (mAudioChannelAgent) {
     mAudioChannelAgent->StopPlaying();
   }
 
+  AudioChannelType type = AUDIO_CHANNEL_NORMAL;
+  switch(mAudioChannel) {
+    case AudioChannel::Normal:
+      type = AUDIO_CHANNEL_NORMAL;
+      break;
+
+    case AudioChannel::Content:
+      type = AUDIO_CHANNEL_CONTENT;
+      break;
+
+    case AudioChannel::Notification:
+      type = AUDIO_CHANNEL_NOTIFICATION;
+      break;
+
+    case AudioChannel::Alarm:
+      type = AUDIO_CHANNEL_ALARM;
+      break;
+
+    case AudioChannel::Telephony:
+      type = AUDIO_CHANNEL_TELEPHONY;
+      break;
+
+    case AudioChannel::Ringer:
+      type = AUDIO_CHANNEL_RINGER;
+      break;
+
+    case AudioChannel::Publicnotification:
+      type = AUDIO_CHANNEL_PUBLICNOTIFICATION;
+      break;
+
+  }
+
   mAudioChannelAgent = new AudioChannelAgent();
-  mAudioChannelAgent->InitWithWeakCallback(GetOwner(),
-                                           static_cast<int32_t>(mAudioChannel),
-                                           this);
+  mAudioChannelAgent->InitWithWeakCallback(GetOwner(), type, this);
 
   nsCOMPtr<nsIDocShell> docshell = do_GetInterface(GetOwner());
   if (docshell) {
     bool isActive = false;
     docshell->GetIsActive(&isActive);
     mAudioChannelAgent->SetVisibilityState(isActive);
   }
 
--- a/content/svg/content/src/SVGAttrValueWrapper.h
+++ b/content/svg/content/src/SVGAttrValueWrapper.h
@@ -7,17 +7,17 @@
 #ifndef MOZILLA_SVGATTRVALUEWRAPPER_H__
 #define MOZILLA_SVGATTRVALUEWRAPPER_H__
 
 /**
  * Utility wrapper for handling SVG types used inside nsAttrValue so that these
  * types don't need to be exported outside the SVG module.
  */
 
-#include "nsStringGlue.h"
+#include "nsString.h"
 
 class nsSVGAngle;
 class nsSVGIntegerPair;
 class nsSVGLength2;
 class nsSVGNumberPair;
 class nsSVGViewBox;
 
 namespace mozilla {
--- a/dom/audiochannel/AudioChannelAgent.cpp
+++ b/dom/audiochannel/AudioChannelAgent.cpp
@@ -79,32 +79,32 @@ nsresult
 AudioChannelAgent::InitInternal(nsIDOMWindow* aWindow, int32_t aChannelType,
                                 nsIAudioChannelAgentCallback *aCallback,
                                 bool aUseWeakRef, bool aWithVideo)
 {
   // We need the window only for IPC.
   MOZ_ASSERT(aWindow || XRE_GetProcessType() == GeckoProcessType_Default);
 
   // We syncd the enum of channel type between nsIAudioChannelAgent.idl and
-  // AudioChannelBinding.h the same.
-  MOZ_ASSERT(static_cast<AudioChannel>(AUDIO_AGENT_CHANNEL_NORMAL) ==
-             AudioChannel::Normal &&
-             static_cast<AudioChannel>(AUDIO_AGENT_CHANNEL_CONTENT) ==
-             AudioChannel::Content &&
-             static_cast<AudioChannel>(AUDIO_AGENT_CHANNEL_NOTIFICATION) ==
-             AudioChannel::Notification &&
-             static_cast<AudioChannel>(AUDIO_AGENT_CHANNEL_ALARM) ==
-             AudioChannel::Alarm &&
-             static_cast<AudioChannel>(AUDIO_AGENT_CHANNEL_TELEPHONY) ==
-             AudioChannel::Telephony &&
-             static_cast<AudioChannel>(AUDIO_AGENT_CHANNEL_RINGER) ==
-             AudioChannel::Ringer &&
-             static_cast<AudioChannel>(AUDIO_AGENT_CHANNEL_PUBLICNOTIFICATION) ==
-             AudioChannel::Publicnotification,
-             "Enum of channel on nsIAudioChannelAgent.idl should be the same with AudioChannelBinding.h");
+  // AudioChannelCommon.h the same.
+  static_assert(static_cast<AudioChannelType>(AUDIO_AGENT_CHANNEL_NORMAL) ==
+                AUDIO_CHANNEL_NORMAL &&
+                static_cast<AudioChannelType>(AUDIO_AGENT_CHANNEL_CONTENT) ==
+                AUDIO_CHANNEL_CONTENT &&
+                static_cast<AudioChannelType>(AUDIO_AGENT_CHANNEL_NOTIFICATION) ==
+                AUDIO_CHANNEL_NOTIFICATION &&
+                static_cast<AudioChannelType>(AUDIO_AGENT_CHANNEL_ALARM) ==
+                AUDIO_CHANNEL_ALARM &&
+                static_cast<AudioChannelType>(AUDIO_AGENT_CHANNEL_TELEPHONY) ==
+                AUDIO_CHANNEL_TELEPHONY &&
+                static_cast<AudioChannelType>(AUDIO_AGENT_CHANNEL_RINGER) ==
+                AUDIO_CHANNEL_RINGER &&
+                static_cast<AudioChannelType>(AUDIO_AGENT_CHANNEL_PUBLICNOTIFICATION) ==
+                AUDIO_CHANNEL_PUBLICNOTIFICATION,
+                "Enum of channel on nsIAudioChannelAgent.idl should be the same with AudioChannelCommon.h");
 
   if (mAudioChannelType != AUDIO_AGENT_CHANNEL_ERROR ||
       aChannelType > AUDIO_AGENT_CHANNEL_PUBLICNOTIFICATION ||
       aChannelType < AUDIO_AGENT_CHANNEL_NORMAL) {
     return NS_ERROR_FAILURE;
   }
 
   mWindow = aWindow;
@@ -126,17 +126,17 @@ NS_IMETHODIMP AudioChannelAgent::StartPl
 {
   AudioChannelService *service = AudioChannelService::GetAudioChannelService();
   if (mAudioChannelType == AUDIO_AGENT_CHANNEL_ERROR ||
       service == nullptr || mIsRegToService) {
     return NS_ERROR_FAILURE;
   }
 
   service->RegisterAudioChannelAgent(this,
-    static_cast<AudioChannel>(mAudioChannelType), mWithVideo);
+    static_cast<AudioChannelType>(mAudioChannelType), mWithVideo);
   *_retval = service->GetState(this, !mVisible);
   mIsRegToService = true;
   return NS_OK;
 }
 
 /* void stopPlaying (); */
 NS_IMETHODIMP AudioChannelAgent::StopPlaying(void)
 {
--- a/dom/audiochannel/AudioChannelCommon.h
+++ b/dom/audiochannel/AudioChannelCommon.h
@@ -5,16 +5,30 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_audiochannelcommon_h__
 #define mozilla_dom_audiochannelcommon_h__
 
 namespace mozilla {
 namespace dom {
 
+// The audio channel. Read the nsIHTMLMediaElement.idl for a description
+// about this attribute.
+enum AudioChannelType {
+  AUDIO_CHANNEL_DEFAULT = -1,
+  AUDIO_CHANNEL_NORMAL = 0,
+  AUDIO_CHANNEL_CONTENT,
+  AUDIO_CHANNEL_NOTIFICATION,
+  AUDIO_CHANNEL_ALARM,
+  AUDIO_CHANNEL_TELEPHONY,
+  AUDIO_CHANNEL_RINGER,
+  AUDIO_CHANNEL_PUBLICNOTIFICATION,
+  AUDIO_CHANNEL_LAST
+};
+
 enum AudioChannelState {
   AUDIO_CHANNEL_STATE_NORMAL = 0,
   AUDIO_CHANNEL_STATE_MUTED,
   AUDIO_CHANNEL_STATE_FADED,
   AUDIO_CHANNEL_STATE_LAST
 };
 
 } // namespace dom
--- a/dom/audiochannel/AudioChannelService.cpp
+++ b/dom/audiochannel/AudioChannelService.cpp
@@ -32,28 +32,16 @@
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::hal;
 
 StaticRefPtr<AudioChannelService> gAudioChannelService;
 
-// Mappings from 'mozaudiochannel' attribute strings to an enumeration.
-static const nsAttrValue::EnumTable kMozAudioChannelAttributeTable[] = {
-  { "normal",             (int16_t)AudioChannel::Normal },
-  { "content",            (int16_t)AudioChannel::Content },
-  { "notification",       (int16_t)AudioChannel::Notification },
-  { "alarm",              (int16_t)AudioChannel::Alarm },
-  { "telephony",          (int16_t)AudioChannel::Telephony },
-  { "ringer",             (int16_t)AudioChannel::Ringer },
-  { "publicnotification", (int16_t)AudioChannel::Publicnotification },
-  { nullptr }
-};
-
 // static
 AudioChannelService*
 AudioChannelService::GetAudioChannelService()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (XRE_GetProcessType() != GeckoProcessType_Default) {
     return AudioChannelServiceChild::GetAudioChannelService();
@@ -82,18 +70,18 @@ AudioChannelService::Shutdown()
   if (gAudioChannelService) {
     gAudioChannelService = nullptr;
   }
 }
 
 NS_IMPL_ISUPPORTS2(AudioChannelService, nsIObserver, nsITimerCallback)
 
 AudioChannelService::AudioChannelService()
-: mCurrentHigherChannel(INT32_MAX)
-, mCurrentVisibleHigherChannel(INT32_MAX)
+: mCurrentHigherChannel(AUDIO_CHANNEL_LAST)
+, mCurrentVisibleHigherChannel(AUDIO_CHANNEL_LAST)
 , mPlayableHiddenContentChildID(CONTENT_PROCESS_ID_UNKNOWN)
 , mDisabled(false)
 , mDefChannelChildID(CONTENT_PROCESS_ID_UNKNOWN)
 {
   if (XRE_GetProcessType() == GeckoProcessType_Default) {
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     if (obs) {
       obs->AddObserver(this, "ipc:content-shutdown", false);
@@ -107,62 +95,62 @@ AudioChannelService::AudioChannelService
 }
 
 AudioChannelService::~AudioChannelService()
 {
 }
 
 void
 AudioChannelService::RegisterAudioChannelAgent(AudioChannelAgent* aAgent,
-                                               AudioChannel aChannel,
+                                               AudioChannelType aType,
                                                bool aWithVideo)
 {
   if (mDisabled) {
     return;
   }
 
-  AudioChannelAgentData* data = new AudioChannelAgentData(aChannel,
+  MOZ_ASSERT(aType != AUDIO_CHANNEL_DEFAULT);
+
+  AudioChannelAgentData* data = new AudioChannelAgentData(aType,
                                 true /* aElementHidden */,
                                 AUDIO_CHANNEL_STATE_MUTED /* aState */,
                                 aWithVideo);
   mAgents.Put(aAgent, data);
-  RegisterType(aChannel, CONTENT_PROCESS_ID_MAIN, aWithVideo);
+  RegisterType(aType, CONTENT_PROCESS_ID_MAIN, aWithVideo);
 
   // If this is the first agent for this window, we must notify the observers.
   uint32_t count = CountWindow(aAgent->Window());
   if (count == 1) {
     nsCOMPtr<nsIObserverService> observerService =
       services::GetObserverService();
     if (observerService) {
       observerService->NotifyObservers(ToSupports(aAgent->Window()),
                                        "media-playback",
                                        NS_LITERAL_STRING("active").get());
     }
   }
 }
 
 void
-AudioChannelService::RegisterType(AudioChannel aChannel, uint64_t aChildID,
-                                  bool aWithVideo)
+AudioChannelService::RegisterType(AudioChannelType aType, uint64_t aChildID, bool aWithVideo)
 {
   if (mDisabled) {
     return;
   }
 
-  AudioChannelInternalType type = GetInternalType(aChannel, true);
+  AudioChannelInternalType type = GetInternalType(aType, true);
   mChannelCounters[type].AppendElement(aChildID);
 
   if (XRE_GetProcessType() == GeckoProcessType_Default) {
     // Since there is another telephony registered, we can unregister old one
     // immediately.
-    if (mDeferTelChannelTimer && aChannel == AudioChannel::Telephony) {
+    if (mDeferTelChannelTimer && aType == AUDIO_CHANNEL_TELEPHONY) {
       mDeferTelChannelTimer->Cancel();
       mDeferTelChannelTimer = nullptr;
-      UnregisterTypeInternal(aChannel, mTimerElementHidden, mTimerChildID,
-                             false);
+      UnregisterTypeInternal(aType, mTimerElementHidden, mTimerChildID, false);
     }
 
     if (aWithVideo) {
       mWithVideoChildIDs.AppendElement(aChildID);
     }
 
     // No hidden content channel can be playable if there is a content channel
     // in foreground (bug 855208), nor if there is a normal channel with video
@@ -193,17 +181,17 @@ AudioChannelService::UnregisterAudioChan
   if (mDisabled) {
     return;
   }
 
   nsAutoPtr<AudioChannelAgentData> data;
   mAgents.RemoveAndForget(aAgent, data);
 
   if (data) {
-    UnregisterType(data->mChannel, data->mElementHidden,
+    UnregisterType(data->mType, data->mElementHidden,
                    CONTENT_PROCESS_ID_MAIN, data->mWithVideo);
   }
 #ifdef MOZ_WIDGET_GONK
   bool active = AnyAudioChannelIsActive();
   for (uint32_t i = 0; i < mSpeakerManager.Length(); i++) {
     mSpeakerManager[i]->SetAudioChannelActive(active);
   }
 #endif
@@ -217,84 +205,84 @@ AudioChannelService::UnregisterAudioChan
       observerService->NotifyObservers(ToSupports(aAgent->Window()),
                                        "media-playback",
                                        NS_LITERAL_STRING("inactive").get());
     }
   }
 }
 
 void
-AudioChannelService::UnregisterType(AudioChannel aChannel,
+AudioChannelService::UnregisterType(AudioChannelType aType,
                                     bool aElementHidden,
                                     uint64_t aChildID,
                                     bool aWithVideo)
 {
   if (mDisabled) {
     return;
   }
 
   // There are two reasons to defer the decrease of telephony channel.
   // 1. User can have time to remove device from his ear before music resuming.
   // 2. Give BT SCO to be disconnected before starting to connect A2DP.
   if (XRE_GetProcessType() == GeckoProcessType_Default &&
-      aChannel == AudioChannel::Telephony &&
+      aType == AUDIO_CHANNEL_TELEPHONY &&
       (mChannelCounters[AUDIO_CHANNEL_INT_TELEPHONY_HIDDEN].Length() +
        mChannelCounters[AUDIO_CHANNEL_INT_TELEPHONY].Length()) == 1) {
     mTimerElementHidden = aElementHidden;
     mTimerChildID = aChildID;
     mDeferTelChannelTimer = do_CreateInstance("@mozilla.org/timer;1");
     mDeferTelChannelTimer->InitWithCallback(this, 1500, nsITimer::TYPE_ONE_SHOT);
     return;
   }
 
-  UnregisterTypeInternal(aChannel, aElementHidden, aChildID, aWithVideo);
+  UnregisterTypeInternal(aType, aElementHidden, aChildID, aWithVideo);
 }
 
 void
-AudioChannelService::UnregisterTypeInternal(AudioChannel aChannel,
+AudioChannelService::UnregisterTypeInternal(AudioChannelType aType,
                                             bool aElementHidden,
                                             uint64_t aChildID,
                                             bool aWithVideo)
 {
   // The array may contain multiple occurrence of this appId but
   // this should remove only the first one.
-  AudioChannelInternalType type = GetInternalType(aChannel, aElementHidden);
+  AudioChannelInternalType type = GetInternalType(aType, aElementHidden);
   MOZ_ASSERT(mChannelCounters[type].Contains(aChildID));
   mChannelCounters[type].RemoveElement(aChildID);
 
   // In order to avoid race conditions, it's safer to notify any existing
   // agent any time a new one is registered.
   if (XRE_GetProcessType() == GeckoProcessType_Default) {
     // No hidden content channel is playable if the original playable hidden
     // process does not need to play audio from background anymore.
-    if (aChannel == AudioChannel::Content &&
+    if (aType == AUDIO_CHANNEL_CONTENT &&
         mPlayableHiddenContentChildID == aChildID &&
         !mChannelCounters[AUDIO_CHANNEL_INT_CONTENT_HIDDEN].Contains(aChildID)) {
       mPlayableHiddenContentChildID = CONTENT_PROCESS_ID_UNKNOWN;
     }
 
     if (aWithVideo) {
       MOZ_ASSERT(mWithVideoChildIDs.Contains(aChildID));
       mWithVideoChildIDs.RemoveElement(aChildID);
     }
 
     SendAudioChannelChangedNotification(aChildID);
     Notify();
   }
 }
 
 void
-AudioChannelService::UpdateChannelType(AudioChannel aChannel,
+AudioChannelService::UpdateChannelType(AudioChannelType aType,
                                        uint64_t aChildID,
                                        bool aElementHidden,
                                        bool aElementWasHidden)
 {
   // Calculate the new and old internal type and update the hashtable if needed.
-  AudioChannelInternalType newType = GetInternalType(aChannel, aElementHidden);
-  AudioChannelInternalType oldType = GetInternalType(aChannel, aElementWasHidden);
+  AudioChannelInternalType newType = GetInternalType(aType, aElementHidden);
+  AudioChannelInternalType oldType = GetInternalType(aType, aElementWasHidden);
 
   if (newType != oldType) {
     mChannelCounters[newType].AppendElement(aChildID);
     MOZ_ASSERT(mChannelCounters[oldType].Contains(aChildID));
     mChannelCounters[oldType].RemoveElement(aChildID);
   }
 
   // No hidden content channel can be playable if there is a content channel
@@ -322,36 +310,34 @@ AudioChannelService::GetState(AudioChann
   if (!mAgents.Get(aAgent, &data)) {
     return AUDIO_CHANNEL_STATE_MUTED;
   }
 
   bool oldElementHidden = data->mElementHidden;
   // Update visibility.
   data->mElementHidden = aElementHidden;
 
-  data->mState = GetStateInternal(data->mChannel, CONTENT_PROCESS_ID_MAIN,
+  data->mState = GetStateInternal(data->mType, CONTENT_PROCESS_ID_MAIN,
                                 aElementHidden, oldElementHidden);
   return data->mState;
 }
 
 AudioChannelState
-AudioChannelService::GetStateInternal(AudioChannel aChannel, uint64_t aChildID,
-                                      bool aElementHidden,
-                                      bool aElementWasHidden)
+AudioChannelService::GetStateInternal(AudioChannelType aType, uint64_t aChildID,
+                                      bool aElementHidden, bool aElementWasHidden)
 {
-  UpdateChannelType(aChannel, aChildID, aElementHidden, aElementWasHidden);
+  UpdateChannelType(aType, aChildID, aElementHidden, aElementWasHidden);
 
   // Calculating the new and old type and update the hashtable if needed.
-  AudioChannelInternalType newType = GetInternalType(aChannel, aElementHidden);
-  AudioChannelInternalType oldType = GetInternalType(aChannel,
-                                                     aElementWasHidden);
+  AudioChannelInternalType newType = GetInternalType(aType, aElementHidden);
+  AudioChannelInternalType oldType = GetInternalType(aType, aElementWasHidden);
 
   if (newType != oldType &&
-      (aChannel == AudioChannel::Content ||
-       (aChannel == AudioChannel::Normal &&
+      (aType == AUDIO_CHANNEL_CONTENT ||
+       (aType == AUDIO_CHANNEL_NORMAL &&
         mWithVideoChildIDs.Contains(aChildID)))) {
     Notify();
   }
 
   SendAudioChannelChangedNotification(aChildID);
 
   // Let play any visible audio channel.
   if (!aElementHidden) {
@@ -436,48 +422,40 @@ bool
 AudioChannelService::ProcessContentOrNormalChannelIsActive(uint64_t aChildID)
 {
   return mChannelCounters[AUDIO_CHANNEL_INT_CONTENT].Contains(aChildID) ||
          mChannelCounters[AUDIO_CHANNEL_INT_CONTENT_HIDDEN].Contains(aChildID) ||
          mChannelCounters[AUDIO_CHANNEL_INT_NORMAL].Contains(aChildID);
 }
 
 void
-AudioChannelService::SetDefaultVolumeControlChannel(int32_t aChannel,
+AudioChannelService::SetDefaultVolumeControlChannel(AudioChannelType aType,
                                                     bool aHidden)
 {
-  SetDefaultVolumeControlChannelInternal(aChannel, aHidden,
-                                         CONTENT_PROCESS_ID_MAIN);
+  SetDefaultVolumeControlChannelInternal(aType, aHidden, CONTENT_PROCESS_ID_MAIN);
 }
 
 void
-AudioChannelService::SetDefaultVolumeControlChannelInternal(int32_t aChannel,
-                                                            bool aHidden,
-                                                            uint64_t aChildID)
+AudioChannelService::SetDefaultVolumeControlChannelInternal(
+  AudioChannelType aType, bool aHidden, uint64_t aChildID)
 {
   if (XRE_GetProcessType() != GeckoProcessType_Default) {
     return;
   }
 
   // If this child is in the background and mDefChannelChildID is set to
   // others then it means other child in the foreground already set it's
   // own default channel already.
   if (!aHidden && mDefChannelChildID != aChildID) {
     return;
   }
 
   mDefChannelChildID = aChildID;
   nsString channelName;
-
-  if (aChannel == -1) {
-    channelName.AssignASCII("unknown");
-  } else {
-    GetAudioChannelString(static_cast<AudioChannel>(aChannel), channelName);
-  }
-
+  channelName.AssignASCII(ChannelName(aType));
   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
   if (obs) {
     obs->NotifyObservers(nullptr, "default-volume-channel-changed",
                          channelName.get());
   }
 }
 
 void
@@ -492,94 +470,87 @@ AudioChannelService::SendAudioChannelCha
 
   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
   if (obs) {
     obs->NotifyObservers(static_cast<nsIWritablePropertyBag*>(props),
                          "audio-channel-process-changed", nullptr);
   }
 
   // Calculating the most important active channel.
-  int32_t higher = -1;
+  AudioChannelType higher = AUDIO_CHANNEL_DEFAULT;
 
   // Top-Down in the hierarchy for visible elements
   if (!mChannelCounters[AUDIO_CHANNEL_INT_PUBLICNOTIFICATION].IsEmpty()) {
-    higher = static_cast<int32_t>(AudioChannel::Publicnotification);
+    higher = AUDIO_CHANNEL_PUBLICNOTIFICATION;
   }
 
   else if (!mChannelCounters[AUDIO_CHANNEL_INT_RINGER].IsEmpty()) {
-    higher = static_cast<int32_t>(AudioChannel::Ringer);
+    higher = AUDIO_CHANNEL_RINGER;
   }
 
   else if (!mChannelCounters[AUDIO_CHANNEL_INT_TELEPHONY].IsEmpty()) {
-    higher = static_cast<int32_t>(AudioChannel::Telephony);
+    higher = AUDIO_CHANNEL_TELEPHONY;
   }
 
   else if (!mChannelCounters[AUDIO_CHANNEL_INT_ALARM].IsEmpty()) {
-    higher = static_cast<int32_t>(AudioChannel::Alarm);
+    higher = AUDIO_CHANNEL_ALARM;
   }
 
   else if (!mChannelCounters[AUDIO_CHANNEL_INT_NOTIFICATION].IsEmpty()) {
-    higher = static_cast<int32_t>(AudioChannel::Notification);
+    higher = AUDIO_CHANNEL_NOTIFICATION;
   }
 
   else if (!mChannelCounters[AUDIO_CHANNEL_INT_CONTENT].IsEmpty()) {
-    higher = static_cast<int32_t>(AudioChannel::Content);
+    higher = AUDIO_CHANNEL_CONTENT;
   }
 
   else if (!mChannelCounters[AUDIO_CHANNEL_INT_NORMAL].IsEmpty()) {
-    higher = static_cast<int32_t>(AudioChannel::Normal);
+    higher = AUDIO_CHANNEL_NORMAL;
   }
 
-  int32_t visibleHigher = higher;
+  AudioChannelType visibleHigher = higher;
 
   // Top-Down in the hierarchy for non-visible elements
   // And we can ignore normal channel because it can't play in the background.
-  int32_t index;
-  for (index = 0; kMozAudioChannelAttributeTable[index].tag; ++index);
-
-  for (--index;
-       kMozAudioChannelAttributeTable[index].value > higher &&
-       kMozAudioChannelAttributeTable[index].value > (int16_t)AudioChannel::Normal;
-       --index) {
-    if (kMozAudioChannelAttributeTable[index].value == (int16_t)AudioChannel::Content &&
+  for (int i = AUDIO_CHANNEL_LAST - 1;
+       i > higher && i > AUDIO_CHANNEL_NORMAL; i--) {
+    if (i == AUDIO_CHANNEL_CONTENT &&
       mPlayableHiddenContentChildID != CONTENT_PROCESS_ID_UNKNOWN) {
-      higher = kMozAudioChannelAttributeTable[index].value;
+      higher = static_cast<AudioChannelType>(i);
     }
 
     // Each channel type will be split to fg and bg for recording the state,
     // so here need to do a translation.
-    if (!mChannelCounters[index * 2 + 1].IsEmpty()) {
-      higher = kMozAudioChannelAttributeTable[index].value;
+    if (!mChannelCounters[i * 2 + 1].IsEmpty()) {
+      higher = static_cast<AudioChannelType>(i);
       break;
     }
   }
 
   if (higher != mCurrentHigherChannel) {
     mCurrentHigherChannel = higher;
 
     nsString channelName;
-    if (mCurrentHigherChannel != -1) {
-      GetAudioChannelString(static_cast<AudioChannel>(mCurrentHigherChannel),
-                            channelName);
+    if (mCurrentHigherChannel != AUDIO_CHANNEL_DEFAULT) {
+      channelName.AssignASCII(ChannelName(mCurrentHigherChannel));
     } else {
       channelName.AssignLiteral("none");
     }
 
     if (obs) {
       obs->NotifyObservers(nullptr, "audio-channel-changed", channelName.get());
     }
   }
 
   if (visibleHigher != mCurrentVisibleHigherChannel) {
     mCurrentVisibleHigherChannel = visibleHigher;
 
     nsString channelName;
-    if (mCurrentVisibleHigherChannel != -1) {
-      GetAudioChannelString(static_cast<AudioChannel>(mCurrentVisibleHigherChannel),
-                            channelName);
+    if (mCurrentVisibleHigherChannel != AUDIO_CHANNEL_DEFAULT) {
+      channelName.AssignASCII(ChannelName(mCurrentVisibleHigherChannel));
     } else {
       channelName.AssignLiteral("none");
     }
 
     if (obs) {
       obs->NotifyObservers(nullptr, "visible-audio-channel-changed", channelName.get());
     }
   }
@@ -608,18 +579,17 @@ AudioChannelService::Notify()
   for (uint32_t i = 0; i < children.Length(); i++) {
     unused << children[i]->SendAudioChannelNotify();
   }
 }
 
 NS_IMETHODIMP
 AudioChannelService::Notify(nsITimer* aTimer)
 {
-  UnregisterTypeInternal(AudioChannel::Telephony, mTimerElementHidden,
-                         mTimerChildID, false);
+  UnregisterTypeInternal(AUDIO_CHANNEL_TELEPHONY, mTimerElementHidden, mTimerChildID, false);
   mDeferTelChannelTimer = nullptr;
   return NS_OK;
 }
 
 bool
 AudioChannelService::AnyAudioChannelIsActive()
 {
   for (int i = AUDIO_CHANNEL_INT_LAST - 1;
@@ -645,16 +615,44 @@ AudioChannelService::ChannelsActiveWithH
     if (!mChannelCounters[i].IsEmpty()) {
       return true;
     }
   }
 
   return false;
 }
 
+const char*
+AudioChannelService::ChannelName(AudioChannelType aType)
+{
+  static struct {
+    int32_t type;
+    const char* value;
+  } ChannelNameTable[] = {
+    { AUDIO_CHANNEL_NORMAL,             "normal" },
+    { AUDIO_CHANNEL_CONTENT,            "content" },
+    { AUDIO_CHANNEL_NOTIFICATION,       "notification" },
+    { AUDIO_CHANNEL_ALARM,              "alarm" },
+    { AUDIO_CHANNEL_TELEPHONY,          "telephony" },
+    { AUDIO_CHANNEL_RINGER,             "ringer" },
+    { AUDIO_CHANNEL_PUBLICNOTIFICATION, "publicnotification" },
+    { -1,                               "unknown" }
+  };
+
+  for (int i = AUDIO_CHANNEL_NORMAL; ; ++i) {
+    if (ChannelNameTable[i].type == aType ||
+        ChannelNameTable[i].type == -1) {
+      return ChannelNameTable[i].value;
+    }
+  }
+
+  NS_NOTREACHED("Execution should not reach here!");
+  return nullptr;
+}
+
 NS_IMETHODIMP
 AudioChannelService::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData)
 {
   if (!strcmp(aTopic, "xpcom-shutdown")) {
     mDisabled = true;
   }
 
   if (!strcmp(aTopic, "ipc:content-shutdown")) {
@@ -690,17 +688,18 @@ AudioChannelService::Observe(nsISupports
 
       // We don't have to remove the agents from the mAgents hashtable because if
       // that table contains only agents running on the same process.
 
       SendAudioChannelChangedNotification(childID);
       Notify();
 
       if (mDefChannelChildID == childID) {
-        SetDefaultVolumeControlChannelInternal(-1, false, childID);
+        SetDefaultVolumeControlChannelInternal(AUDIO_CHANNEL_DEFAULT,
+                                               false, childID);
         mDefChannelChildID = CONTENT_PROCESS_ID_UNKNOWN;
       }
     } else {
       NS_WARNING("ipc:content-shutdown message without childID property");
     }
   }
 #ifdef MOZ_WIDGET_GONK
   // To process the volume control on each audio channel according to
@@ -735,82 +734,83 @@ AudioChannelService::Observe(nsISupports
       return NS_OK;
     }
 
     nsCOMPtr<nsIAudioManager> audioManager = do_GetService(NS_AUDIOMANAGER_CONTRACTID);
     NS_ENSURE_TRUE(audioManager, NS_OK);
 
     int32_t index = value.toInt32();
     if (keyStr.EqualsLiteral("audio.volume.content")) {
-      audioManager->SetAudioChannelVolume((int32_t)AudioChannel::Content, index);
+      audioManager->SetAudioChannelVolume(AUDIO_CHANNEL_CONTENT, index);
     } else if (keyStr.EqualsLiteral("audio.volume.notification")) {
-      audioManager->SetAudioChannelVolume((int32_t)AudioChannel::Notification, index);
+      audioManager->SetAudioChannelVolume(AUDIO_CHANNEL_NOTIFICATION, index);
     } else if (keyStr.EqualsLiteral("audio.volume.alarm")) {
-      audioManager->SetAudioChannelVolume((int32_t)AudioChannel::Alarm, index);
+      audioManager->SetAudioChannelVolume(AUDIO_CHANNEL_ALARM, index);
     } else if (keyStr.EqualsLiteral("audio.volume.telephony")) {
-      audioManager->SetAudioChannelVolume((int32_t)AudioChannel::Telephony, index);
+      audioManager->SetAudioChannelVolume(AUDIO_CHANNEL_TELEPHONY, index);
     } else if (!keyStr.EqualsLiteral("audio.volume.bt_sco")) {
       // bt_sco is not a valid audio channel so we manipulate it in
       // AudioManager.cpp. And the others should not be used.
       // We didn't use MOZ_ASSUME_UNREACHABLE here because any web content who
       // has permission of mozSettings can set any names then it can be easy to
       // crash the B2G.
       NS_WARNING("unexpected audio channel for volume control");
     }
   }
 #endif
 
   return NS_OK;
 }
 
 AudioChannelService::AudioChannelInternalType
-AudioChannelService::GetInternalType(AudioChannel aChannel,
+AudioChannelService::GetInternalType(AudioChannelType aType,
                                      bool aElementHidden)
 {
-  switch (aChannel) {
-    case AudioChannel::Normal:
+  switch (aType) {
+    case AUDIO_CHANNEL_NORMAL:
       return aElementHidden
                ? AUDIO_CHANNEL_INT_NORMAL_HIDDEN
                : AUDIO_CHANNEL_INT_NORMAL;
 
-    case AudioChannel::Content:
+    case AUDIO_CHANNEL_CONTENT:
       return aElementHidden
                ? AUDIO_CHANNEL_INT_CONTENT_HIDDEN
                : AUDIO_CHANNEL_INT_CONTENT;
 
-    case AudioChannel::Notification:
+    case AUDIO_CHANNEL_NOTIFICATION:
       return aElementHidden
                ? AUDIO_CHANNEL_INT_NOTIFICATION_HIDDEN
                : AUDIO_CHANNEL_INT_NOTIFICATION;
 
-    case AudioChannel::Alarm:
+    case AUDIO_CHANNEL_ALARM:
       return aElementHidden
                ? AUDIO_CHANNEL_INT_ALARM_HIDDEN
                : AUDIO_CHANNEL_INT_ALARM;
 
-    case AudioChannel::Telephony:
+    case AUDIO_CHANNEL_TELEPHONY:
       return aElementHidden
                ? AUDIO_CHANNEL_INT_TELEPHONY_HIDDEN
                : AUDIO_CHANNEL_INT_TELEPHONY;
 
-    case AudioChannel::Ringer:
+    case AUDIO_CHANNEL_RINGER:
       return aElementHidden
                ? AUDIO_CHANNEL_INT_RINGER_HIDDEN
                : AUDIO_CHANNEL_INT_RINGER;
 
-    case AudioChannel::Publicnotification:
+    case AUDIO_CHANNEL_PUBLICNOTIFICATION:
       return aElementHidden
                ? AUDIO_CHANNEL_INT_PUBLICNOTIFICATION_HIDDEN
                : AUDIO_CHANNEL_INT_PUBLICNOTIFICATION;
 
+    case AUDIO_CHANNEL_LAST:
     default:
       break;
   }
 
-  MOZ_CRASH("unexpected audio channel");
+  MOZ_CRASH("unexpected audio channel type");
 }
 
 struct RefreshAgentsVolumeData
 {
   RefreshAgentsVolumeData(nsPIDOMWindow* aWindow)
     : mWindow(aWindow)
   {}
 
@@ -878,73 +878,56 @@ AudioChannelService::CountWindowEnumerat
 uint32_t
 AudioChannelService::CountWindow(nsIDOMWindow* aWindow)
 {
   CountWindowData data(aWindow);
   mAgents.EnumerateRead(CountWindowEnumerator, &data);
   return data.mCount;
 }
 
-/* static */ const nsAttrValue::EnumTable*
-AudioChannelService::GetAudioChannelTable()
-{
-  return kMozAudioChannelAttributeTable;
-}
-
-/* static */ AudioChannel
-AudioChannelService::GetAudioChannel(const nsAString& aChannel)
+// Mappings from 'mozaudiochannel' attribute strings to an enumeration.
+static const struct AudioChannelTable
 {
-  for (uint32_t i = 0; kMozAudioChannelAttributeTable[i].tag; ++i) {
-    if (aChannel.EqualsASCII(kMozAudioChannelAttributeTable[i].tag)) {
-      return static_cast<AudioChannel>(kMozAudioChannelAttributeTable[i].value);
-    }
-  }
-
-  return AudioChannel::Normal;
-}
+  const char* string;
+  AudioChannel value;
+} kMozAudioChannelAttributeTable[] = {
+  { "normal",             AudioChannel::Normal },
+  { "content",            AudioChannel::Content },
+  { "notification",       AudioChannel::Notification },
+  { "alarm",              AudioChannel::Alarm },
+  { "telephony",          AudioChannel::Telephony },
+  { "ringer",             AudioChannel::Ringer },
+  { "publicnotification", AudioChannel::Publicnotification },
+  { nullptr }
+};
 
 /* static */ AudioChannel
 AudioChannelService::GetDefaultAudioChannel()
 {
   nsString audioChannel = Preferences::GetString("media.defaultAudioChannel");
   if (audioChannel.IsEmpty()) {
     return AudioChannel::Normal;
   }
 
-  for (uint32_t i = 0; kMozAudioChannelAttributeTable[i].tag; ++i) {
-    if (audioChannel.EqualsASCII(kMozAudioChannelAttributeTable[i].tag)) {
-      return static_cast<AudioChannel>(kMozAudioChannelAttributeTable[i].value);
+  for (uint32_t i = 0; kMozAudioChannelAttributeTable[i].string; ++i) {
+    if (audioChannel.EqualsASCII(kMozAudioChannelAttributeTable[i].string)) {
+      return kMozAudioChannelAttributeTable[i].value;
     }
   }
 
   return AudioChannel::Normal;
 }
 
 /* static */ void
-AudioChannelService::GetAudioChannelString(AudioChannel aChannel,
-                                           nsAString& aString)
-{
-  aString.AssignASCII("normal");
-
-  for (uint32_t i = 0; kMozAudioChannelAttributeTable[i].tag; ++i) {
-    if (aChannel ==
-        static_cast<AudioChannel>(kMozAudioChannelAttributeTable[i].value)) {
-      aString.AssignASCII(kMozAudioChannelAttributeTable[i].tag);
-      break;
-    }
-  }
-}
-
-/* static */ void
-AudioChannelService::GetDefaultAudioChannelString(nsAString& aString)
+AudioChannelService::GetDefaultAudioChannelString(nsString& aString)
 {
   aString.AssignASCII("normal");
 
   nsString audioChannel = Preferences::GetString("media.defaultAudioChannel");
   if (!audioChannel.IsEmpty()) {
-    for (uint32_t i = 0; kMozAudioChannelAttributeTable[i].tag; ++i) {
-      if (audioChannel.EqualsASCII(kMozAudioChannelAttributeTable[i].tag)) {
+    for (uint32_t i = 0; kMozAudioChannelAttributeTable[i].string; ++i) {
+      if (audioChannel.EqualsASCII(kMozAudioChannelAttributeTable[i].string)) {
         aString = audioChannel;
         break;
       }
     }
   }
 }
--- a/dom/audiochannel/AudioChannelService.h
+++ b/dom/audiochannel/AudioChannelService.h
@@ -9,17 +9,16 @@
 
 #include "nsAutoPtr.h"
 #include "nsIObserver.h"
 #include "nsTArray.h"
 #include "nsITimer.h"
 
 #include "AudioChannelCommon.h"
 #include "AudioChannelAgent.h"
-#include "nsAttrValue.h"
 #include "nsClassHashtable.h"
 #include "mozilla/dom/AudioChannelBinding.h"
 
 class nsPIDOMWindow;
 
 namespace mozilla {
 namespace dom {
 #ifdef MOZ_WIDGET_GONK
@@ -44,20 +43,20 @@ public:
 
   /**
    * Shutdown the singleton.
    */
   static void Shutdown();
 
   /**
    * Any audio channel agent that starts playing should register itself to
-   * this service, sharing the AudioChannel.
+   * this service, sharing the AudioChannelType.
    */
   virtual void RegisterAudioChannelAgent(AudioChannelAgent* aAgent,
-                                         AudioChannel aChannel,
+                                         AudioChannelType aType,
                                          bool aWithVideo);
 
   /**
    * Any audio channel agent that stops playing should unregister itself to
    * this service.
    */
   virtual void UnregisterAudioChannelAgent(AudioChannelAgent* aAgent);
 
@@ -77,21 +76,19 @@ public:
   /**
    * Return true if a normal or content channel is active for the given
    * process ID.
    */
   virtual bool ProcessContentOrNormalChannelIsActive(uint64_t aChildID);
 
   /***
    * AudioChannelManager calls this function to notify the default channel used
-   * to adjust volume when there is no any active channel. if aChannel is -1,
-   * the default audio channel will be used. Otherwise aChannel is casted to
-   * AudioChannel enum.
+   * to adjust volume when there is no any active channel.
    */
-  virtual void SetDefaultVolumeControlChannel(int32_t aChannel,
+  virtual void SetDefaultVolumeControlChannel(AudioChannelType aType,
                                               bool aHidden);
 
   bool AnyAudioChannelIsActive();
 
   void RefreshAgentsVolume(nsPIDOMWindow* aWindow);
 
 #ifdef MOZ_WIDGET_GONK
   void RegisterSpeakerManager(SpeakerManagerService* aSpeakerManager)
@@ -102,48 +99,45 @@ public:
   }
 
   void UnregisterSpeakerManager(SpeakerManagerService* aSpeakerManager)
   {
     mSpeakerManager.RemoveElement(aSpeakerManager);
   }
 #endif
 
-  static const nsAttrValue::EnumTable* GetAudioChannelTable();
-  static AudioChannel GetAudioChannel(const nsAString& aString);
   static AudioChannel GetDefaultAudioChannel();
-  static void GetAudioChannelString(AudioChannel aChannel, nsAString& aString);
-  static void GetDefaultAudioChannelString(nsAString& aString);
+  static void GetDefaultAudioChannelString(nsString& aString);
 
 protected:
   void Notify();
 
   /**
    * Send the audio-channel-changed notification for the given process ID if
    * needed.
    */
   void SendAudioChannelChangedNotification(uint64_t aChildID);
 
   /* Register/Unregister IPC types: */
-  void RegisterType(AudioChannel aChannel, uint64_t aChildID, bool aWithVideo);
-  void UnregisterType(AudioChannel aChannel, bool aElementHidden,
+  void RegisterType(AudioChannelType aType, uint64_t aChildID, bool aWithVideo);
+  void UnregisterType(AudioChannelType aType, bool aElementHidden,
                       uint64_t aChildID, bool aWithVideo);
-  void UnregisterTypeInternal(AudioChannel aChannel, bool aElementHidden,
+  void UnregisterTypeInternal(AudioChannelType aType, bool aElementHidden,
                               uint64_t aChildID, bool aWithVideo);
 
-  AudioChannelState GetStateInternal(AudioChannel aChannel, uint64_t aChildID,
+  AudioChannelState GetStateInternal(AudioChannelType aType, uint64_t aChildID,
                                      bool aElementHidden,
                                      bool aElementWasHidden);
 
   /* Update the internal type value following the visibility changes */
-  void UpdateChannelType(AudioChannel aChannel, uint64_t aChildID,
+  void UpdateChannelType(AudioChannelType aType, uint64_t aChildID,
                          bool aElementHidden, bool aElementWasHidden);
 
   /* Send the default-volume-channel-changed notification */
-  void SetDefaultVolumeControlChannelInternal(int32_t aChannel,
+  void SetDefaultVolumeControlChannelInternal(AudioChannelType aType,
                                               bool aHidden, uint64_t aChildID);
 
   AudioChannelService();
   virtual ~AudioChannelService();
 
   enum AudioChannelInternalType {
     AUDIO_CHANNEL_INT_NORMAL = 0,
     AUDIO_CHANNEL_INT_NORMAL_HIDDEN,
@@ -162,32 +156,34 @@ protected:
     AUDIO_CHANNEL_INT_LAST
   };
 
   bool ChannelsActiveWithHigherPriorityThan(AudioChannelInternalType aType);
 
   bool CheckVolumeFadedCondition(AudioChannelInternalType aType,
                                  bool aElementHidden);
 
-  AudioChannelInternalType GetInternalType(AudioChannel aChannel,
+  const char* ChannelName(AudioChannelType aType);
+
+  AudioChannelInternalType GetInternalType(AudioChannelType aType,
                                            bool aElementHidden);
 
   class AudioChannelAgentData {
   public:
-    AudioChannelAgentData(AudioChannel aChannel,
+    AudioChannelAgentData(AudioChannelType aType,
                           bool aElementHidden,
                           AudioChannelState aState,
                           bool aWithVideo)
-    : mChannel(aChannel)
+    : mType(aType)
     , mElementHidden(aElementHidden)
     , mState(aState)
     , mWithVideo(aWithVideo)
     {}
 
-    AudioChannel mChannel;
+    AudioChannelType mType;
     bool mElementHidden;
     AudioChannelState mState;
     const bool mWithVideo;
   };
 
   static PLDHashOperator
   NotifyEnumerator(AudioChannelAgent* aAgent,
                    AudioChannelAgentData* aData, void *aUnused);
@@ -206,18 +202,18 @@ protected:
   uint32_t CountWindow(nsIDOMWindow* aWindow);
 
   nsClassHashtable< nsPtrHashKey<AudioChannelAgent>, AudioChannelAgentData > mAgents;
 #ifdef MOZ_WIDGET_GONK
   nsTArray<SpeakerManagerService*>  mSpeakerManager;
 #endif
   nsTArray<uint64_t> mChannelCounters[AUDIO_CHANNEL_INT_LAST];
 
-  int32_t mCurrentHigherChannel;
-  int32_t mCurrentVisibleHigherChannel;
+  AudioChannelType mCurrentHigherChannel;
+  AudioChannelType mCurrentVisibleHigherChannel;
 
   nsTArray<uint64_t> mWithVideoChildIDs;
 
   // mPlayableHiddenContentChildID stores the ChildID of the process which can
   // play content channel(s) in the background.
   // A background process contained content channel(s) will become playable:
   //   1. When this background process registers its content channel(s) in
   //   AudioChannelService and there is no foreground process with registered
--- a/dom/audiochannel/AudioChannelServiceChild.cpp
+++ b/dom/audiochannel/AudioChannelServiceChild.cpp
@@ -67,39 +67,39 @@ AudioChannelServiceChild::GetState(Audio
   AudioChannelAgentData* data;
   if (!mAgents.Get(aAgent, &data)) {
     return AUDIO_CHANNEL_STATE_MUTED;
   }
 
   AudioChannelState state = AUDIO_CHANNEL_STATE_MUTED;
   bool oldElementHidden = data->mElementHidden;
 
-  UpdateChannelType(data->mChannel, CONTENT_PROCESS_ID_MAIN, aElementHidden,
-                    oldElementHidden);
+  UpdateChannelType(data->mType, CONTENT_PROCESS_ID_MAIN, aElementHidden, oldElementHidden);
 
   // Update visibility.
   data->mElementHidden = aElementHidden;
 
   ContentChild* cc = ContentChild::GetSingleton();
-  cc->SendAudioChannelGetState(data->mChannel, aElementHidden, oldElementHidden,
-                               &state);
+  cc->SendAudioChannelGetState(data->mType, aElementHidden, oldElementHidden, &state);
   data->mState = state;
   cc->SendAudioChannelChangedNotification();
 
   return state;
 }
 
 void
 AudioChannelServiceChild::RegisterAudioChannelAgent(AudioChannelAgent* aAgent,
-                                                    AudioChannel aChannel,
+                                                    AudioChannelType aType,
                                                     bool aWithVideo)
 {
-  AudioChannelService::RegisterAudioChannelAgent(aAgent, aChannel, aWithVideo);
+  MOZ_ASSERT(aType != AUDIO_CHANNEL_DEFAULT);
 
-  ContentChild::GetSingleton()->SendAudioChannelRegisterType(aChannel, aWithVideo);
+  AudioChannelService::RegisterAudioChannelAgent(aAgent, aType, aWithVideo);
+
+  ContentChild::GetSingleton()->SendAudioChannelRegisterType(aType, aWithVideo);
 
   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
   if (obs) {
     obs->NotifyObservers(nullptr, "audio-channel-agent-changed", nullptr);
   }
 }
 
 void
@@ -112,31 +112,31 @@ AudioChannelServiceChild::UnregisterAudi
 
   // We need to keep a copy because unregister will remove the
   // AudioChannelAgentData object from the hashtable.
   AudioChannelAgentData data(*pData);
 
   AudioChannelService::UnregisterAudioChannelAgent(aAgent);
 
   ContentChild::GetSingleton()->SendAudioChannelUnregisterType(
-      data.mChannel, data.mElementHidden, data.mWithVideo);
+      data.mType, data.mElementHidden, data.mWithVideo);
 
   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
   if (obs) {
     obs->NotifyObservers(nullptr, "audio-channel-agent-changed", nullptr);
   }
 #ifdef MOZ_WIDGET_GONK
   bool active = AnyAudioChannelIsActive();
   for (uint32_t i = 0; i < mSpeakerManager.Length(); i++) {
     mSpeakerManager[i]->SetAudioChannelActive(active);
   }
 #endif
 }
 
 void
-AudioChannelServiceChild::SetDefaultVolumeControlChannel(int32_t aChannel,
-                                                         bool aHidden)
+AudioChannelServiceChild::SetDefaultVolumeControlChannel(
+  AudioChannelType aType, bool aHidden)
 {
   ContentChild *cc = ContentChild::GetSingleton();
   if (cc) {
-    cc->SendAudioChannelChangeDefVolChannel(aChannel, aHidden);
+    cc->SendAudioChannelChangeDefVolChannel(aType, aHidden);
   }
 }
--- a/dom/audiochannel/AudioChannelServiceChild.h
+++ b/dom/audiochannel/AudioChannelServiceChild.h
@@ -26,29 +26,28 @@ public:
    *
    * @return NS_OK on proper assignment, NS_ERROR_FAILURE otherwise.
    */
   static AudioChannelService* GetAudioChannelService();
 
   static void Shutdown();
 
   virtual void RegisterAudioChannelAgent(AudioChannelAgent* aAgent,
-                                         AudioChannel aChannel,
+                                         AudioChannelType aType,
                                          bool aWithVideo);
   virtual void UnregisterAudioChannelAgent(AudioChannelAgent* aAgent);
 
   /**
    * Return the state to indicate this agent should keep playing/
    * fading volume/muted.
    */
   virtual AudioChannelState GetState(AudioChannelAgent* aAgent,
                                      bool aElementHidden);
 
-  virtual void SetDefaultVolumeControlChannel(int32_t aChannel,
-                                              bool aHidden);
+  virtual void SetDefaultVolumeControlChannel(AudioChannelType aType, bool aHidden);
 
 protected:
   AudioChannelServiceChild();
   virtual ~AudioChannelServiceChild();
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/audiochannel/tests/TestAudioChannelService.cpp
+++ b/dom/audiochannel/tests/TestAudioChannelService.cpp
@@ -26,18 +26,18 @@
 using namespace mozilla::dom;
 
 class Agent : public nsIAudioChannelAgentCallback,
               public nsSupportsWeakReference
 {
 public:
   NS_DECL_ISUPPORTS
 
-  Agent(AudioChannel aChannel)
-  : mChannel(aChannel)
+  Agent(AudioChannelType aType)
+  : mType(aType)
   , mWaitCallback(false)
   , mRegistered(false)
   , mCanPlay(AUDIO_CHANNEL_STATE_MUTED)
   {
     mAgent = do_CreateInstance("@mozilla.org/audiochannelagent;1");
   }
 
   virtual ~Agent()
@@ -46,22 +46,20 @@ public:
       StopPlaying();
     }
   }
 
   nsresult Init(bool video=false)
   {
     nsresult rv = NS_OK;
     if (video) {
-      rv = mAgent->InitWithVideo(nullptr, static_cast<int32_t>(mChannel),
-                                 this, true);
+      rv = mAgent->InitWithVideo(nullptr, mType, this, true);
     }
     else {
-      rv = mAgent->InitWithWeakCallback(nullptr, static_cast<int32_t>(mChannel),
-                                        this);
+      rv = mAgent->InitWithWeakCallback(nullptr, mType, this);
     }
     NS_ENSURE_SUCCESS(rv, rv);
 
     return mAgent->SetVisibilityState(false);
   }
 
   nsresult StartPlaying(AudioChannelState *_ret)
   {
@@ -124,29 +122,29 @@ public:
         TEST_ENSURE_BASE(false, "GetCanPlay timeout");
       }
     }
     *_ret = mCanPlay;
     return NS_OK;
   }
 
   nsCOMPtr<nsIAudioChannelAgent> mAgent;
-  AudioChannel mChannel;
+  AudioChannelType mType;
   bool mWaitCallback;
   bool mRegistered;
   AudioChannelState mCanPlay;
 };
 
 NS_IMPL_ISUPPORTS2(Agent, nsIAudioChannelAgentCallback,
                    nsISupportsWeakReference)
 
 nsresult
 TestDoubleStartPlaying()
 {
-  nsRefPtr<Agent> agent = new Agent(AudioChannel::Normal);
+  nsRefPtr<Agent> agent = new Agent(AUDIO_CHANNEL_NORMAL);
 
   nsresult rv = agent->Init();
   NS_ENSURE_SUCCESS(rv, rv);
 
   AudioChannelState playable;
   rv = agent->mAgent->StartPlaying((int32_t *)&playable);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -155,17 +153,17 @@ TestDoubleStartPlaying()
     "Test0: StartPlaying calling twice must return error");
 
   return NS_OK;
 }
 
 nsresult
 TestOneNormalChannel()
 {
-  nsRefPtr<Agent> agent = new Agent(AudioChannel::Normal);
+  nsRefPtr<Agent> agent = new Agent(AUDIO_CHANNEL_NORMAL);
   nsresult rv = agent->Init();
   NS_ENSURE_SUCCESS(rv, rv);
 
   AudioChannelState playable;
   rv = agent->StartPlaying(&playable);
   NS_ENSURE_SUCCESS(rv, rv);
   TEST_ENSURE_BASE(playable == AUDIO_CHANNEL_STATE_MUTED,
     "Test1: A normal channel unvisible agent must be muted");
@@ -179,21 +177,21 @@ TestOneNormalChannel()
     "Test1: A normal channel visible agent must be playable");
 
   return rv;
 }
 
 nsresult
 TestTwoNormalChannels()
 {
-  nsRefPtr<Agent> agent1 = new Agent(AudioChannel::Normal);
+  nsRefPtr<Agent> agent1 = new Agent(AUDIO_CHANNEL_NORMAL);
   nsresult rv = agent1->Init();
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsRefPtr<Agent> agent2 = new Agent(AudioChannel::Normal);
+  nsRefPtr<Agent> agent2 = new Agent(AUDIO_CHANNEL_NORMAL);
   rv = agent2->Init();
   NS_ENSURE_SUCCESS(rv, rv);
 
   AudioChannelState playable;
   rv = agent1->StartPlaying(&playable);
   NS_ENSURE_SUCCESS(rv, rv);
   TEST_ENSURE_BASE(playable == AUDIO_CHANNEL_STATE_MUTED,
     "Test2: A normal channel unvisible agent1 must be muted");
@@ -220,21 +218,21 @@ TestTwoNormalChannels()
     "Test2: A normal channel visible agent2 must be playable");
 
   return rv;
 }
 
 nsresult
 TestContentChannels()
 {
-  nsRefPtr<Agent> agent1 = new Agent(AudioChannel::Content);
+  nsRefPtr<Agent> agent1 = new Agent(AUDIO_CHANNEL_CONTENT);
   nsresult rv = agent1->Init();
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsRefPtr<Agent> agent2 = new Agent(AudioChannel::Content);
+  nsRefPtr<Agent> agent2 = new Agent(AUDIO_CHANNEL_CONTENT);
   rv = agent2->Init();
   NS_ENSURE_SUCCESS(rv, rv);
 
   // All content channels in the foreground can be allowed to play
   rv = agent1->SetVisibilityState(true);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = agent2->SetVisibilityState(true);
@@ -305,25 +303,25 @@ TestContentChannels()
     "from background state");
 
   return rv;
 }
 
 nsresult
 TestFadedState()
 {
-  nsRefPtr<Agent> normalAgent = new Agent(AudioChannel::Normal);
+  nsRefPtr<Agent> normalAgent = new Agent(AUDIO_CHANNEL_NORMAL);
   nsresult rv = normalAgent->Init();
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsRefPtr<Agent> contentAgent = new Agent(AudioChannel::Content);
+  nsRefPtr<Agent> contentAgent = new Agent(AUDIO_CHANNEL_CONTENT);
   rv = contentAgent->Init();
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsRefPtr<Agent> notificationAgent = new Agent(AudioChannel::Notification);
+  nsRefPtr<Agent> notificationAgent = new Agent(AUDIO_CHANNEL_NOTIFICATION);
   rv = notificationAgent->Init();
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = normalAgent->SetVisibilityState(true);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = contentAgent->SetVisibilityState(true);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -384,42 +382,42 @@ TestFadedState()
   NS_ENSURE_SUCCESS(rv, rv);
 
   return rv;
 }
 
 nsresult
 TestPriorities()
 {
-  nsRefPtr<Agent> normalAgent = new Agent(AudioChannel::Normal);
+  nsRefPtr<Agent> normalAgent = new Agent(AUDIO_CHANNEL_NORMAL);
   nsresult rv = normalAgent->Init();
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsRefPtr<Agent> contentAgent = new Agent(AudioChannel::Content);
+  nsRefPtr<Agent> contentAgent = new Agent(AUDIO_CHANNEL_CONTENT);
   rv = contentAgent->Init();
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsRefPtr<Agent> notificationAgent = new Agent(AudioChannel::Notification);
+  nsRefPtr<Agent> notificationAgent = new Agent(AUDIO_CHANNEL_NOTIFICATION);
   rv = notificationAgent->Init();
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsRefPtr<Agent> alarmAgent = new Agent(AudioChannel::Alarm);
+  nsRefPtr<Agent> alarmAgent = new Agent(AUDIO_CHANNEL_ALARM);
   rv = alarmAgent->Init();
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsRefPtr<Agent> telephonyAgent = new Agent(AudioChannel::Telephony);
+  nsRefPtr<Agent> telephonyAgent = new Agent(AUDIO_CHANNEL_TELEPHONY);
   rv = telephonyAgent->Init();
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsRefPtr<Agent> ringerAgent = new Agent(AudioChannel::Ringer);
+  nsRefPtr<Agent> ringerAgent = new Agent(AUDIO_CHANNEL_RINGER);
   rv = ringerAgent->Init();
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsRefPtr<Agent> pNotificationAgent =
-    new Agent(AudioChannel::Publicnotification);
+    new Agent(AUDIO_CHANNEL_PUBLICNOTIFICATION);
   rv = pNotificationAgent->Init();
   NS_ENSURE_SUCCESS(rv, rv);
 
   AudioChannelState playable;
 
   rv = normalAgent->StartPlaying(&playable);
   NS_ENSURE_SUCCESS(rv, rv);
   TEST_ENSURE_BASE(playable == AUDIO_CHANNEL_STATE_MUTED,
@@ -541,21 +539,21 @@ TestPriorities()
     "Test5: A pNotification channel visible agent must be playable");
 
   return rv;
 }
 
 nsresult
 TestOneVideoNormalChannel()
 {
-  nsRefPtr<Agent> agent1 = new Agent(AudioChannel::Normal);
+  nsRefPtr<Agent> agent1 = new Agent(AUDIO_CHANNEL_NORMAL);
   nsresult rv = agent1->Init(true);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsRefPtr<Agent> agent2 = new Agent(AudioChannel::Content);
+  nsRefPtr<Agent> agent2 = new Agent(AUDIO_CHANNEL_CONTENT);
   rv = agent2->Init(false);
   NS_ENSURE_SUCCESS(rv, rv);
 
   AudioChannelState playable;
   rv = agent1->StartPlaying(&playable);
   NS_ENSURE_SUCCESS(rv, rv);
   TEST_ENSURE_BASE(playable == AUDIO_CHANNEL_STATE_MUTED,
     "Test6: A video normal channel invisible agent1 must be muted");
@@ -646,21 +644,21 @@ int main(int argc, char** argv)
   if (NS_FAILED(TestContentChannels())) {
     return 1;
   }
 
   if (NS_FAILED(TestFadedState())) {
     return 1;
   }
 
-  // Channel type with AudioChannel::Telephony cannot be unregistered until the
+  // Channel type with AUDIO_CHANNEL_TELEPHONY cannot be unregistered until the
   // main thread has chances to process 1500 millisecond timer. In order to
   // skip ambiguous return value of ChannelsActiveWithHigherPriorityThan(), new
   // test cases are added before any test case that registers the channel type
-  // with AudioChannel::Telephony channel.
+  // with AUDIO_CHANNEL_TELEPHONY channel.
   if (NS_FAILED(TestOneVideoNormalChannel())) {
     return 1;
   }
 
   if (NS_FAILED(TestPriorities())) {
     return 1;
   }
 
--- a/dom/audiochannel/tests/moz.build
+++ b/dom/audiochannel/tests/moz.build
@@ -3,13 +3,10 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 CPP_UNIT_TESTS += [
     'TestAudioChannelService.cpp',
 ]
 
-if CONFIG['OS_ARCH'] == 'WINNT':
-    DEFINES['NOMINMAX'] = True
-
 FAIL_ON_WARNINGS = True
 
--- a/dom/camera/DOMCameraControl.cpp
+++ b/dom/camera/DOMCameraControl.cpp
@@ -694,17 +694,17 @@ nsDOMCameraControl::StartRecording(const
 
   NotifyRecordingStatusChange(NS_LITERAL_STRING("starting"));
 
 #ifdef MOZ_B2G
   if (!mAudioChannelAgent) {
     mAudioChannelAgent = do_CreateInstance("@mozilla.org/audiochannelagent;1");
     if (mAudioChannelAgent) {
       // Camera app will stop recording when it falls to the background, so no callback is necessary.
-      mAudioChannelAgent->Init(mWindow, (int32_t)AudioChannel::Content, nullptr);
+      mAudioChannelAgent->Init(mWindow, AUDIO_CHANNEL_CONTENT, nullptr);
       // Video recording doesn't output any sound, so it's not necessary to check canPlay.
       int32_t canPlay;
       mAudioChannelAgent->StartPlaying(&canPlay);
     }
   }
 #endif
 
   nsCOMPtr<nsIDOMDOMRequest> request;
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -1894,75 +1894,75 @@ ContentParent::RecvFirstIdle()
     // which we use as a good time to prelaunch another process. If we
     // prelaunch any sooner than this, then we'll be competing with the
     // child process and slowing it down.
     PreallocatedProcessManager::AllocateAfterDelay();
     return true;
 }
 
 bool
-ContentParent::RecvAudioChannelGetState(const AudioChannel& aChannel,
+ContentParent::RecvAudioChannelGetState(const AudioChannelType& aType,
                                         const bool& aElementHidden,
                                         const bool& aElementWasHidden,
                                         AudioChannelState* aState)
 {
     nsRefPtr<AudioChannelService> service =
         AudioChannelService::GetAudioChannelService();
     *aState = AUDIO_CHANNEL_STATE_NORMAL;
     if (service) {
-        *aState = service->GetStateInternal(aChannel, mChildID,
+        *aState = service->GetStateInternal(aType, mChildID,
                                             aElementHidden, aElementWasHidden);
     }
     return true;
 }
 
 bool
-ContentParent::RecvAudioChannelRegisterType(const AudioChannel& aChannel,
+ContentParent::RecvAudioChannelRegisterType(const AudioChannelType& aType,
                                             const bool& aWithVideo)
 {
     nsRefPtr<AudioChannelService> service =
         AudioChannelService::GetAudioChannelService();
     if (service) {
-        service->RegisterType(aChannel, mChildID, aWithVideo);
+        service->RegisterType(aType, mChildID, aWithVideo);
     }
     return true;
 }
 
 bool
-ContentParent::RecvAudioChannelUnregisterType(const AudioChannel& aChannel,
+ContentParent::RecvAudioChannelUnregisterType(const AudioChannelType& aType,
                                               const bool& aElementHidden,
                                               const bool& aWithVideo)
 {
     nsRefPtr<AudioChannelService> service =
         AudioChannelService::GetAudioChannelService();
     if (service) {
-        service->UnregisterType(aChannel, aElementHidden, mChildID, aWithVideo);
+        service->UnregisterType(aType, aElementHidden, mChildID, aWithVideo);
     }
     return true;
 }
 
 bool
 ContentParent::RecvAudioChannelChangedNotification()
 {
     nsRefPtr<AudioChannelService> service =
         AudioChannelService::GetAudioChannelService();
     if (service) {
        service->SendAudioChannelChangedNotification(ChildID());
     }
     return true;
 }
 
 bool
-ContentParent::RecvAudioChannelChangeDefVolChannel(const int32_t& aChannel,
-                                                   const bool& aHidden)
+ContentParent::RecvAudioChannelChangeDefVolChannel(
+  const AudioChannelType& aType, const bool& aHidden)
 {
     nsRefPtr<AudioChannelService> service =
         AudioChannelService::GetAudioChannelService();
     if (service) {
-       service->SetDefaultVolumeControlChannelInternal(aChannel,
+       service->SetDefaultVolumeControlChannelInternal(aType,
                                                        aHidden, mChildID);
     }
     return true;
 }
 
 bool
 ContentParent::RecvBroadcastVolume(const nsString& aVolumeName)
 {
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -485,30 +485,30 @@ private:
                                  const uint32_t& aColNumber,
                                  const uint32_t& aFlags,
                                  const nsCString& aCategory) MOZ_OVERRIDE;
 
     virtual bool RecvPrivateDocShellsExist(const bool& aExist) MOZ_OVERRIDE;
 
     virtual bool RecvFirstIdle() MOZ_OVERRIDE;
 
-    virtual bool RecvAudioChannelGetState(const AudioChannel& aChannel,
+    virtual bool RecvAudioChannelGetState(const AudioChannelType& aType,
                                           const bool& aElementHidden,
                                           const bool& aElementWasHidden,
                                           AudioChannelState* aValue) MOZ_OVERRIDE;
 
-    virtual bool RecvAudioChannelRegisterType(const AudioChannel& aChannel,
+    virtual bool RecvAudioChannelRegisterType(const AudioChannelType& aType,
                                               const bool& aWithVideo) MOZ_OVERRIDE;
-    virtual bool RecvAudioChannelUnregisterType(const AudioChannel& aChannel,
+    virtual bool RecvAudioChannelUnregisterType(const AudioChannelType& aType,
                                                 const bool& aElementHidden,
                                                 const bool& aWithVideo) MOZ_OVERRIDE;
 
     virtual bool RecvAudioChannelChangedNotification() MOZ_OVERRIDE;
 
-    virtual bool RecvAudioChannelChangeDefVolChannel(const int32_t& aChannel,
+    virtual bool RecvAudioChannelChangeDefVolChannel(const AudioChannelType& aType,
                                                      const bool& aHidden) MOZ_OVERRIDE;
 
     virtual bool RecvBroadcastVolume(const nsString& aVolumeName) MOZ_OVERRIDE;
 
     virtual bool RecvSpeakerManagerGetSpeakerStatus(bool* aValue) MOZ_OVERRIDE;
 
     virtual bool RecvSpeakerManagerForceSpeaker(const bool& aEnable) MOZ_OVERRIDE;
 
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -41,17 +41,17 @@ using struct ResourceMapping from "mozil
 using struct OverrideMapping from "mozilla/chrome/RegistryMessageUtils.h";
 using base::ChildPrivileges from "base/process_util.h";
 using struct IPC::Permission from "mozilla/net/NeckoMessageUtils.h";
 using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h";
 using struct mozilla::null_t from "ipc/IPCMessageUtils.h";
 using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
 using mozilla::dom::asmjscache::OpenMode from "mozilla/dom/asmjscache/AsmJSCache.h";
 using mozilla::dom::asmjscache::WriteParams from "mozilla/dom/asmjscache/AsmJSCache.h";
-using mozilla::dom::AudioChannel from "mozilla/dom/AudioChannelBinding.h";
+using mozilla::dom::AudioChannelType from "AudioChannelCommon.h";
 using mozilla::dom::AudioChannelState from "AudioChannelCommon.h";
 using mozilla::dom::NativeThreadId from "mozilla/dom/TabMessageUtils.h";
 using mozilla::hal::ProcessPriority from "mozilla/HalTypes.h";
 using gfxIntSize from "nsSize.h";
 
 namespace mozilla {
 namespace dom {
 
@@ -510,27 +510,28 @@ parent:
 
     // Notify the parent of the presence or absence of private docshells
     PrivateDocShellsExist(bool aExist);
 
     // Tell the parent that the child has gone idle for the first time
     async FirstIdle();
 
     // Get Muted from the main AudioChannelService.
-    sync AudioChannelGetState(AudioChannel aChannel, bool aElementHidden,
+    sync AudioChannelGetState(AudioChannelType aType, bool aElementHidden,
                               bool aElementWasHidden)
         returns (AudioChannelState value);
 
-    sync AudioChannelRegisterType(AudioChannel aChannel, bool aWithVideo);
-    sync AudioChannelUnregisterType(AudioChannel aChannel,
+    sync AudioChannelRegisterType(AudioChannelType aType, bool aWithVideo);
+    sync AudioChannelUnregisterType(AudioChannelType aType,
                                     bool aElementHidden,
                                     bool aWithVideo);
 
     async AudioChannelChangedNotification();
-    async AudioChannelChangeDefVolChannel(int32_t aChannel, bool aHidden);
+    async AudioChannelChangeDefVolChannel(AudioChannelType aType,
+                                          bool aHidden);
 
     async FilePathUpdateNotify(nsString aType,
                                nsString aStorageName,
                                nsString aFilepath,
                                nsCString aReason);
     // get nsIVolumeService to broadcast volume information
     async BroadcastVolume(nsString volumeName);
 
--- a/dom/ipc/TabMessageUtils.h
+++ b/dom/ipc/TabMessageUtils.h
@@ -3,17 +3,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef TABMESSAGE_UTILS_H
 #define TABMESSAGE_UTILS_H
 
 #include "AudioChannelCommon.h"
 #include "ipc/IPCMessageUtils.h"
-#include "mozilla/dom/AudioChannelBinding.h"
 #include "nsIDOMEvent.h"
 #include "nsCOMPtr.h"
 
 #ifdef MOZ_CRASHREPORTER
 #include "nsExceptionHandler.h"
 #endif
 
 namespace mozilla {
@@ -54,48 +53,26 @@ struct ParamTraits<mozilla::dom::RemoteD
     return mozilla::dom::ReadRemoteEvent(aMsg, aIter, aResult);
   }
 
   static void Log(const paramType& aParam, std::wstring* aLog)
   {
   }
 };
 
-template<>
-struct ParamTraits<mozilla::dom::AudioChannel>
-{
-  typedef mozilla::dom::AudioChannel paramType;
-
-  static bool IsLegalValue(const paramType &aValue) {
-    return aValue <= mozilla::dom::AudioChannel::Publicnotification;
-  }
-
-  static void Write(Message* aMsg, const paramType& aValue) {
-    MOZ_ASSERT(IsLegalValue(aValue));
-    WriteParam(aMsg, (uint32_t)aValue);
-  }
-
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult) {
-    uint32_t value;
-    if(!ReadParam(aMsg, aIter, &value) ||
-       !IsLegalValue(paramType(value))) {
-      return false;
-    }
-    *aResult = paramType(value);
-    return true;
-  }
-
-  static void Log(const paramType& aParam, std::wstring* aLog)
-  {
-  }
-};
+template <>
+struct ParamTraits<mozilla::dom::AudioChannelType>
+  : public EnumSerializer<mozilla::dom::AudioChannelType,
+                          mozilla::dom::AUDIO_CHANNEL_DEFAULT,
+                          mozilla::dom::AUDIO_CHANNEL_LAST>
+{ };
 
 template <>
 struct ParamTraits<mozilla::dom::AudioChannelState>
   : public EnumSerializer<mozilla::dom::AudioChannelState,
-                          mozilla::dom::AUDIO_CHANNEL_STATE_NORMAL,
-                          mozilla::dom::AUDIO_CHANNEL_STATE_LAST>
+                           mozilla::dom::AUDIO_CHANNEL_STATE_NORMAL,
+                           mozilla::dom::AUDIO_CHANNEL_STATE_LAST>
 { };
 
 }
 
 
 #endif
--- a/dom/system/gonk/AudioChannelManager.cpp
+++ b/dom/system/gonk/AudioChannelManager.cpp
@@ -20,17 +20,17 @@ namespace system {
 
 NS_IMPL_QUERY_INTERFACE_INHERITED1(AudioChannelManager, DOMEventTargetHelper,
                                    nsIDOMEventListener)
 NS_IMPL_ADDREF_INHERITED(AudioChannelManager, DOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(AudioChannelManager, DOMEventTargetHelper)
 
 AudioChannelManager::AudioChannelManager()
   : mState(SWITCH_STATE_UNKNOWN)
-  , mVolumeChannel(-1)
+  , mVolumeChannel(AUDIO_CHANNEL_DEFAULT)
 {
   RegisterSwitchObserver(SWITCH_HEADPHONES, this);
   mState = GetCurrentSwitchState(SWITCH_HEADPHONES);
   SetIsDOMBinding();
 }
 
 AudioChannelManager::~AudioChannelManager()
 {
@@ -75,51 +75,69 @@ AudioChannelManager::Notify(const Switch
 
 bool
 AudioChannelManager::SetVolumeControlChannel(const nsAString& aChannel)
 {
   if (aChannel.EqualsASCII("publicnotification")) {
     return false;
   }
 
-  AudioChannel newChannel = AudioChannelService::GetAudioChannel(aChannel);
-
+  AudioChannelType oldVolumeChannel = mVolumeChannel;
   // Only normal channel doesn't need permission.
-  if (newChannel != AudioChannel::Normal) {
+  if (aChannel.EqualsASCII("normal")) {
+    mVolumeChannel = AUDIO_CHANNEL_NORMAL;
+  } else {
     nsCOMPtr<nsIPermissionManager> permissionManager =
       do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
     if (!permissionManager) {
       return false;
     }
     uint32_t perm = nsIPermissionManager::UNKNOWN_ACTION;
     permissionManager->TestPermissionFromWindow(GetOwner(),
       nsCString(NS_LITERAL_CSTRING("audio-channel-") +
       NS_ConvertUTF16toUTF8(aChannel)).get(), &perm);
     if (perm != nsIPermissionManager::ALLOW_ACTION) {
       return false;
     }
+
+    if (aChannel.EqualsASCII("content")) {
+      mVolumeChannel = AUDIO_CHANNEL_CONTENT;
+    } else if (aChannel.EqualsASCII("notification")) {
+      mVolumeChannel = AUDIO_CHANNEL_NOTIFICATION;
+    } else if (aChannel.EqualsASCII("alarm")) {
+      mVolumeChannel = AUDIO_CHANNEL_ALARM;
+    } else if (aChannel.EqualsASCII("telephony")) {
+      mVolumeChannel = AUDIO_CHANNEL_TELEPHONY;
+    } else if (aChannel.EqualsASCII("ringer")) {
+      mVolumeChannel = AUDIO_CHANNEL_RINGER;
+    }
   }
 
-  if (mVolumeChannel == (int32_t)newChannel) {
+  if (oldVolumeChannel == mVolumeChannel) {
     return true;
   }
-
-  mVolumeChannel = (int32_t)newChannel;
-
   NotifyVolumeControlChannelChanged();
   return true;
 }
 
 bool
 AudioChannelManager::GetVolumeControlChannel(nsAString & aChannel)
 {
-  if (mVolumeChannel >= 0) {
-    AudioChannelService::GetAudioChannelString(
-                                      static_cast<AudioChannel>(mVolumeChannel),
-                                      aChannel);
+  if (mVolumeChannel == AUDIO_CHANNEL_NORMAL) {
+    aChannel.AssignASCII("normal");
+  } else if (mVolumeChannel == AUDIO_CHANNEL_CONTENT) {
+    aChannel.AssignASCII("content");
+  } else if (mVolumeChannel == AUDIO_CHANNEL_NOTIFICATION) {
+    aChannel.AssignASCII("notification");
+  } else if (mVolumeChannel == AUDIO_CHANNEL_ALARM) {
+    aChannel.AssignASCII("alarm");
+  } else if (mVolumeChannel == AUDIO_CHANNEL_TELEPHONY) {
+    aChannel.AssignASCII("telephony");
+  } else if (mVolumeChannel == AUDIO_CHANNEL_RINGER) {
+    aChannel.AssignASCII("ringer");
   } else {
     aChannel.AssignASCII("");
   }
 
   return true;
 }
 
 void
@@ -130,17 +148,17 @@ AudioChannelManager::NotifyVolumeControl
 
   bool isActive = false;
   docshell->GetIsActive(&isActive);
 
   AudioChannelService* service = AudioChannelService::GetAudioChannelService();
   if (isActive) {
     service->SetDefaultVolumeControlChannel(mVolumeChannel, isActive);
   } else {
-    service->SetDefaultVolumeControlChannel(-1, isActive);
+    service->SetDefaultVolumeControlChannel(AUDIO_CHANNEL_DEFAULT, isActive);
   }
 }
 
 NS_IMETHODIMP
 AudioChannelManager::HandleEvent(nsIDOMEvent* aEvent)
 {
   nsAutoString type;
   aEvent->GetType(type);
--- a/dom/system/gonk/AudioChannelManager.h
+++ b/dom/system/gonk/AudioChannelManager.h
@@ -61,16 +61,16 @@ public:
   bool GetVolumeControlChannel(nsAString& aChannel);
 
   IMPL_EVENT_HANDLER(headphoneschange)
 
 private:
   void NotifyVolumeControlChannelChanged();
 
   hal::SwitchState mState;
-  int32_t mVolumeChannel;
+  AudioChannelType mVolumeChannel;
 };
 
 } // namespace system
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_system_AudioChannelManager_h
--- a/dom/system/gonk/AudioManager.cpp
+++ b/dom/system/gonk/AudioManager.cpp
@@ -124,27 +124,24 @@ public:
   NS_IMETHOD Handle(const nsAString& aName, JS::Handle<JS::Value> aResult)
   {
     nsCOMPtr<nsIAudioManager> audioManager =
       do_GetService(NS_AUDIOMANAGER_CONTRACTID);
     NS_ENSURE_TRUE(JSVAL_IS_INT(aResult), NS_OK);
 
     int32_t volIndex = JSVAL_TO_INT(aResult);
     if (aName.EqualsLiteral("audio.volume.content")) {
-      audioManager->SetAudioChannelVolume((int32_t)AudioChannel::Content,
-                                          volIndex);
+      audioManager->SetAudioChannelVolume(AUDIO_CHANNEL_CONTENT, volIndex);
     } else if (aName.EqualsLiteral("audio.volume.notification")) {
-      audioManager->SetAudioChannelVolume((int32_t)AudioChannel::Notification,
+      audioManager->SetAudioChannelVolume(AUDIO_CHANNEL_NOTIFICATION,
                                           volIndex);
     } else if (aName.EqualsLiteral("audio.volume.alarm")) {
-      audioManager->SetAudioChannelVolume((int32_t)AudioChannel::Alarm,
-                                          volIndex);
+      audioManager->SetAudioChannelVolume(AUDIO_CHANNEL_ALARM, volIndex);
     } else if (aName.EqualsLiteral("audio.volume.telephony")) {
-      audioManager->SetAudioChannelVolume((int32_t)AudioChannel::Telephony,
-                                          volIndex);
+      audioManager->SetAudioChannelVolume(AUDIO_CHANNEL_TELEPHONY, volIndex);
     } else if (aName.EqualsLiteral("audio.volume.bt_sco")) {
       static_cast<AudioManager *>(audioManager.get())->SetStreamVolumeIndex(
         AUDIO_STREAM_BLUETOOTH_SCO, volIndex);
     } else {
       MOZ_ASSUME_UNREACHABLE("unexpected audio channel for initializing "
                              "volume control");
     }
 
@@ -529,19 +526,19 @@ AudioManager::SetPhoneState(int32_t aSta
     mPhoneAudioAgent = nullptr;
   }
 
   if (aState == PHONE_STATE_IN_CALL || aState == PHONE_STATE_RINGTONE) {
     mPhoneAudioAgent = do_CreateInstance("@mozilla.org/audiochannelagent;1");
     MOZ_ASSERT(mPhoneAudioAgent);
     if (aState == PHONE_STATE_IN_CALL) {
       // Telephony doesn't be paused by any other channels.
-      mPhoneAudioAgent->Init(nullptr, (int32_t)AudioChannel::Telephony, nullptr);
+      mPhoneAudioAgent->Init(nullptr, AUDIO_CHANNEL_TELEPHONY, nullptr);
     } else {
-      mPhoneAudioAgent->Init(nullptr, (int32_t)AudioChannel::Ringer, nullptr);
+      mPhoneAudioAgent->Init(nullptr, AUDIO_CHANNEL_RINGER, nullptr);
     }
 
     // Telephony can always play.
     int32_t canPlay;
     mPhoneAudioAgent->StartPlaying(&canPlay);
   }
 
   return NS_OK;
@@ -606,97 +603,97 @@ AudioManager::SetFmRadioAudioEnabled(boo
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 }
 
 NS_IMETHODIMP
 AudioManager::SetAudioChannelVolume(int32_t aChannel, int32_t aIndex) {
   nsresult status;
 
-  switch (static_cast<AudioChannel>(aChannel)) {
-    case AudioChannel::Content:
+  switch (aChannel) {
+    case AUDIO_CHANNEL_CONTENT:
       // sync FMRadio's volume with content channel.
       if (IsDeviceOn(AUDIO_DEVICE_OUT_FM)) {
         status = SetStreamVolumeIndex(AUDIO_STREAM_FM, aIndex);
         NS_ENSURE_SUCCESS(status, status);
       }
       status = SetStreamVolumeIndex(AUDIO_STREAM_MUSIC, aIndex);
       NS_ENSURE_SUCCESS(status, status);
       status = SetStreamVolumeIndex(AUDIO_STREAM_SYSTEM, aIndex);
       break;
-    case AudioChannel::Notification:
+    case AUDIO_CHANNEL_NOTIFICATION:
       status = SetStreamVolumeIndex(AUDIO_STREAM_NOTIFICATION, aIndex);
       NS_ENSURE_SUCCESS(status, status);
       status = SetStreamVolumeIndex(AUDIO_STREAM_RING, aIndex);
       break;
-    case AudioChannel::Alarm:
+    case AUDIO_CHANNEL_ALARM:
       status = SetStreamVolumeIndex(AUDIO_STREAM_ALARM, aIndex);
       break;
-    case AudioChannel::Telephony:
+    case AUDIO_CHANNEL_TELEPHONY:
       status = SetStreamVolumeIndex(AUDIO_STREAM_VOICE_CALL, aIndex);
       break;
     default:
       return NS_ERROR_INVALID_ARG;
   }
 
   return status;
 }
 
 NS_IMETHODIMP
 AudioManager::GetAudioChannelVolume(int32_t aChannel, int32_t* aIndex) {
   if (!aIndex) {
     return NS_ERROR_NULL_POINTER;
   }
 
-  switch (static_cast<AudioChannel>(aChannel)) {
-    case AudioChannel::Content:
+  switch (aChannel) {
+    case AUDIO_CHANNEL_CONTENT:
       MOZ_ASSERT(mCurrentStreamVolumeTbl[AUDIO_STREAM_MUSIC] ==
                  mCurrentStreamVolumeTbl[AUDIO_STREAM_SYSTEM]);
       *aIndex = mCurrentStreamVolumeTbl[AUDIO_STREAM_MUSIC];
       break;
-    case AudioChannel::Notification:
+    case AUDIO_CHANNEL_NOTIFICATION:
       MOZ_ASSERT(mCurrentStreamVolumeTbl[AUDIO_STREAM_NOTIFICATION] ==
                  mCurrentStreamVolumeTbl[AUDIO_STREAM_RING]);
       *aIndex = mCurrentStreamVolumeTbl[AUDIO_STREAM_NOTIFICATION];
       break;
-    case AudioChannel::Alarm:
+    case AUDIO_CHANNEL_ALARM:
       *aIndex = mCurrentStreamVolumeTbl[AUDIO_STREAM_ALARM];
       break;
-    case AudioChannel::Telephony:
+    case AUDIO_CHANNEL_TELEPHONY:
       *aIndex = mCurrentStreamVolumeTbl[AUDIO_STREAM_VOICE_CALL];
       break;
     default:
       return NS_ERROR_INVALID_ARG;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 AudioManager::GetMaxAudioChannelVolume(int32_t aChannel, int32_t* aMaxIndex) {
   if (!aMaxIndex) {
     return NS_ERROR_NULL_POINTER;
   }
 
   int32_t stream;
-  switch (static_cast<AudioChannel>(aChannel)) {
-    case AudioChannel::Content:
+  switch (aChannel) {
+    case AUDIO_CHANNEL_CONTENT:
       MOZ_ASSERT(sMaxStreamVolumeTbl[AUDIO_STREAM_MUSIC] ==
                  sMaxStreamVolumeTbl[AUDIO_STREAM_SYSTEM]);
       stream = AUDIO_STREAM_MUSIC;
       break;
-    case AudioChannel::Notification:
+    case AUDIO_CHANNEL_NOTIFICATION:
       MOZ_ASSERT(sMaxStreamVolumeTbl[AUDIO_STREAM_NOTIFICATION] ==
                  sMaxStreamVolumeTbl[AUDIO_STREAM_RING]);
       stream = AUDIO_STREAM_NOTIFICATION;
       break;
-    case AudioChannel::Alarm:
+    case AUDIO_CHANNEL_ALARM:
       stream = AUDIO_STREAM_ALARM;
       break;
-    case AudioChannel::Telephony:
+    case AUDIO_CHANNEL_TELEPHONY:
       stream = AUDIO_STREAM_VOICE_CALL;
       break;
     default:
       return NS_ERROR_INVALID_ARG;
   }
 
   *aMaxIndex = sMaxStreamVolumeTbl[stream];
    return NS_OK;