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

Side by Side Diff: chrome/browser/ui/webui/copresence_ui_handler.cc

Issue 734243003: Adding the chrome://copresence page (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@state
Patch Set: Created 6 years 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 unified diff | Download patch
« no previous file with comments | « chrome/browser/ui/webui/copresence_ui_handler.h ('k') | chrome/chrome_browser_ui.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/webui/copresence_ui_handler.h"
6
7 #include <map>
8 #include <string>
9 #include <vector>
10
11 #include "base/bind.h"
12 #include "base/i18n/time_formatting.h"
13 #include "base/strings/stringprintf.h"
14 #include "base/time/time.h"
15 #include "base/values.h"
16 #include "chrome/browser/extensions/api/copresence/copresence_api.h"
17 #include "components/copresence/proto/chrome_only.pb.h"
18 #include "components/copresence/proto/data.pb.h"
19 #include "components/copresence/public/copresence_manager.h"
20 #include "components/copresence/public/copresence_state.h"
21 #include "content/public/browser/web_contents.h"
22 #include "content/public/browser/web_ui.h"
23
24 using base::ListValue;
25 using base::DictionaryValue;
26 using content::WebUI;
27 using copresence::Directive;
28 using copresence::ReceivedToken;
29 using copresence::SentToken;
30 using extensions::CopresenceService;
31
32 namespace {
33
34 const int kMillisecondsPerMinute = 60 * 1000;
35 const int kMillisecondsPerHour = 60 * kMillisecondsPerMinute;
36
37 std::string FormatInstructionType(
38 copresence::TokenInstructionType directive_type) {
39 if (directive_type == copresence::TRANSMIT) {
40 return "Send";
rkc 2014/12/05 21:36:34 We should either stick with Broadcast/Scan or Tran
41 } else {
42 DCHECK(directive_type == copresence::RECEIVE);
43 return "Receive";
44 }
45 }
46
47 std::string FormatMedium(copresence::TokenMedium medium) {
48 if (medium == copresence::AUDIO_ULTRASOUND_PASSBAND) {
49 return "Ultrasound";
50 } else {
51 DCHECK(medium == copresence::AUDIO_AUDIBLE_DTMF);
52 return "Audible";
53 }
54 }
55
56 std::string FormatDuration(int64 milliseconds) {
57 DCHECK_GE(milliseconds, 0);
58 if (milliseconds < 1000) {
59 return base::StringPrintf("%ld milliseconds", milliseconds);
60 } else if (milliseconds < kMillisecondsPerMinute) {
61 int seconds = milliseconds / 1000;
62 return seconds == 1 ? "1 second" :
63 base::StringPrintf("%d seconds", seconds);
64 } else if (milliseconds < kMillisecondsPerHour) {
65 int minutes = milliseconds / kMillisecondsPerMinute;
66 return minutes == 1 ? "1 minute" :
67 base::StringPrintf("%d minutes", minutes);
68 } else {
69 int hours = milliseconds / kMillisecondsPerHour;
70 return hours == 1 ? "1 hour" :
71 base::StringPrintf("%d hours", hours);
72 }
73 }
74
75 base::Time ParseTimestamp(int64 milliseconds) {
76 return base::Time::UnixEpoch() +
77 base::TimeDelta::FromMilliseconds(milliseconds);
78 }
79
80 base::string16 FormatTime(int64 milliseconds) {
81 return base::TimeFormatTimeOfDay(ParseTimestamp(milliseconds));
82 }
83
84 std::string ConvertStatus(const SentToken& token) {
85 DCHECK(token.has_stop_time_millis());
86 bool done =
87 ParseTimestamp(token.stop_time_millis()) < base::Time::Now();
88 std::string status = done ? "done" : "active";
89 if (token.broadcast_confirmed())
90 status += " confirmed";
91 return status;
92 }
93
94 std::string ConvertStatus(const ReceivedToken& token) {
95 if (token.has_valid())
96 return token.valid() ? "valid" : "invalid";
97 else
98 return std::string();
99 }
100
101 template<class T>
102 scoped_ptr<DictionaryValue> FormatToken(const T& token) {
103 scoped_ptr<DictionaryValue> js_token(new DictionaryValue);
104
105 js_token->SetString("id", token.id());
106 js_token->SetString("statuses", ConvertStatus(token));
107 js_token->SetString("medium", FormatMedium(token.medium()));
108 js_token->SetString("time", FormatTime(token.start_time_millis()));
109
110 return js_token.Pass();
111 }
112
113 // Safely retrieve the CopresenceState, if any.
114 copresence::CopresenceState* GetCopresenceState(
115 WebUI* web_ui) {
116 DCHECK(web_ui && web_ui->GetWebContents());
117 CopresenceService* service = CopresenceService::GetFactoryInstance()->Get(
118 web_ui->GetWebContents()->GetBrowserContext());
119 return service && service->manager() ? service->manager()->state() : nullptr;
120 }
121
122 } // namespace
123
124
125 // Public functions.
126
127 CopresenceUIHandler::CopresenceUIHandler(WebUI* web_ui)
128 : state_(GetCopresenceState(web_ui)) {
129 DCHECK(state_);
130 state_->AddObserver(this);
131 }
132
133 CopresenceUIHandler::~CopresenceUIHandler() {
134 // Check if the CopresenceService is still up before unregistering.
135 state_ = GetCopresenceState(web_ui());
136 if (state_)
137 state_->RemoveObserver(this);
138 }
139
140
141 // Private functions.
142
143 void CopresenceUIHandler::RegisterMessages() {
144 web_ui()->RegisterMessageCallback(
145 "populateCopresenceState",
146 base::Bind(&CopresenceUIHandler::HandlePopulateState,
147 base::Unretained(this)));
148 }
149
150 void CopresenceUIHandler::DirectivesUpdated() {
151 ListValue js_directives;
152 for (const Directive& directive : state_->active_directives()) {
153 DictionaryValue* js_directive = new DictionaryValue;
154
155 js_directive->SetString("type", FormatInstructionType(
156 directive.token_instruction().token_instruction_type()));
157 js_directive->SetString("medium", FormatMedium(
158 directive.token_instruction().medium()));
159 js_directive->SetString("duration", FormatDuration(directive.ttl_millis()));
160
161 js_directives.Append(js_directive);
162 }
163
164 web_ui()->CallJavascriptFunction("refreshDirectives", js_directives);
165 }
166
167 void CopresenceUIHandler::TokenSent(const copresence::SentToken& token) {
168 web_ui()->CallJavascriptFunction("updateSentToken",
169 *FormatToken(token));
170 }
171
172 void CopresenceUIHandler::TokenReceived(
173 const copresence::ReceivedToken& token) {
174 web_ui()->CallJavascriptFunction("updateReceivedToken",
175 *FormatToken(token));
176 }
177
178 void CopresenceUIHandler::HandlePopulateState(const ListValue* args) {
179 DCHECK(args->empty()) << "populateCopresenceState() doesn't take arguments";
180 DirectivesUpdated();
181 for (const auto& token_entry : state_->sent_tokens())
182 TokenSent(token_entry.second);
183 for (const auto& token_entry : state_->received_tokens())
184 TokenReceived(token_entry.second);
185 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/webui/copresence_ui_handler.h ('k') | chrome/chrome_browser_ui.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698