Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8054)

Unified Diff: chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js

Issue 1805813002: [Media Router] Wiring for searching route providers for new sinks. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Clarifying pseudo sink comments Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js
diff --git a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js
index 5cdbb30e01befe872da983eea59d5ae454176c99..70f696cb33e3aabc7d93bba190b6aa55ae3af830 100644
--- a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js
+++ b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js
@@ -215,6 +215,25 @@ Polymer({
},
/**
+ * Pseudo sinks from MRPs that represent their ability to accept sink search
+ * requests.
+ * @private {!Array<!media_router.Sink>}
+ */
+ pseudoSinks_: {
+ type: Array,
+ value: [],
+ },
+
+ /**
+ * Helps manage the state of creating a sink and a route from a pseudo sink.
+ * @private {PseudoSinkSearchState}
+ */
+ pseudoSinkSearchState_: {
+ type: Object,
+ value: null,
+ },
+
+ /**
* Whether the next character input should cause a filter action metric to
* be sent.
* @type {boolean}
@@ -244,6 +263,15 @@ Polymer({
value: {},
},
+ /*
+ * Helps manage the state of creating a sink and a route from a pseudo sink.
+ * @private {PseudoSinkSearchStateMachine}
+ */
+ searchInProgress_: {
+ type: Object,
+ value: null,
+ },
+
/**
* Search text entered by the user into the sink search input.
* @private {string}
@@ -665,6 +693,7 @@ Polymer({
*/
computeIssueBannerShown_: function(view, issue) {
return !!issue && (view == media_router.MediaRouterView.SINK_LIST ||
+ view == media_router.MediaRouterView.FILTER ||
view == media_router.MediaRouterView.ISSUE);
},
@@ -997,6 +1026,31 @@ Polymer({
substrings: matchSubstrings});
}
searchResultsToShow.sort(this.compareSearchMatches_);
+
+ var pendingPseudoSink = (this.pseudoSinkSearchState_) ?
+ this.pseudoSinkSearchState_.getPseudoSink() :
+ null;
+ // We may need to add pseudo sinks to the filter results. A pseudo sink will
+ // be shown if there is no real sink with the same icon and name exactly
+ // matching the filter text. The map() call transforms any pseudo sink
+ // objects that will be shown to the search result format, where we know
+ // that the entire sink name will be a match.
+ //
+ // The exception to this is when there is a pending pseudo sink search. Then
+ // the pseudo sink for the search will be treated like a real sink because
+ // it will actually be in |sinksToShow_| until a real sink is returned by
+ // search. So the filter here shouldn't treat it like a pseudo sink.
+ searchResultsToShow = this.pseudoSinks_.filter(function(pseudoSink) {
+ return (!pendingPseudoSink || pseudoSink.id != pendingPseudoSink.id) &&
+ !searchResultsToShow.find(function(searchResult) {
+ return searchResult.sinkItem.name == searchInputText &&
+ searchResult.sinkItem.iconType == pseudoSink.iconType;
+ });
+ }).map(function(pseudoSink) {
+ pseudoSink.name = searchInputText;
+ return {sinkItem: pseudoSink,
+ substrings: [[0, searchInputText.length - 1]]};
+ }).concat(searchResultsToShow);
this.searchResultsToShow_ = searchResultsToShow;
},
@@ -1242,6 +1296,10 @@ Polymer({
return;
}
+ if (this.pseudoSinkSearchState_) {
+ sinkId = this.pseudoSinkSearchState_.mapRouteSinkId(sinkId);
+ }
+
// Check that |sinkId| exists and corresponds to |currentLaunchingSinkId_|.
if (!this.sinkMap_[sinkId] || this.currentLaunchingSinkId_ != sinkId) {
this.fire('report-resolved-route', {
@@ -1339,6 +1397,25 @@ Polymer({
},
/**
+ * Called when a search has completed up to route creation. |sinkId|
+ * identifies the sink that should be in |allSinks|, if a sink was found.
+ *
+ * @param {string} sinkId The ID of the sink that is the result of the
+ * currently pending search.
+ */
+ onReceiveSearchResult: function(sinkId) {
+ this.pseudoSinkSearchState_.receiveSinkResponse(sinkId);
+ this.currentLaunchingSinkId_ =
+ this.pseudoSinkSearchState_.checkForRealSink(this.allSinks);
+ this.rebuildSinksToShow_();
+ // If we're in filter view, make sure the |sinksToShow_| change is picked
+ // up.
+ if (this.isUserSearching_) {
+ this.filterSinks_(this.searchInputText_);
+ }
+ },
+
+ /**
* Called when a sink is clicked.
*
* @param {!Event} event The event object.
@@ -1406,11 +1483,24 @@ Polymer({
* name.
*/
rebuildSinksToShow_: function() {
- var sinksToShow = [];
+ var sinksToShow = this.allSinks.filter(function(sink) {
+ return !sink.isPseudoSink;
+ }, this);
+ if (this.pseudoSinkSearchState_) {
+ var pendingPseudoSink = this.pseudoSinkSearchState_.getPseudoSink();
+ // Here we will treat the pseudo sink that launched the search as a real
+ // sink until one is returned by search. This way it isn't possible to
+ // ever reach a UI state where there is no spinner being shown in the sink
+ // list but |currentLaunchingSinkId_| is non-empty (thereby preventing any
+ // other sink from launching).
+ if (pendingPseudoSink.id == this.currentLaunchingSinkId_) {
+ sinksToShow.unshift(pendingPseudoSink);
+ }
+ }
if (this.userHasSelectedCastMode_) {
// If user explicitly selected a cast mode, then we show only sinks that
// are compatible with current cast mode or sinks that are active.
- sinksToShow = this.allSinks.filter(function(element) {
+ sinksToShow = sinksToShow.filter(function(element) {
return (element.castModes & this.shownCastModeValue_) ||
this.sinkToRouteMap_[element.id];
}, this);
@@ -1421,7 +1511,6 @@ Polymer({
// - Otherwise, the cast mode becomes auto mode.
// Either way, all sinks will be shown.
this.setShownCastMode_(this.computeCastMode_());
- sinksToShow = this.allSinks;
}
this.sinksToShow_ = sinksToShow;
@@ -1436,9 +1525,17 @@ Polymer({
this.sinkMap_ = {};
this.allSinks.forEach(function(sink) {
- this.sinkMap_[sink.id] = sink;
+ if (!sink.isPseudoSink) {
+ this.sinkMap_[sink.id] = sink;
+ }
}, this);
+ if (this.pseudoSinkSearchState_) {
+ this.currentLaunchingSinkId_ =
+ this.pseudoSinkSearchState_.checkForRealSink(this.allSinks);
+ }
+ this.pseudoSinks_ =
+ this.allSinks.filter(function(sink) { return sink.isPseudoSink; });
this.rebuildSinksToShow_();
if (this.isUserSearching_) {
this.filterSinks_(this.searchInputText_);
@@ -1454,6 +1551,7 @@ Polymer({
* @private
*/
resetRouteCreationProperties_: function(creationSuccess) {
+ this.pseudoSinkSearchState_ = null;
this.currentLaunchingSinkId_ = '';
this.pendingCreatedRouteId_ = '';
@@ -1588,21 +1686,35 @@ Polymer({
media_router.MediaRouterUserAction.STATUS_REMOTE);
} else if (this.currentLaunchingSinkId_ == '') {
// Allow one launch at a time.
- this.fire('create-route', {
- sinkId: sink.id,
- // If user selected a cast mode, then we will create a route using that
- // cast mode. Otherwise, the UI is in "auto" cast mode and will use the
- // preferred cast mode compatible with the sink. The preferred cast mode
- // value is the least significant bit on the bitset.
- selectedCastModeValue:
- this.shownCastModeValue_ == media_router.CastModeType.AUTO ?
- sink.castModes & -sink.castModes : this.shownCastModeValue_
- });
- this.currentLaunchingSinkId_ = sink.id;
+ var selectedCastModeValue =
+ this.shownCastModeValue_ == media_router.CastModeType.AUTO ?
+ sink.castModes & -sink.castModes : this.shownCastModeValue_;
+ if (sink.isPseudoSink) {
+ this.pseudoSinkSearchState_ = new PseudoSinkSearchState(sink);
+ this.fire('search-sinks-and-create-route', {
+ id: sink.id,
+ name: sink.name,
+ domain: sink.domain,
+ selectedCastMode: selectedCastModeValue
+ });
+ } else {
+ this.fire('create-route', {
+ sinkId: sink.id,
+ // If user selected a cast mode, then we will create a route using
+ // that cast mode. Otherwise, the UI is in "auto" cast mode and will
+ // use the preferred cast mode compatible with the sink. The preferred
+ // cast mode value is the least significant bit on the bitset.
+ selectedCastModeValue: selectedCastModeValue
+ });
- var timeToSelectSink =
- performance.now() - this.populatedSinkListSeenTimeMs_;
- this.fire('report-sink-click-time', {timeMs: timeToSelectSink});
+ var timeToSelectSink =
+ performance.now() - this.populatedSinkListSeenTimeMs_;
+ this.fire('report-sink-click-time', {timeMs: timeToSelectSink});
+ }
+ this.currentLaunchingSinkId_ = sink.id;
+ if (sink.isPseudoSink) {
+ this.rebuildSinksToShow_();
+ }
this.maybeReportUserFirstAction(
media_router.MediaRouterUserAction.START_LOCAL);

Powered by Google App Engine
This is Rietveld 408576698