| 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..3b7396e2a375a20d1339d11ac5de3786d5bf5506
|
| --- /dev/null
|
| +++ b/chrome/browser/ui/webui/copresence_ui_handler.cc
|
| @@ -0,0 +1,182 @@
|
| +// 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/time/time.h"
|
| +#include "base/values.h"
|
| +#include "chrome/browser/extensions/api/copresence/copresence_api.h"
|
| +#include "components/copresence/proto/data.pb.h"
|
| +#include "components/copresence/public/copresence_manager.h"
|
| +#include "components/copresence/public/copresence_state.h"
|
| +#include "components/copresence/tokens.h"
|
| +#include "content/public/browser/web_contents.h"
|
| +#include "content/public/browser/web_ui.h"
|
| +#include "ui/base/l10n/time_format.h"
|
| +
|
| +using base::ListValue;
|
| +using base::DictionaryValue;
|
| +using content::WebUI;
|
| +using copresence::Directive;
|
| +using copresence::ReceivedToken;
|
| +using copresence::TransmittedToken;
|
| +using extensions::CopresenceService;
|
| +
|
| +// TODO(ckehoe): Make debug strings translatable?
|
| +
|
| +namespace {
|
| +
|
| +std::string FormatInstructionType(
|
| + copresence::TokenInstructionType directive_type) {
|
| + switch (directive_type) {
|
| + case copresence::TRANSMIT:
|
| + return "Transmit";
|
| +
|
| + case copresence::RECEIVE:
|
| + return "Receive";
|
| +
|
| + default:
|
| + NOTREACHED();
|
| + return "Unknown";
|
| + }
|
| +}
|
| +
|
| +std::string FormatMedium(copresence::TokenMedium medium) {
|
| + switch (medium) {
|
| + case copresence::AUDIO_ULTRASOUND_PASSBAND:
|
| + return "Ultrasound";
|
| +
|
| + case copresence::AUDIO_AUDIBLE_DTMF:
|
| + return "Audible";
|
| +
|
| + default:
|
| + NOTREACHED();
|
| + return "Unknown";
|
| + }
|
| +}
|
| +
|
| +std::string ConvertStatus(const TransmittedToken& token) {
|
| + bool done = token.stop_time < base::Time::Now();
|
| + std::string status = done ? "done" : "active";
|
| + if (token.broadcast_confirmed)
|
| + status += " confirmed";
|
| + return status;
|
| +}
|
| +
|
| +std::string ConvertStatus(const ReceivedToken& token) {
|
| + switch (token.valid) {
|
| + case ReceivedToken::VALID:
|
| + return "valid";
|
| +
|
| + case ReceivedToken::INVALID:
|
| + return "invalid";
|
| +
|
| + case ReceivedToken::UNKNOWN:
|
| + return std::string();
|
| +
|
| + default:
|
| + NOTREACHED();
|
| + 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));
|
| + DCHECK(!token.start_time.is_null());
|
| + js_token->SetString("time",
|
| + base::TimeFormatTimeOfDay(token.start_time));
|
| +
|
| + return js_token.Pass();
|
| +}
|
| +
|
| +// Safely retrieve the CopresenceState, if any.
|
| +copresence::CopresenceState* GetCopresenceState(WebUI* web_ui) {
|
| + // This function must be called with a valid web_ui.
|
| + DCHECK(web_ui);
|
| + DCHECK(web_ui->GetWebContents());
|
| +
|
| + // During shutdown, however, there may be no CopresenceService.
|
| + 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()) {
|
| + scoped_ptr<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", ui::TimeFormat::Simple(
|
| + ui::TimeFormat::FORMAT_DURATION,
|
| + ui::TimeFormat::LENGTH_LONG,
|
| + base::TimeDelta::FromMilliseconds(directive.ttl_millis())));
|
| +
|
| + js_directives.Append(js_directive.release());
|
| + }
|
| +
|
| + web_ui()->CallJavascriptFunction("refreshDirectives", js_directives);
|
| +}
|
| +
|
| +void CopresenceUIHandler::TokenTransmitted(const TransmittedToken& token) {
|
| + web_ui()->CallJavascriptFunction("updateTransmittedToken",
|
| + *FormatToken(token));
|
| +}
|
| +
|
| +void CopresenceUIHandler::TokenReceived(const ReceivedToken& token) {
|
| + web_ui()->CallJavascriptFunction("updateReceivedToken",
|
| + *FormatToken(token));
|
| +}
|
| +
|
| +void CopresenceUIHandler::HandlePopulateState(const ListValue* args) {
|
| + DCHECK(args->empty());
|
| + DirectivesUpdated();
|
| + // TODO(ckehoe): Pass tokens to JS as a batch.
|
| + for (const auto& token_entry : state_->transmitted_tokens())
|
| + TokenTransmitted(token_entry.second);
|
| + for (const auto& token_entry : state_->received_tokens())
|
| + TokenReceived(token_entry.second);
|
| +}
|
|
|