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

Unified 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/ui/webui/copresence_ui_handler.cc
diff --git a/chrome/browser/ui/webui/copresence_ui_handler.cc b/chrome/browser/ui/webui/copresence_ui_handler.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7b1ecb5775de08f6a16cc560753ab1fcda185163
--- /dev/null
+++ b/chrome/browser/ui/webui/copresence_ui_handler.cc
@@ -0,0 +1,185 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/copresence_ui_handler.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/i18n/time_formatting.h"
+#include "base/strings/stringprintf.h"
+#include "base/time/time.h"
+#include "base/values.h"
+#include "chrome/browser/extensions/api/copresence/copresence_api.h"
+#include "components/copresence/proto/chrome_only.pb.h"
+#include "components/copresence/proto/data.pb.h"
+#include "components/copresence/public/copresence_manager.h"
+#include "components/copresence/public/copresence_state.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_ui.h"
+
+using base::ListValue;
+using base::DictionaryValue;
+using content::WebUI;
+using copresence::Directive;
+using copresence::ReceivedToken;
+using copresence::SentToken;
+using extensions::CopresenceService;
+
+namespace {
+
+const int kMillisecondsPerMinute = 60 * 1000;
+const int kMillisecondsPerHour = 60 * kMillisecondsPerMinute;
+
+std::string FormatInstructionType(
+ copresence::TokenInstructionType directive_type) {
+ if (directive_type == copresence::TRANSMIT) {
+ return "Send";
rkc 2014/12/05 21:36:34 We should either stick with Broadcast/Scan or Tran
+ } else {
+ DCHECK(directive_type == copresence::RECEIVE);
+ return "Receive";
+ }
+}
+
+std::string FormatMedium(copresence::TokenMedium medium) {
+ if (medium == copresence::AUDIO_ULTRASOUND_PASSBAND) {
+ return "Ultrasound";
+ } else {
+ DCHECK(medium == copresence::AUDIO_AUDIBLE_DTMF);
+ return "Audible";
+ }
+}
+
+std::string FormatDuration(int64 milliseconds) {
+ DCHECK_GE(milliseconds, 0);
+ if (milliseconds < 1000) {
+ return base::StringPrintf("%ld milliseconds", milliseconds);
+ } else if (milliseconds < kMillisecondsPerMinute) {
+ int seconds = milliseconds / 1000;
+ return seconds == 1 ? "1 second" :
+ base::StringPrintf("%d seconds", seconds);
+ } else if (milliseconds < kMillisecondsPerHour) {
+ int minutes = milliseconds / kMillisecondsPerMinute;
+ return minutes == 1 ? "1 minute" :
+ base::StringPrintf("%d minutes", minutes);
+ } else {
+ int hours = milliseconds / kMillisecondsPerHour;
+ return hours == 1 ? "1 hour" :
+ base::StringPrintf("%d hours", hours);
+ }
+}
+
+base::Time ParseTimestamp(int64 milliseconds) {
+ return base::Time::UnixEpoch() +
+ base::TimeDelta::FromMilliseconds(milliseconds);
+}
+
+base::string16 FormatTime(int64 milliseconds) {
+ return base::TimeFormatTimeOfDay(ParseTimestamp(milliseconds));
+}
+
+std::string ConvertStatus(const SentToken& token) {
+ DCHECK(token.has_stop_time_millis());
+ bool done =
+ ParseTimestamp(token.stop_time_millis()) < base::Time::Now();
+ std::string status = done ? "done" : "active";
+ if (token.broadcast_confirmed())
+ status += " confirmed";
+ return status;
+}
+
+std::string ConvertStatus(const ReceivedToken& token) {
+ if (token.has_valid())
+ return token.valid() ? "valid" : "invalid";
+ else
+ return std::string();
+}
+
+template<class T>
+scoped_ptr<DictionaryValue> FormatToken(const T& token) {
+ scoped_ptr<DictionaryValue> js_token(new DictionaryValue);
+
+ js_token->SetString("id", token.id());
+ js_token->SetString("statuses", ConvertStatus(token));
+ js_token->SetString("medium", FormatMedium(token.medium()));
+ js_token->SetString("time", FormatTime(token.start_time_millis()));
+
+ return js_token.Pass();
+}
+
+// Safely retrieve the CopresenceState, if any.
+copresence::CopresenceState* GetCopresenceState(
+ WebUI* web_ui) {
+ DCHECK(web_ui && web_ui->GetWebContents());
+ CopresenceService* service = CopresenceService::GetFactoryInstance()->Get(
+ web_ui->GetWebContents()->GetBrowserContext());
+ return service && service->manager() ? service->manager()->state() : nullptr;
+}
+
+} // namespace
+
+
+// Public functions.
+
+CopresenceUIHandler::CopresenceUIHandler(WebUI* web_ui)
+ : state_(GetCopresenceState(web_ui)) {
+ DCHECK(state_);
+ state_->AddObserver(this);
+}
+
+CopresenceUIHandler::~CopresenceUIHandler() {
+ // Check if the CopresenceService is still up before unregistering.
+ state_ = GetCopresenceState(web_ui());
+ if (state_)
+ state_->RemoveObserver(this);
+}
+
+
+// Private functions.
+
+void CopresenceUIHandler::RegisterMessages() {
+ web_ui()->RegisterMessageCallback(
+ "populateCopresenceState",
+ base::Bind(&CopresenceUIHandler::HandlePopulateState,
+ base::Unretained(this)));
+}
+
+void CopresenceUIHandler::DirectivesUpdated() {
+ ListValue js_directives;
+ for (const Directive& directive : state_->active_directives()) {
+ DictionaryValue* js_directive = new DictionaryValue;
+
+ js_directive->SetString("type", FormatInstructionType(
+ directive.token_instruction().token_instruction_type()));
+ js_directive->SetString("medium", FormatMedium(
+ directive.token_instruction().medium()));
+ js_directive->SetString("duration", FormatDuration(directive.ttl_millis()));
+
+ js_directives.Append(js_directive);
+ }
+
+ web_ui()->CallJavascriptFunction("refreshDirectives", js_directives);
+}
+
+void CopresenceUIHandler::TokenSent(const copresence::SentToken& token) {
+ web_ui()->CallJavascriptFunction("updateSentToken",
+ *FormatToken(token));
+}
+
+void CopresenceUIHandler::TokenReceived(
+ const copresence::ReceivedToken& token) {
+ web_ui()->CallJavascriptFunction("updateReceivedToken",
+ *FormatToken(token));
+}
+
+void CopresenceUIHandler::HandlePopulateState(const ListValue* args) {
+ DCHECK(args->empty()) << "populateCopresenceState() doesn't take arguments";
+ DirectivesUpdated();
+ for (const auto& token_entry : state_->sent_tokens())
+ TokenSent(token_entry.second);
+ for (const auto& token_entry : state_->received_tokens())
+ TokenReceived(token_entry.second);
+}
« 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