1 // Copyright 2012 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "polo/pairing/message/configurationmessage.h"
16
17 #include <algorithm>
18 #include <sstream>
19 #include <string>
20
21 namespace polo {
22 namespace pairing {
23 namespace message {
24
ConfigurationMessage(const encoding::EncodingOption & encoding,message::OptionsMessage::ProtocolRole client_role)25 ConfigurationMessage::ConfigurationMessage(
26 const encoding::EncodingOption& encoding,
27 message::OptionsMessage::ProtocolRole client_role)
28 : PoloMessage(PoloMessage::kConfiguration),
29 encoding_(encoding),
30 client_role_(client_role) {
31 }
32
encoding() const33 const encoding::EncodingOption& ConfigurationMessage::encoding() const {
34 return encoding_;
35 }
36
client_role() const37 OptionsMessage::ProtocolRole ConfigurationMessage::client_role() const {
38 return client_role_;
39 }
40
ToString() const41 std::string ConfigurationMessage::ToString() const {
42 std::ostringstream ss;
43 ss << "[ConfigurationMessage encoding=" << encoding_.ToString()
44 << ", client_role=" << client_role_ << "]";
45 return ss.str();
46 }
47
GetBestConfiguration(const OptionsMessage & local_options,const OptionsMessage & peer_options)48 ConfigurationMessage* ConfigurationMessage::GetBestConfiguration(
49 const OptionsMessage &local_options,
50 const OptionsMessage &peer_options) {
51 // Compute the intersection of the available encodings. The sets use the
52 // 'less' comparator so they are ordered using EncodingOption's less-than
53 // operator.
54 encoding::EncodingOption::EncodingSet common_outputs;
55 std::insert_iterator<encoding::EncodingOption::EncodingSet> outputs_inserter(
56 common_outputs,
57 common_outputs.begin());
58 set_intersection(local_options.output_encodings().begin(),
59 local_options.output_encodings().end(),
60 peer_options.output_encodings().begin(),
61 peer_options.output_encodings().end(),
62 outputs_inserter,
63 encoding::EncodingOption::EncodingOptionComparator());
64
65 encoding::EncodingOption::EncodingSet common_inputs;
66 std::insert_iterator<encoding::EncodingOption::EncodingSet> inputs_inserter(
67 common_inputs,
68 common_inputs.begin());
69 set_intersection(local_options.input_encodings().begin(),
70 local_options.input_encodings().end(),
71 peer_options.input_encodings().begin(),
72 peer_options.input_encodings().end(),
73 inputs_inserter,
74 encoding::EncodingOption::EncodingOptionComparator());
75
76 if (common_outputs.size() == 0 || common_inputs.size() == 0) {
77 return NULL;
78 }
79
80 const encoding::EncodingOption* best_input = NULL;
81 const encoding::EncodingOption* best_output = NULL;
82
83 // Use the last option as the best encoding since that one will be the most
84 // complex based on the sorting order.
85 if (common_outputs.size() > 0) {
86 best_output = &*(--common_outputs.end());
87 }
88
89 if (common_inputs.size() > 0) {
90 best_input = &*(--common_inputs.end());
91 }
92
93 if (local_options.protocol_role_preference()
94 == OptionsMessage::kDisplayDevice) {
95 if (best_input) {
96 return new ConfigurationMessage(*best_input,
97 OptionsMessage::kDisplayDevice);
98 } else {
99 return new ConfigurationMessage(*best_output,
100 OptionsMessage::kInputDevice);
101 }
102 } else {
103 if (best_output) {
104 return new ConfigurationMessage(*best_output,
105 OptionsMessage::kInputDevice);
106 } else {
107 return new ConfigurationMessage(*best_input,
108 OptionsMessage::kDisplayDevice);
109 }
110 }
111 }
112
113 } // namespace message
114 } // namespace pairing
115 } // namespace polo
116