1 /* 2 * libjingle 3 * Copyright 2004--2005, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef _STATUS_H_ 29 #define _STATUS_H_ 30 31 #include "talk/xmpp/jid.h" 32 #include "talk/xmpp/constants.h" 33 34 #define GOOGLE_CLIENT_NODE "http://www.google.com/xmpp/client/caps" 35 36 namespace buzz { 37 38 class Status { 39 public: 40 Status() : 41 pri_(0), 42 show_(SHOW_NONE), 43 available_(false), 44 e_code_(0), 45 feedback_probation_(false), 46 know_capabilities_(false), 47 phone_capability_(false), 48 pmuc_capability_(false), 49 video_capability_(false), 50 camera_capability_(false), 51 is_google_client_(false) {} 52 53 ~Status() {} 54 55 // These are arranged in "priority order", i.e., if we see 56 // two statuses at the same priority but with different Shows, 57 // we will show the one with the highest show in the following 58 // order. 59 enum Show { 60 SHOW_NONE = 0, 61 SHOW_OFFLINE = 1, 62 SHOW_XA = 2, 63 SHOW_AWAY = 3, 64 SHOW_DND = 4, 65 SHOW_ONLINE = 5, 66 SHOW_CHAT = 6, 67 }; 68 69 const Jid & jid() const { return jid_; } 70 int priority() const { return pri_; } 71 Show show() const { return show_; } 72 const std::string & status() const { return status_; } 73 bool available() const { return available_ ; } 74 int error_code() const { return e_code_; } 75 const std::string & error_string() const { return e_str_; } 76 bool know_capabilities() const { return know_capabilities_; } 77 bool phone_capability() const { return phone_capability_; } 78 bool pmuc_capability() const { return pmuc_capability_; } 79 bool video_capability() const { return video_capability_; } 80 bool camera_capability() const { return camera_capability_; } 81 bool is_google_client() const { return is_google_client_; } 82 const std::string & version() const { return version_; } 83 bool feedback_probation() const { return feedback_probation_; } 84 const std::string& sent_time() const { return sent_time_; } 85 86 void set_jid(const Jid & jid) { jid_ = jid; } 87 void set_priority(int pri) { pri_ = pri; } 88 void set_show(Show show) { show_ = show; } 89 void set_status(const std::string & status) { status_ = status; } 90 void set_available(bool a) { available_ = a; } 91 void set_error(int e_code, const std::string e_str) 92 { e_code_ = e_code; e_str_ = e_str; } 93 void set_know_capabilities(bool f) { know_capabilities_ = f; } 94 void set_phone_capability(bool f) { phone_capability_ = f; } 95 void set_pmuc_capability(bool f) { pmuc_capability_ = f; } 96 void set_video_capability(bool f) { video_capability_ = f; } 97 void set_camera_capability(bool f) { camera_capability_ = f; } 98 void set_is_google_client(bool f) { is_google_client_ = f; } 99 void set_version(const std::string & v) { version_ = v; } 100 void set_feedback_probation(bool f) { feedback_probation_ = f; } 101 void set_sent_time(const std::string& time) { sent_time_ = time; } 102 103 void UpdateWith(const Status & new_value) { 104 if (!new_value.know_capabilities()) { 105 bool k = know_capabilities(); 106 bool i = is_google_client(); 107 bool p = phone_capability(); 108 std::string v = version(); 109 110 *this = new_value; 111 112 set_know_capabilities(k); 113 set_is_google_client(i); 114 set_phone_capability(p); 115 set_version(v); 116 } 117 else { 118 *this = new_value; 119 } 120 } 121 122 bool HasQuietStatus() const { 123 if (status_.empty()) 124 return false; 125 return !(QuietStatus().empty()); 126 } 127 128 // Knowledge of other clients' silly automatic status strings - 129 // Don't show these. 130 std::string QuietStatus() const { 131 if (jid_.resource().find("Psi") != std::string::npos) { 132 if (status_ == "Online" || 133 status_.find("Auto Status") != std::string::npos) 134 return STR_EMPTY; 135 } 136 if (jid_.resource().find("Gaim") != std::string::npos) { 137 if (status_ == "Sorry, I ran out for a bit!") 138 return STR_EMPTY; 139 } 140 return TrimStatus(status_); 141 } 142 143 std::string ExplicitStatus() const { 144 std::string result = QuietStatus(); 145 if (result.empty()) { 146 result = ShowStatus(); 147 } 148 return result; 149 } 150 151 std::string ShowStatus() const { 152 std::string result; 153 if (!available()) { 154 result = "Offline"; 155 } 156 else { 157 switch (show()) { 158 case SHOW_AWAY: 159 case SHOW_XA: 160 result = "Idle"; 161 break; 162 case SHOW_DND: 163 result = "Busy"; 164 break; 165 case SHOW_CHAT: 166 result = "Chatty"; 167 break; 168 default: 169 result = "Available"; 170 break; 171 } 172 } 173 return result; 174 } 175 176 static std::string TrimStatus(const std::string & st) { 177 std::string s(st); 178 int j = 0; 179 bool collapsing = true; 180 for (unsigned int i = 0; i < s.length(); i+= 1) { 181 if (s[i] <= ' ' && s[i] >= 0) { 182 if (collapsing) { 183 continue; 184 } 185 else { 186 s[j] = ' '; 187 j += 1; 188 collapsing = true; 189 } 190 } 191 else { 192 s[j] = s[i]; 193 j += 1; 194 collapsing = false; 195 } 196 } 197 if (collapsing && j > 0) { 198 j -= 1; 199 } 200 s.erase(j, s.length()); 201 return s; 202 } 203 204 private: 205 Jid jid_; 206 int pri_; 207 Show show_; 208 std::string status_; 209 bool available_; 210 int e_code_; 211 std::string e_str_; 212 bool feedback_probation_; 213 214 // capabilities (valid only if know_capabilities_ 215 bool know_capabilities_; 216 bool phone_capability_; 217 bool pmuc_capability_; 218 bool video_capability_; 219 bool camera_capability_; 220 bool is_google_client_; 221 std::string version_; 222 223 std::string sent_time_; // from the jabber:x:delay element 224 }; 225 226 class MucStatus : public Status { 227 public: 228 MucStatus() : audio_src_id_(0), video_src_id_(0) {} 229 uint32 audio_src_id() const { return audio_src_id_; } 230 uint32 video_src_id() const { return video_src_id_; } 231 void set_audio_src_id(uint32 audio_src_id) { 232 audio_src_id_ = audio_src_id; 233 } 234 void set_video_src_id(uint32 video_src_id) { 235 video_src_id_ = video_src_id; 236 } 237 private: 238 uint32 audio_src_id_; 239 uint32 video_src_id_; 240 }; 241 242 } 243 244 245 #endif 246