Bug 829561 - AudioChannelService needs some unit test, r=mchen, a=blocking-b2g
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 16 Jan 2013 14:34:07 +0100
changeset 118340 0a2501533cfdf3573e9f0ee0488c282893fdf382
parent 118339 694c52fd8d8e9dc17e141b8b85b47551a959126a
child 118341 c99fb2843bdc6385543e54c7e89b42196b961d01
push id363
push useramarchesini@mozilla.com
push dateFri, 25 Jan 2013 15:48:07 +0000
reviewersmchen, blocking-b2g
bugs829561
milestone18.0
Bug 829561 - AudioChannelService needs some unit test, r=mchen, a=blocking-b2g
dom/audiochannel/AudioChannelService.cpp
dom/audiochannel/Makefile.in
dom/audiochannel/tests/Makefile.in
dom/audiochannel/tests/TestAudioChannelService.cpp
dom/ipc/ContentParent.h
--- a/dom/audiochannel/AudioChannelService.cpp
+++ b/dom/audiochannel/AudioChannelService.cpp
@@ -86,17 +86,17 @@ AudioChannelService::~AudioChannelServic
 void
 AudioChannelService::RegisterAudioChannelAgent(AudioChannelAgent* aAgent,
                                                AudioChannelType aType)
 {
   AudioChannelAgentData* data = new AudioChannelAgentData(aType,
                                                           true /* mElementHidden */,
                                                           true /* mMuted */);
   mAgents.Put(aAgent, data);
-  RegisterType(aType, CONTENT_PARENT_UNKNOWN_CHILD_ID);
+  RegisterType(aType, CONTENT_PARENT_NO_CHILD_ID);
 }
 
 void
 AudioChannelService::RegisterType(AudioChannelType aType, uint64_t aChildID)
 {
   AudioChannelInternalType type = GetInternalType(aType, true);
   mChannelCounters[type].AppendElement(aChildID);
 
@@ -110,17 +110,17 @@ AudioChannelService::RegisterType(AudioC
 
 void
 AudioChannelService::UnregisterAudioChannelAgent(AudioChannelAgent* aAgent)
 {
   nsAutoPtr<AudioChannelAgentData> data;
   mAgents.RemoveAndForget(aAgent, data);
 
   if (data) {
-    UnregisterType(data->mType, data->mElementHidden, CONTENT_PARENT_UNKNOWN_CHILD_ID);
+    UnregisterType(data->mType, data->mElementHidden, CONTENT_PARENT_NO_CHILD_ID);
   }
 }
 
 void
 AudioChannelService::UnregisterType(AudioChannelType aType,
                                     bool aElementHidden,
                                     uint64_t aChildID)
 {
@@ -140,17 +140,17 @@ AudioChannelService::UnregisterType(Audi
 bool
 AudioChannelService::GetMuted(AudioChannelAgent* aAgent, bool aElementHidden)
 {
   AudioChannelAgentData* data;
   if (!mAgents.Get(aAgent, &data)) {
     return true;
   }
 
-  bool muted = GetMutedInternal(data->mType, CONTENT_PARENT_UNKNOWN_CHILD_ID,
+  bool muted = GetMutedInternal(data->mType, CONTENT_PARENT_NO_CHILD_ID,
                                 aElementHidden, data->mElementHidden);
 
   // Update visibility.
   data->mElementHidden = aElementHidden;
   data->mMuted = muted;
 
   SendAudioChannelChangedNotification();
   return muted;
--- a/dom/audiochannel/Makefile.in
+++ b/dom/audiochannel/Makefile.in
@@ -41,12 +41,17 @@ CPPSRCS += \
   AudioChannelServiceChild.cpp \
   AudioChannelAgent.cpp \
   $(NULL)
 
 XPIDLSRCS = \
   nsIAudioChannelAgent.idl \
   $(NULL)
 
+
+ifdef ENABLE_TESTS
+TOOL_DIRS += tests
+endif
+
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
 
new file mode 100644
--- /dev/null
+++ b/dom/audiochannel/tests/Makefile.in
@@ -0,0 +1,22 @@
+# 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/.
+
+DEPTH		= @DEPTH@
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+relativesrcdir = @relativesrcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE           = dom
+FAIL_ON_WARNINGS = 1
+
+CPP_UNIT_TESTS = \
+		TestAudioChannelService.cpp \
+		$(NULL)
+
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/config/rules.mk
+
new file mode 100644
--- /dev/null
+++ b/dom/audiochannel/tests/TestAudioChannelService.cpp
@@ -0,0 +1,307 @@
+/* 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/. */
+
+#include "TestHarness.h"
+
+#include "AudioChannelService.h"
+#include "AudioChannelAgent.h"
+
+#define TEST_ENSURE_BASE(_test, _msg)       \
+  PR_BEGIN_MACRO                            \
+    if (!_test) {                           \
+      fail(_msg);                           \
+      return NS_ERROR_FAILURE;              \
+    } else {                                \
+      passed(_msg);                         \
+    }                                       \
+  PR_END_MACRO
+
+using namespace mozilla::dom;
+
+class Agent
+{
+public:
+  Agent(AudioChannelType aType)
+  : mType(aType)
+  , mRegistered(false)
+  {
+    mAgent = do_CreateInstance("@mozilla.org/audiochannelagent;1");
+  }
+
+  nsresult Init()
+  {
+    nsresult rv = mAgent->Init(mType, nullptr);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    return mAgent->SetVisibilityState(false);
+  }
+
+  nsresult StartPlaying(bool *_ret)
+  {
+    if (mRegistered)
+      StopPlaying();
+
+    nsresult rv = mAgent->StartPlaying(_ret);
+    mRegistered = true;
+    return rv;
+  }
+
+  nsresult StopPlaying()
+  {
+    mRegistered = false;
+    return mAgent->StopPlaying();
+  }
+
+  nsCOMPtr<AudioChannelAgent> mAgent;
+  AudioChannelType mType;
+  bool mRegistered;
+};
+
+nsresult
+TestDoubleStartPlaying()
+{
+  Agent agent(AUDIO_CHANNEL_NORMAL);
+  nsresult rv = agent.Init();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  bool playing;
+  rv = agent.mAgent->StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = agent.mAgent->StartPlaying(&playing);
+  TEST_ENSURE_BASE(NS_FAILED(rv), "Test0: StartPlaying calling twice should return error");
+
+  return NS_OK;
+}
+
+nsresult
+TestOneNormalChannel()
+{
+  Agent agent(AUDIO_CHANNEL_NORMAL);
+  nsresult rv = agent.Init();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  bool playing;
+  rv = agent.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(!playing, "Test1: A normal channel unvisible agent must not be playing");
+
+  rv = agent.mAgent->SetVisibilityState(true);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = agent.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(playing, "Test1: A normal channel visible agent should be playing");
+
+  return rv;
+}
+
+nsresult
+TestTwoNormalChannels()
+{
+  Agent agent1(AUDIO_CHANNEL_NORMAL);
+  nsresult rv = agent1.Init();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  Agent agent2(AUDIO_CHANNEL_NORMAL);
+  rv = agent2.Init();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  bool playing;
+  rv = agent1.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(!playing, "Test2: A normal channel unvisible agent1 must not be playing");
+
+  rv = agent2.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(!playing, "Test2: A normal channel unvisible agent2 must not be playing");
+
+  rv = agent1.mAgent->SetVisibilityState(true);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = agent2.mAgent->SetVisibilityState(true);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = agent1.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(playing, "Test2: A normal channel visible agent1 should be playing");
+
+  rv = agent2.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(playing, "Test2: A normal channel visible agent2 should be playing");
+
+  return rv;
+}
+
+nsresult
+TestContentChannels()
+{
+  Agent agent1(AUDIO_CHANNEL_CONTENT);
+  nsresult rv = agent1.Init();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  Agent agent2(AUDIO_CHANNEL_CONTENT);
+  rv = agent2.Init();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  bool playing;
+  rv = agent1.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(playing, "Test3: A content channel unvisible agent1 should be playing");
+
+  rv = agent2.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(playing, "Test3: A content channel unvisible agent2 should be playing");
+
+  rv = agent1.mAgent->SetVisibilityState(true);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = agent2.mAgent->SetVisibilityState(false);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = agent1.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(playing, "Test3: A content channel visible agent1 should be playing");
+
+  rv = agent2.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(!playing, "Test3: A content channel unvisible agent2 should not be playing");
+
+  rv = agent1.mAgent->SetVisibilityState(true);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = agent2.mAgent->SetVisibilityState(true);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = agent1.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(playing, "Test3: A content channel visible agent1 should be playing");
+
+  rv = agent2.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(playing, "Test3: A content channel visible agent2 should be playing");
+
+  return rv;
+}
+
+nsresult
+TestPriorities()
+{
+  Agent normalAgent(AUDIO_CHANNEL_NORMAL);
+  nsresult rv = normalAgent.Init();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  Agent contentAgent(AUDIO_CHANNEL_CONTENT);
+  rv = contentAgent.Init();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  Agent notificationAgent(AUDIO_CHANNEL_NOTIFICATION);
+  rv = notificationAgent.Init();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  Agent alarmAgent(AUDIO_CHANNEL_ALARM);
+  rv = alarmAgent.Init();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  Agent telephonyAgent(AUDIO_CHANNEL_TELEPHONY);
+  rv = telephonyAgent.Init();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  Agent ringerAgent(AUDIO_CHANNEL_RINGER);
+  rv = ringerAgent.Init();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  Agent pNotificationAgent(AUDIO_CHANNEL_PUBLICNOTIFICATION);
+  rv = pNotificationAgent.Init();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  bool playing;
+
+  // Normal should not be playing because not visible.
+  rv = normalAgent.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(!playing, "Test4: A normal channel unvisible agent should not be playing");
+
+  // Content should be playing.
+  rv = contentAgent.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(playing, "Test4: A content channel unvisible agent should be playing");
+
+  // Notification should be playing.
+  rv = notificationAgent.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(playing, "Test4: An notification channel unvisible agent should be playing");
+
+  // Now content should be not playing because of the notification playing.
+  rv = contentAgent.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(!playing, "Test4: A content channel unvisible agent should not be playing when notification channel is playing");
+
+  // Adding an alarm.
+  rv = alarmAgent.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(playing, "Test4: An alarm channel unvisible agent should be playing");
+
+  // Now notification should be not playing because of the alarm playing.
+  rv = notificationAgent.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(!playing, "Test4: A notification channel unvisible agent should not be playing when an alarm is playing");
+
+  // Adding an telephony.
+  rv = telephonyAgent.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(playing, "Test4: An telephony channel unvisible agent should be playing");
+
+  // Now alarm should be not playing because of the telephony playing.
+  rv = alarmAgent.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(!playing, "Test4: A alarm channel unvisible agent should not be playing when a telephony is playing");
+
+  // Adding an ringer.
+  rv = ringerAgent.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(playing, "Test4: An ringer channel unvisible agent should be playing");
+
+  // Now telephony should be not playing because of the ringer playing.
+  rv = telephonyAgent.StartPlaying(&playing);
+  NS_ENSURE_SUCCESS(rv, rv);
+  TEST_ENSURE_BASE(!playing, "Test4: A telephony channel unvisible agent should not be playing when a riger is playing");
+
+  // Adding an pNotification.
+  rv = pNotificationAgent.StartPlaying(&playing);
+  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");
+
+  return rv;
+}
+
+int main(int argc, char** argv)
+{
+  ScopedXPCOM xpcom("AudioChannelService");
+  if (xpcom.failed())
+    return 1;
+
+  if (NS_FAILED(TestDoubleStartPlaying()))
+    return 1;
+
+  if (NS_FAILED(TestOneNormalChannel()))
+    return 1;
+
+  if (NS_FAILED(TestTwoNormalChannels()))
+    return 1;
+
+  if (NS_FAILED(TestContentChannels()))
+    return 1;
+
+  if (NS_FAILED(TestPriorities()))
+    return 1;
+
+  return 0;
+}
+
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -25,16 +25,17 @@
 #include "nsIMemoryReporter.h"
 #include "nsCOMArray.h"
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 #include "PermissionMessageUtils.h"
 
 #define CHILD_PROCESS_SHUTDOWN_MESSAGE NS_LITERAL_STRING("child-process-shutdown")
 
+#define CONTENT_PARENT_NO_CHILD_ID 0
 #define CONTENT_PARENT_UNKNOWN_CHILD_ID -1
 
 class mozIApplication;
 class nsConsoleService;
 class nsIDOMBlob;
 class nsDOMFileBase;
 
 namespace mozilla {