Skip to content

Commit

Permalink
Tachyon in Chromium.
Browse files Browse the repository at this point in the history
Implements the HTTP APIs for Tachyon Express to send and receive
messages between devices. Tachyon would be used as the signaling
channel for webrtc messages in Chrome Sharing. The actual mojo
implementation and tying it to the utility process is upcoming in
the next CL.

Bug: 1082305
Change-Id: I62e1c3a2deb8a6ef376e474b5ce353a3cb863232
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2250061
Commit-Queue: Himanshu Jaju <himanshujaju@chromium.org>
Reviewed-by: Christian Dullweber <dullweber@chromium.org>
Reviewed-by: David Roger <droger@chromium.org>
Reviewed-by: Alex Gough <ajgo@chromium.org>
Reviewed-by: Alex Chau <alexchau@chromium.org>
Cr-Commit-Position: refs/heads/master@{#782712}
  • Loading branch information
Himanshu Jaju authored and Commit Bot committed Jun 25, 2020
1 parent ef2ef40 commit bba37e4
Show file tree
Hide file tree
Showing 22 changed files with 1,222 additions and 0 deletions.
10 changes: 10 additions & 0 deletions chrome/browser/BUILD.gn
Expand Up @@ -3311,6 +3311,15 @@ static_library("browser") {
"nearby_sharing/share_target.cc",
"nearby_sharing/share_target.h",
"nearby_sharing/share_target_discovered_callback.h",
"nearby_sharing/tachyon/constants.h",
"nearby_sharing/tachyon/receive_messages_express.cc",
"nearby_sharing/tachyon/receive_messages_express.h",
"nearby_sharing/tachyon/send_message_express.cc",
"nearby_sharing/tachyon/send_message_express.h",
"nearby_sharing/tachyon/stream_parser.cc",
"nearby_sharing/tachyon/stream_parser.h",
"nearby_sharing/tachyon/token_fetcher.cc",
"nearby_sharing/tachyon/token_fetcher.h",
"nearby_sharing/text_attachment.cc",
"nearby_sharing/text_attachment.h",
"nearby_sharing/transfer_metadata.cc",
Expand Down Expand Up @@ -3712,6 +3721,7 @@ static_library("browser") {
"//chrome/browser/nearby_sharing/certificates",
"//chrome/browser/nearby_sharing/logging",
"//chrome/browser/nearby_sharing/proto",
"//chrome/browser/nearby_sharing/tachyon/proto",
"//chrome/browser/policy:path_parser",
"//chrome/browser/profile_resetter:profile_reset_report_proto",
"//chrome/browser/resource_coordinator:intervention_policy_database_proto",
Expand Down
2 changes: 2 additions & 0 deletions chrome/browser/nearby_sharing/tachyon/OWNERS
@@ -0,0 +1,2 @@
per-file *_messages*.h=set noparent
per-file *_messages*.h=file://ipc/SECURITY_OWNERS
27 changes: 27 additions & 0 deletions chrome/browser/nearby_sharing/tachyon/constants.h
@@ -0,0 +1,27 @@
// Copyright 2020 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.

#ifndef CHROME_BROWSER_NEARBY_SHARING_TACHYON_CONSTANTS_H_
#define CHROME_BROWSER_NEARBY_SHARING_TACHYON_CONSTANTS_H_

#if defined(NDEBUG)
const char kTachyonReceiveMessageAPI[] =
"https://tachyon-playground-autopush-grpc.sandbox.googleapis.com/v1/"
"messages:receiveExpress";

const char kTachyonSendMessageAPI[] =
"https://tachyon-playground-autopush-grpc.sandbox.googleapis.com/v1/"
"message:sendExpress";
#else
const char kTachyonReceiveMessageAPI[] =
"https://instantmessaging-pa.googleapis.com/v1/messages:receiveExpress";

const char kTachyonSendMessageAPI[] =
"https://instantmessaging-pa.googleapis.com/v1/message:sendExpress";
#endif // defined(NDEBUG)

// Template for optional OAuth2 authorization HTTP header.
const char kAuthorizationHeaderFormat[] = "Authorization: Bearer %s";

#endif // CHROME_BROWSER_NEARBY_SHARING_TACHYON_CONSTANTS_H_
19 changes: 19 additions & 0 deletions chrome/browser/nearby_sharing/tachyon/fake_token_fetcher.cc
@@ -0,0 +1,19 @@
// Copyright 2020 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/nearby_sharing/tachyon/fake_token_fetcher.h"

FakeTokenFetcher::FakeTokenFetcher()
: TokenFetcher(/*identity_manager=*/nullptr) {}

FakeTokenFetcher::~FakeTokenFetcher() = default;

void FakeTokenFetcher::GetAccessToken(
base::OnceCallback<void(const std::string& token)> callback) {
std::move(callback).Run(token_);
}

void FakeTokenFetcher::SetAccessToken(const std::string& token) {
token_ = token;
}
25 changes: 25 additions & 0 deletions chrome/browser/nearby_sharing/tachyon/fake_token_fetcher.h
@@ -0,0 +1,25 @@
// Copyright 2020 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.

#ifndef CHROME_BROWSER_NEARBY_SHARING_TACHYON_FAKE_TOKEN_FETCHER_H_
#define CHROME_BROWSER_NEARBY_SHARING_TACHYON_FAKE_TOKEN_FETCHER_H_

#include <string>

#include "chrome/browser/nearby_sharing/tachyon/token_fetcher.h"

class FakeTokenFetcher : public TokenFetcher {
public:
FakeTokenFetcher();
~FakeTokenFetcher() override;

void GetAccessToken(
base::OnceCallback<void(const std::string& token)> callback) override;
void SetAccessToken(const std::string& token);

private:
std::string token_;
};

#endif // CHROME_BROWSER_NEARBY_SHARING_TACHYON_FAKE_TOKEN_FETCHER_H_
16 changes: 16 additions & 0 deletions chrome/browser/nearby_sharing/tachyon/proto/BUILD.gn
@@ -0,0 +1,16 @@
# Copyright 2020 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.

import("//third_party/protobuf/proto_library.gni")

group("proto_lite") {
public_deps = [
":proto",
"//third_party/protobuf:protobuf_lite",
]
}

proto_library("proto") {
sources = [ "tachyon.proto" ]
}
99 changes: 99 additions & 0 deletions chrome/browser/nearby_sharing/tachyon/proto/tachyon.proto
@@ -0,0 +1,99 @@
// Copyright 2020 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.

// Brought from:
// google3/google/internal/communications/instantmessaging/v1/tachyon.proto At
// CL 316140872

syntax = "proto3";

package chrome_browser_nearby_sharing_tachyon;

// Required in Chrome.
option optimize_for = LITE_RUNTIME;

message InboxMessage {
string message_id = 1;

enum MessageType {
UNKNOWN = 0;
BASIC = 4;
}
MessageType message_type = 2;

bytes message = 12;

enum MessageClass {
USER = 0;
EPHEMERAL = 2;
}
MessageClass message_class = 5;
}

message IdType {
enum Type {
UNSET = 0;
NEARBY_ID = 27;
}
}

message Id {
IdType.Type type = 1;
string id = 2;
string app = 3;
}

message ApiVersion {
enum Value {
UNKNOWN = 0;
V4 = 4;
}
}

message Platform {
enum Type {
UNKNOWN = 0;
DESKTOP = 6;
}
}

message ClientInfo {
int32 version_major = 3;
int32 version_minor = 4;
int32 version_point = 5;
ApiVersion.Value api_version = 7;
Platform.Type platform_type = 9;
}

message RequestHeader {
string request_id = 1;
string app = 3;
ClientInfo client_info = 7;
Id requester_id = 10;
}

message SendMessageExpressRequest {
RequestHeader header = 1;
Id dest_id = 3;
InboxMessage message = 4;
}

message ReceiveMessagesExpressRequest {
RequestHeader header = 1;
}

message ReceiveMessagesResponse {
message Header {}
Header header = 1;
message FastPathReady {}

oneof body {
InboxMessage inbox_message = 2;
FastPathReady fast_path_ready = 7;
}
}

message StreamBody {
repeated bytes messages = 1;
}
144 changes: 144 additions & 0 deletions chrome/browser/nearby_sharing/tachyon/receive_messages_express.cc
@@ -0,0 +1,144 @@
// Copyright 2020 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/nearby_sharing/tachyon/receive_messages_express.h"

#include "base/bind.h"
#include "base/callback.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/nearby_sharing/tachyon/constants.h"
#include "chrome/browser/nearby_sharing/tachyon/proto/tachyon.pb.h"
#include "chrome/browser/nearby_sharing/tachyon/token_fetcher.h"
#include "net/base/load_flags.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "url/gurl.h"

namespace {
// TODO(himanshujaju) - Add nearby sharing policy when available.
const net::NetworkTrafficAnnotationTag kTrafficAnnotation =
net::DefineNetworkTrafficAnnotation("receive_messages_express", R"(
semantics {
sender: "ReceiveMessagesExpress"
description:
"Receives messages sent from another device via a Gaia "
"authenticated Google messaging backend."
trigger:
"Peer uses any Chrome cross-device sharing feature and selects "
"this devices to send the data to."
data: "WebRTC session description protocol messages are exchanged "
"between devices to set up a peer to peer connection as documented "
"in https://tools.ietf.org/html/rfc4566 and "
"https://www.w3.org/TR/webrtc/#session-description-model. No user "
"data is sent in the request."
destination: GOOGLE_OWNED_SERVICE
}
policy {
cookies_allowed: NO
setting:
"This feature is only enabled for signed-in users who enable "
"Nearby sharing"
chrome_policy {
BrowserSignin {
policy_options {mode: MANDATORY}
BrowserSignin: 0
}
}
})");

} // namespace

ReceiveMessagesExpress::ReceiveMessagesExpress(
TokenFetcher* token_fetcher,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
: token_fetcher_(token_fetcher),
url_loader_factory_(std::move(url_loader_factory)) {
DCHECK(token_fetcher_);
}

ReceiveMessagesExpress::~ReceiveMessagesExpress() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!success_callback_.is_null())
std::move(success_callback_).Run(false);
}

void ReceiveMessagesExpress::StartReceivingMessages(
const chrome_browser_nearby_sharing_tachyon::ReceiveMessagesExpressRequest&
request,
base::RepeatingCallback<void(const std::string& message)> listener,
SuccessCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!success_callback_.is_null()) {
// A pending callback was found, this should be marked as false since the
// previous receiver has not yet started listening for messages and is now
// going to be replaced by the new listener.
std::move(success_callback_).Run(false);
}
success_callback_ = std::move(callback);
url_loader_.reset();
stream_parser_ = std::make_unique<StreamParser>(listener);

token_fetcher_->GetAccessToken(
base::BindOnce(&ReceiveMessagesExpress::DoStartReceivingMessages,
weak_ptr_factory_.GetWeakPtr(), request));
}

void ReceiveMessagesExpress::DoStartReceivingMessages(
const chrome_browser_nearby_sharing_tachyon::ReceiveMessagesExpressRequest&
request,
const std::string& oauth_token) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (oauth_token.empty()) {
std::move(success_callback_).Run(false);
return;
}

auto resource_request = std::make_unique<network::ResourceRequest>();
resource_request->url = GURL(kTachyonReceiveMessageAPI);
resource_request->load_flags =
net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE;
resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit;
resource_request->method = net::HttpRequestHeaders::kPostMethod;
resource_request->headers.AddHeaderFromString(
base::StringPrintf(kAuthorizationHeaderFormat, oauth_token.c_str()));

url_loader_ = network::SimpleURLLoader::Create(std::move(resource_request),
kTrafficAnnotation);
url_loader_->AttachStringForUpload(request.SerializeAsString(),
"application/x-protobuf");
url_loader_->DownloadAsStream(url_loader_factory_.get(), this);
}

void ReceiveMessagesExpress::StopReceivingMessages() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!success_callback_.is_null())
std::move(success_callback_).Run(false);

url_loader_.reset();
stream_parser_.reset();
}

void ReceiveMessagesExpress::OnDataReceived(base::StringPiece data,
base::OnceClosure resume) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!success_callback_.is_null())
std::move(success_callback_).Run(true);

stream_parser_->Append(data);
std::move(resume).Run();
}

void ReceiveMessagesExpress::OnComplete(bool success) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!success_callback_.is_null())
std::move(success_callback_).Run(success);

url_loader_.reset();
stream_parser_.reset();
}

void ReceiveMessagesExpress::OnRetry(base::OnceClosure start_retry) {
NOTIMPLEMENTED();
}

0 comments on commit bba37e4

Please sign in to comment.