SyncSlides: Only support one live presentation at a time.

Presenting multiple decks at the same time is not a use-case
that we need to support.

Starting a new presentation will stop the previous
presentation, if any.

Change-Id: I27b58f8ba91abd11510a5a3554c2a493561e42d8
diff --git a/dart/lib/stores/state.dart b/dart/lib/stores/state.dart
index 34599c5..8261dfb 100644
--- a/dart/lib/stores/state.dart
+++ b/dart/lib/stores/state.dart
@@ -17,9 +17,8 @@
   // List of decks.
   UnmodifiableMapView<String, DeckState> get decks;
 
-  // List of presentations advertised by this instance of the app.
-  UnmodifiableListView<
-      model.PresentationAdvertisement> get advertisedPresentations;
+  // The presentation advertised by this instance of the app.
+  model.PresentationAdvertisement get advertisedPresentation;
 
   // List of presentations advertised by others.
   UnmodifiableMapView<String,
diff --git a/dart/lib/stores/syncbase/actions.dart b/dart/lib/stores/syncbase/actions.dart
index 040700f..7feda01 100644
--- a/dart/lib/stores/syncbase/actions.dart
+++ b/dart/lib/stores/syncbase/actions.dart
@@ -73,17 +73,15 @@
 
   Future<model.PresentationAdvertisement> startPresentation(
       String deckId) async {
-    var alreadyAdvertised = _state._advertisedPresentations
-        .any((model.PresentationAdvertisement p) => p.deck.key == deckId);
-    if (alreadyAdvertised) {
-      throw new ArgumentError.value(deckId,
-          'Cannot simultaneously present the same deck. Presentation already in progress.');
-    }
-
     if (!_state._decks.containsKey(deckId)) {
       throw new ArgumentError.value(deckId, 'Deck no longer exists.');
     }
 
+    // Stop the existing presentation, if any.
+    if (_state._advertisedPresentation != null) {
+      await stopPresentation(_state._advertisedPresentation.key);
+    }
+
     model.Deck deck = _state._getOrCreateDeckState(deckId)._deck;
     String presentationId = uuidutil.createUuid();
     String syncgroupName = _getSyncgroupName(_state.settings, presentationId);
@@ -110,7 +108,7 @@
     ]);
 
     await discovery.advertise(presentation);
-    _state._advertisedPresentations.add(presentation);
+    _state._advertisedPresentation = presentation;
 
     // Set the presentation state for the deck.
     _DeckState deckState = _state._getOrCreateDeckState(deckId);
@@ -155,7 +153,7 @@
     // Wait until at least the current slide number, driver and the slide for current slide number is synced.
     join() async {
       bool isMyOwnPresentation =
-          _state._advertisedPresentations.any((p) => p.key == presentation.key);
+          _state._advertisedPresentation.key == presentation.key;
       if (!isMyOwnPresentation) {
         await sb.joinSyncgroup(presentation.syncgroupName);
       }
@@ -189,7 +187,7 @@
 
   Future stopPresentation(String presentationId) async {
     await discovery.stopAdvertising(presentationId);
-    _state._advertisedPresentations.removeWhere((p) => p.key == presentationId);
+    _state._advertisedPresentation = null;
     _state._decks.values.forEach((_DeckState deck) {
       if (deck.presentation != null &&
           deck.presentation.key == presentationId) {
diff --git a/dart/lib/stores/syncbase/state.dart b/dart/lib/stores/syncbase/state.dart
index 484a014..b943899 100644
--- a/dart/lib/stores/syncbase/state.dart
+++ b/dart/lib/stores/syncbase/state.dart
@@ -8,7 +8,8 @@
   model.User get user => _user;
   model.Settings get settings => _settings;
   UnmodifiableMapView<String, DeckState> decks;
-  UnmodifiableListView<model.PresentationAdvertisement> advertisedPresentations;
+  model.PresentationAdvertisement get advertisedPresentation =>
+      _advertisedPresentation;
   UnmodifiableMapView<String,
       model.PresentationAdvertisement> presentationAdvertisements;
 
@@ -16,8 +17,6 @@
     _user = null;
     _settings = null;
     decks = new UnmodifiableMapView(_decks);
-    advertisedPresentations =
-        new UnmodifiableListView(_advertisedPresentations);
     presentationAdvertisements =
         new UnmodifiableMapView(_presentationsAdvertisements);
   }
@@ -25,7 +24,7 @@
   model.User _user;
   model.Settings _settings;
   Map<String, _DeckState> _decks = new Map();
-  List<model.PresentationAdvertisement> _advertisedPresentations = new List();
+  model.PresentationAdvertisement _advertisedPresentation;
   Map<String, model.PresentationAdvertisement> _presentationsAdvertisements =
       new Map();