Bug 830672 - audio-channel-changed is properly when an audio channel is visible. r=mchen, a=tef+
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 16 Jan 2013 14:38:51 +0100
changeset 118311 ca138e4376f1a764952d98970323fd01e4d0c8e9
parent 118310 5e5b35cd7f5d9d83ae9ec29e8b6428da4a9c3af8
child 118312 715e2e7ce60aa0429ba871fe08587097bdb45618
push id343
push userryanvm@gmail.com
push dateThu, 24 Jan 2013 18:55:32 +0000
reviewersmchen, tef
bugs830672
milestone18.0
Bug 830672 - audio-channel-changed is properly when an audio channel is visible. r=mchen, a=tef+
dom/audiochannel/AudioChannelService.cpp
dom/audiochannel/AudioChannelService.h
dom/audiochannel/tests/TestAudioChannelService.cpp
--- a/dom/audiochannel/AudioChannelService.cpp
+++ b/dom/audiochannel/AudioChannelService.cpp
@@ -223,17 +223,17 @@ AudioChannelService::SendAudioChannelCha
 {
   if (XRE_GetProcessType() != GeckoProcessType_Default) {
     return;
   }
 
   // Calculating the most important active channel.
   AudioChannelType higher = AUDIO_CHANNEL_LAST;
 
-  // Top-Down in the hierarchy.
+  // Top-Down in the hierarchy for visible elements
   if (!mChannelCounters[AUDIO_CHANNEL_INT_PUBLICNOTIFICATION].IsEmpty()) {
     higher = AUDIO_CHANNEL_PUBLICNOTIFICATION;
   }
 
   else if (!mChannelCounters[AUDIO_CHANNEL_INT_RINGER].IsEmpty()) {
     higher = AUDIO_CHANNEL_RINGER;
   }
 
@@ -244,28 +244,51 @@ AudioChannelService::SendAudioChannelCha
   else if (!mChannelCounters[AUDIO_CHANNEL_INT_ALARM].IsEmpty()) {
     higher = AUDIO_CHANNEL_ALARM;
   }
 
   else if (!mChannelCounters[AUDIO_CHANNEL_INT_NOTIFICATION].IsEmpty()) {
     higher = AUDIO_CHANNEL_NOTIFICATION;
   }
 
-  // Only 1 content channel hidden or a visible one.
-  else if ((!mChannelCounters[AUDIO_CHANNEL_INT_CONTENT_HIDDEN].IsEmpty() &&
-            !HasMoreThanOneContentChannelHidden()) ||
-           !mChannelCounters[AUDIO_CHANNEL_INT_CONTENT].IsEmpty()) {
+  else if (!mChannelCounters[AUDIO_CHANNEL_INT_CONTENT].IsEmpty()) {
     higher = AUDIO_CHANNEL_CONTENT;
   }
 
-  // At least 1 visible normal channel.
   else if (!mChannelCounters[AUDIO_CHANNEL_INT_NORMAL].IsEmpty()) {
     higher = AUDIO_CHANNEL_NORMAL;
   }
 
+  // Top-Down in the hierarchy for non-visible elements
+  else if (!mChannelCounters[AUDIO_CHANNEL_INT_PUBLICNOTIFICATION_HIDDEN].IsEmpty()) {
+    higher = AUDIO_CHANNEL_PUBLICNOTIFICATION;
+  }
+
+  else if (!mChannelCounters[AUDIO_CHANNEL_INT_RINGER_HIDDEN].IsEmpty()) {
+    higher = AUDIO_CHANNEL_RINGER;
+  }
+
+  else if (!mChannelCounters[AUDIO_CHANNEL_INT_TELEPHONY_HIDDEN].IsEmpty()) {
+    higher = AUDIO_CHANNEL_TELEPHONY;
+  }
+
+  else if (!mChannelCounters[AUDIO_CHANNEL_INT_ALARM_HIDDEN].IsEmpty()) {
+    higher = AUDIO_CHANNEL_ALARM;
+  }
+
+  else if (!mChannelCounters[AUDIO_CHANNEL_INT_NOTIFICATION_HIDDEN].IsEmpty()) {
+    higher = AUDIO_CHANNEL_NOTIFICATION;
+  }
+
+  // Content channels play in background if just one is active.
+  else if ((!mChannelCounters[AUDIO_CHANNEL_INT_CONTENT_HIDDEN].IsEmpty() &&
+            !HasMoreThanOneContentChannelHidden())) {
+    higher = AUDIO_CHANNEL_CONTENT;
+  }
+
   if (higher != mCurrentHigherChannel) {
     mCurrentHigherChannel = higher;
 
     nsString channelName;
     if (mCurrentHigherChannel != AUDIO_CHANNEL_LAST) {
       channelName.AssignASCII(ChannelName(mCurrentHigherChannel));
     } else {
       channelName.AssignLiteral("none");
@@ -299,17 +322,17 @@ AudioChannelService::Notify()
   for (uint32_t i = 0; i < children.Length(); i++) {
     unused << children[i]->SendAudioChannelNotify();
   }
 }
 
 bool
 AudioChannelService::ChannelsActiveWithHigherPriorityThan(AudioChannelInternalType aType)
 {
-  for (int i = AUDIO_CHANNEL_INT_PUBLICNOTIFICATION;
+  for (int i = AUDIO_CHANNEL_INT_LAST - 1;
        i != AUDIO_CHANNEL_INT_CONTENT_HIDDEN; --i) {
     if (i == aType) {
       return false;
     }
 
     if (!mChannelCounters[i].IsEmpty()) {
       return true;
     }
@@ -384,36 +407,48 @@ AudioChannelService::Observe(nsISupports
 
 AudioChannelService::AudioChannelInternalType
 AudioChannelService::GetInternalType(AudioChannelType aType,
                                      bool aElementHidden)
 {
   switch (aType) {
     case AUDIO_CHANNEL_NORMAL:
       return aElementHidden
-               ? AUDIO_CHANNEL_INT_NORMAL_HIDDEN : AUDIO_CHANNEL_INT_NORMAL;
+               ? AUDIO_CHANNEL_INT_NORMAL_HIDDEN
+               : AUDIO_CHANNEL_INT_NORMAL;
 
     case AUDIO_CHANNEL_CONTENT:
       return aElementHidden
-               ? AUDIO_CHANNEL_INT_CONTENT_HIDDEN : AUDIO_CHANNEL_INT_CONTENT;
+               ? AUDIO_CHANNEL_INT_CONTENT_HIDDEN
+               : AUDIO_CHANNEL_INT_CONTENT;
 
     case AUDIO_CHANNEL_NOTIFICATION:
-      return AUDIO_CHANNEL_INT_NOTIFICATION;
+      return aElementHidden
+               ? AUDIO_CHANNEL_INT_NOTIFICATION_HIDDEN
+               : AUDIO_CHANNEL_INT_NOTIFICATION;
 
     case AUDIO_CHANNEL_ALARM:
-      return AUDIO_CHANNEL_INT_ALARM;
+      return aElementHidden
+               ? AUDIO_CHANNEL_INT_ALARM_HIDDEN
+               : AUDIO_CHANNEL_INT_ALARM;
 
     case AUDIO_CHANNEL_TELEPHONY:
-      return AUDIO_CHANNEL_INT_TELEPHONY;
+      return aElementHidden
+               ? AUDIO_CHANNEL_INT_TELEPHONY_HIDDEN
+               : AUDIO_CHANNEL_INT_TELEPHONY;
 
     case AUDIO_CHANNEL_RINGER:
-      return AUDIO_CHANNEL_INT_RINGER;
+      return aElementHidden
+               ? AUDIO_CHANNEL_INT_RINGER_HIDDEN
+               : AUDIO_CHANNEL_INT_RINGER;
 
     case AUDIO_CHANNEL_PUBLICNOTIFICATION:
-      return AUDIO_CHANNEL_INT_PUBLICNOTIFICATION;
+      return aElementHidden
+               ? AUDIO_CHANNEL_INT_PUBLICNOTIFICATION_HIDDEN
+               : AUDIO_CHANNEL_INT_PUBLICNOTIFICATION;
 
     case AUDIO_CHANNEL_LAST:
     default:
       break;
   }
 
   MOZ_NOT_REACHED();
   return AUDIO_CHANNEL_INT_LAST;
--- a/dom/audiochannel/AudioChannelService.h
+++ b/dom/audiochannel/AudioChannelService.h
@@ -79,20 +79,25 @@ protected:
   virtual ~AudioChannelService();
 
   enum AudioChannelInternalType {
     AUDIO_CHANNEL_INT_NORMAL = 0,
     AUDIO_CHANNEL_INT_NORMAL_HIDDEN,
     AUDIO_CHANNEL_INT_CONTENT,
     AUDIO_CHANNEL_INT_CONTENT_HIDDEN,
     AUDIO_CHANNEL_INT_NOTIFICATION,
+    AUDIO_CHANNEL_INT_NOTIFICATION_HIDDEN,
     AUDIO_CHANNEL_INT_ALARM,
+    AUDIO_CHANNEL_INT_ALARM_HIDDEN,
     AUDIO_CHANNEL_INT_TELEPHONY,
+    AUDIO_CHANNEL_INT_TELEPHONY_HIDDEN,
     AUDIO_CHANNEL_INT_RINGER,
+    AUDIO_CHANNEL_INT_RINGER_HIDDEN,
     AUDIO_CHANNEL_INT_PUBLICNOTIFICATION,
+    AUDIO_CHANNEL_INT_PUBLICNOTIFICATION_HIDDEN,
     AUDIO_CHANNEL_INT_LAST
   };
 
   bool ChannelsActiveWithHigherPriorityThan(AudioChannelInternalType aType);
 
   bool HasMoreThanOneContentChannelHidden();
 
   const char* ChannelName(AudioChannelType aType);
--- a/dom/audiochannel/tests/TestAudioChannelService.cpp
+++ b/dom/audiochannel/tests/TestAudioChannelService.cpp
@@ -273,16 +273,79 @@ TestPriorities()
   NS_ENSURE_SUCCESS(rv, rv);
   TEST_ENSURE_BASE(playing, "Test4: An pNotification channel unvisible agent should be playing");
 
   // Now ringer should be not playing because of the public notification playing.
   rv = ringerAgent.StartPlaying(&playing);
   NS_ENSURE_SUCCESS(rv, rv);
   TEST_ENSURE_BASE(!playing, "Test4: A ringer channel unvisible agent should not be playing when a public notification is playing");
 
+  // Settings visible the normal channel.
+  rv = normalAgent.mAgent->SetVisibilityState(true);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // Normal should be playing because visible.
+  rv = normalAgent.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(playing, "Test4: A normal channel visible agent should be playing");
+
+  // Settings visible the content channel.
+  rv = contentAgent.mAgent->SetVisibilityState(true);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // Content should be playing because visible.
+  rv = contentAgent.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(playing, "Test4: A content channel visible agent should be playing");
+
+  // Settings visible the notification channel.
+  rv = notificationAgent.mAgent->SetVisibilityState(true);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // Notification should be playing because visible.
+  rv = notificationAgent.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(playing, "Test4: A notification channel visible agent should be playing");
+
+  // Settings visible the alarm channel.
+  rv = alarmAgent.mAgent->SetVisibilityState(true);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // Alarm should be playing because visible.
+  rv = alarmAgent.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(playing, "Test4: A alarm channel visible agent should be playing");
+
+  // Settings visible the telephony channel.
+  rv = telephonyAgent.mAgent->SetVisibilityState(true);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // Telephony should be playing because visible.
+  rv = telephonyAgent.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(playing, "Test4: A telephony channel visible agent should be playing");
+
+  // Settings visible the ringer channel.
+  rv = ringerAgent.mAgent->SetVisibilityState(true);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // Ringer should be playing because visible.
+  rv = ringerAgent.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(playing, "Test4: A ringer channel visible agent should be playing");
+
+  // Settings visible the pNotification channel.
+  rv = pNotificationAgent.mAgent->SetVisibilityState(true);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // pNotification should be playing because visible.
+  rv = pNotificationAgent.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(playing, "Test4: A pNotification channel visible agent should be playing");
+
   return rv;
 }
 
 int main(int argc, char** argv)
 {
   ScopedXPCOM xpcom("AudioChannelService");
   if (xpcom.failed())
     return 1;