diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-07-12 14:07:37 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-07-17 10:29:26 +0000 |
commit | ec02ee4181c49b61fce1c8fb99292dbb8139cc90 (patch) | |
tree | 25cde714b2b71eb639d1cd53f5a22e9ba76e14ef /chromium/google_apis | |
parent | bb09965444b5bb20b096a291445170876225268d (diff) | |
download | qtwebengine-chromium-ec02ee4181c49b61fce1c8fb99292dbb8139cc90.tar.gz |
BASELINE: Update Chromium to 59.0.3071.134
Change-Id: Id02ef6fb2204c5fd21668a1c3e6911c83b17585a
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/google_apis')
31 files changed, 638 insertions, 90 deletions
diff --git a/chromium/google_apis/BUILD.gn b/chromium/google_apis/BUILD.gn index f92cbac1716..7170f4ecb67 100644 --- a/chromium/google_apis/BUILD.gn +++ b/chromium/google_apis/BUILD.gn @@ -138,7 +138,6 @@ template("google_apis_tmpl") { "//base", "//base/third_party/dynamic_annotations", "//crypto", - "//third_party/libxml", ] if (defined(invoker.deps)) { diff --git a/chromium/google_apis/drive/DEPS b/chromium/google_apis/drive/DEPS deleted file mode 100644 index 5827c268b07..00000000000 --- a/chromium/google_apis/drive/DEPS +++ /dev/null @@ -1,3 +0,0 @@ -include_rules = [ - "+third_party/libxml", -] diff --git a/chromium/google_apis/drive/base_requests.cc b/chromium/google_apis/drive/base_requests.cc index 39492d0f344..93d6cb1ccb0 100644 --- a/chromium/google_apis/drive/base_requests.cc +++ b/chromium/google_apis/drive/base_requests.cc @@ -37,6 +37,7 @@ #include "net/http/http_byte_range.h" #include "net/http/http_response_headers.h" #include "net/http/http_util.h" +#include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_status.h" @@ -399,7 +400,8 @@ void UrlFetchRequestBase::StartAfterPrepare( DVLOG(1) << "URL: " << url.spec(); URLFetcher::RequestType request_type = GetRequestType(); - url_fetcher_ = URLFetcher::Create(url, request_type, this); + url_fetcher_ = URLFetcher::Create(url, request_type, this, + sender_->get_traffic_annotation_tag()); url_fetcher_->SetRequestContext(sender_->url_request_context_getter()); // Always set flags to neither send nor save cookies. url_fetcher_->SetLoadFlags( diff --git a/chromium/google_apis/drive/base_requests_server_unittest.cc b/chromium/google_apis/drive/base_requests_server_unittest.cc index 6f815b99aa2..c1ce4326011 100644 --- a/chromium/google_apis/drive/base_requests_server_unittest.cc +++ b/chromium/google_apis/drive/base_requests_server_unittest.cc @@ -19,6 +19,7 @@ #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request_test_util.h" #include "testing/gtest/include/gtest/gtest.h" @@ -41,11 +42,10 @@ class BaseRequestsServerTest : public testing::Test { request_context_getter_ = new net::TestURLRequestContextGetter( message_loop_.task_runner()); - request_sender_.reset(new RequestSender( - new DummyAuthService, - request_context_getter_.get(), - message_loop_.task_runner(), - kTestUserAgent)); + request_sender_.reset( + new RequestSender(new DummyAuthService, request_context_getter_.get(), + message_loop_.task_runner(), kTestUserAgent, + TRAFFIC_ANNOTATION_FOR_TESTS)); ASSERT_TRUE(test_server_.InitializeAndListen()); test_server_.RegisterRequestHandler( diff --git a/chromium/google_apis/drive/base_requests_unittest.cc b/chromium/google_apis/drive/base_requests_unittest.cc index bce6b71b5fa..19449aa1730 100644 --- a/chromium/google_apis/drive/base_requests_unittest.cc +++ b/chromium/google_apis/drive/base_requests_unittest.cc @@ -22,6 +22,7 @@ #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request_test_util.h" #include "testing/gtest/include/gtest/gtest.h" @@ -115,10 +116,10 @@ class BaseRequestsTest : public testing::Test { request_context_getter_ = new net::TestURLRequestContextGetter( message_loop_.task_runner()); - sender_.reset(new RequestSender(new DummyAuthService, - request_context_getter_.get(), - message_loop_.task_runner(), - std::string() /* custom user agent */)); + sender_.reset(new RequestSender( + new DummyAuthService, request_context_getter_.get(), + message_loop_.task_runner(), std::string(), /* custom user agent */ + TRAFFIC_ANNOTATION_FOR_TESTS)); test_server_.RegisterRequestHandler( base::Bind(&BaseRequestsTest::HandleRequest, base::Unretained(this))); diff --git a/chromium/google_apis/drive/drive_api_parser.cc b/chromium/google_apis/drive/drive_api_parser.cc index 5cdff358f69..3e8975d1e4a 100644 --- a/chromium/google_apis/drive/drive_api_parser.cc +++ b/chromium/google_apis/drive/drive_api_parser.cc @@ -28,6 +28,13 @@ bool CreateFileResourceFromValue(const base::Value* value, return !!*file; } +bool CreateTeamDriveResourceFromValue( + const base::Value* value, + std::unique_ptr<TeamDriveResource>* file) { + *file = TeamDriveResource::CreateFrom(*value); + return !!*file; +} + // Converts |url_string| to |result|. Always returns true to be used // for JSONValueConverter::RegisterCustomField method. // TODO(mukai): make it return false in case of invalid |url_string|. @@ -97,6 +104,7 @@ const char kId[] = "id"; const char kETag[] = "etag"; const char kItems[] = "items"; const char kLargestChangeId[] = "largestChangeId"; +const char kNextPageToken[] = "nextPageToken"; // About Resource // https://developers.google.com/drive/v2/reference/about @@ -166,6 +174,7 @@ const char kDriveFolderMimeType[] = "application/vnd.google-apps.folder"; // Team Drive const char kTeamDriveKind[] = "drive#teamDrive"; +const char kTeamDriveListKind[] = "drive#teamDriveList"; const char kCapabilities[] = "capabilities"; // Team Drive capabilities. @@ -191,21 +200,35 @@ const char kNextLink[] = "nextLink"; // Change Resource // https://developers.google.com/drive/v2/reference/changes const char kChangeKind[] = "drive#change"; +const char kType[] = "type"; const char kFileId[] = "fileId"; const char kDeleted[] = "deleted"; const char kFile[] = "file"; +const char kTeamDrive[] = "teamDrive"; +const char kTeamDriveId[] = "teamDriveId"; // Changes List // https://developers.google.com/drive/v2/reference/changes/list const char kChangeListKind[] = "drive#changeList"; +// Maps category name to enum ChangeType. +struct ChangeTypeMap { + ChangeResource::ChangeType type; + const char* type_name; +}; + +constexpr ChangeTypeMap kChangeTypeMap[] = { + { ChangeResource::FILE, "file" }, + { ChangeResource::TEAM_DRIVE, "teamDrive" }, +}; + // Maps category name to enum IconCategory. struct AppIconCategoryMap { DriveAppIcon::IconCategory category; const char* category_name; }; -const AppIconCategoryMap kAppIconCategoryMap[] = { +constexpr AppIconCategoryMap kAppIconCategoryMap[] = { { DriveAppIcon::DOCUMENT, "document" }, { DriveAppIcon::APPLICATION, "application" }, { DriveAppIcon::SHARED_DOCUMENT, "documentShared" }, @@ -429,6 +452,9 @@ TeamDriveCapabilities::TeamDriveCapabilities() can_share_(false) { } +TeamDriveCapabilities::TeamDriveCapabilities(const TeamDriveCapabilities& src) = + default; + TeamDriveCapabilities::~TeamDriveCapabilities(){} // static @@ -496,6 +522,47 @@ bool TeamDriveResource::Parse(const base::Value& value) { } //////////////////////////////////////////////////////////////////////////////// +// TeamDriveList implementation + +TeamDriveList::TeamDriveList() {} + +TeamDriveList::~TeamDriveList() {} + +// static +void TeamDriveList::RegisterJSONConverter( + base::JSONValueConverter<TeamDriveList>* converter) { + converter->RegisterStringField(kNextPageToken, + &TeamDriveList::next_page_token_); + converter->RegisterRepeatedMessage<TeamDriveResource>(kItems, + &TeamDriveList::items_); +} + +// static +bool TeamDriveList::HasTeamDriveListKind(const base::Value& value) { + return IsResourceKindExpected(value, kTeamDriveListKind); +} + +// static +std::unique_ptr<TeamDriveList> TeamDriveList::CreateFrom( + const base::Value& value) { + std::unique_ptr<TeamDriveList> resource(new TeamDriveList()); + if (!HasTeamDriveListKind(value) || !resource->Parse(value)) { + LOG(ERROR) << "Unable to create: Invalid TeamDriveList JSON!"; + return std::unique_ptr<TeamDriveList>(); + } + return resource; +} + +bool TeamDriveList::Parse(const base::Value& value) { + base::JSONValueConverter<TeamDriveList> converter; + if (!converter.Convert(value, this)) { + LOG(ERROR) << "Unable to parse: Invalid TeamDriveList"; + return false; + } + return true; +} + +//////////////////////////////////////////////////////////////////////////////// // ParentReference implementation ParentReference::ParentReference() {} @@ -658,7 +725,8 @@ bool FileList::Parse(const base::Value& value) { //////////////////////////////////////////////////////////////////////////////// // ChangeResource implementation -ChangeResource::ChangeResource() : change_id_(0), deleted_(false) {} +ChangeResource::ChangeResource() + : change_id_(0), type_(UNKNOWN), deleted_(false) {} ChangeResource::~ChangeResource() {} @@ -667,6 +735,8 @@ void ChangeResource::RegisterJSONConverter( base::JSONValueConverter<ChangeResource>* converter) { converter->RegisterCustomField<int64_t>(kId, &ChangeResource::change_id_, &base::StringToInt64); + converter->RegisterCustomField<ChangeType>(kType, &ChangeResource::type_, + &ChangeResource::GetType); converter->RegisterStringField(kFileId, &ChangeResource::file_id_); converter->RegisterBoolField(kDeleted, &ChangeResource::deleted_); converter->RegisterCustomValueField(kFile, &ChangeResource::file_, @@ -674,6 +744,9 @@ void ChangeResource::RegisterJSONConverter( converter->RegisterCustomField<base::Time>( kModificationDate, &ChangeResource::modification_date_, &util::GetTimeFromString); + converter->RegisterStringField(kTeamDriveId, &ChangeResource::team_drive_id_); + converter->RegisterCustomValueField(kTeamDrive, &ChangeResource::team_drive_, + &CreateTeamDriveResourceFromValue); } // static @@ -696,6 +769,19 @@ bool ChangeResource::Parse(const base::Value& value) { return true; } +// static +bool ChangeResource::GetType(const base::StringPiece& type_name, + ChangeResource::ChangeType* result) { + for (size_t i = 0; i < arraysize(kChangeTypeMap); i++) { + if (type_name == kChangeTypeMap[i].type_name) { + *result = kChangeTypeMap[i].type; + return true; + } + } + DVLOG(1) << "Unknown change type" << type_name; + return false; +} + //////////////////////////////////////////////////////////////////////////////// // ChangeList implementation diff --git a/chromium/google_apis/drive/drive_api_parser.h b/chromium/google_apis/drive/drive_api_parser.h index 7f8c3ce5b6c..477ccfb4f7f 100644 --- a/chromium/google_apis/drive/drive_api_parser.h +++ b/chromium/google_apis/drive/drive_api_parser.h @@ -331,6 +331,7 @@ class AppList { class TeamDriveCapabilities { public: TeamDriveCapabilities(); + TeamDriveCapabilities(const TeamDriveCapabilities& src); ~TeamDriveCapabilities(); // Registers the mapping between JSON field names and the members in this @@ -410,8 +411,10 @@ class TeamDriveResource { // The ID of this Team Drive. The ID is the same as the top-level folder for // this Team Drive. const std::string& id() const { return id_; } + void set_id(const std::string& id) { id_ = id; } // The name of this Team Drive. const std::string& name() const { return name_; } + void set_name(const std::string& name) { name_ = name; } // Capabilities the current user has on this Team Drive. const TeamDriveCapabilities& capabilities() const { return capabilities_; } @@ -428,6 +431,53 @@ class TeamDriveResource { TeamDriveCapabilities capabilities_; }; +// TeamDriveList represents a collection of Team Drives. +// https://developers.google.com/drive/v2/reference/teamdrives/list +class TeamDriveList { + public: + TeamDriveList(); + ~TeamDriveList(); + + // Registers the mapping between JSON field names and the members in this + // class. + static void RegisterJSONConverter( + base::JSONValueConverter<TeamDriveList>* converter); + + // Returns true if the |value| has kind field for TeamDriveList. + static bool HasTeamDriveListKind(const base::Value& value); + + // Creates file list from parsed JSON. + static std::unique_ptr<TeamDriveList> CreateFrom(const base::Value& value); + + // Returns a page token for the next page of Team Drives. + const std::string& next_page_token() const { return next_page_token_; } + + void set_next_page_token(const std::string& next_page_token) { + this->next_page_token_ = next_page_token; + } + + // Returns a set of Team Drives in this list. + const std::vector<std::unique_ptr<TeamDriveResource>>& items() const { + return items_; + } + + std::vector<std::unique_ptr<TeamDriveResource>>* mutable_items() { + return &items_; + } + + private: + friend class DriveAPIParserTest; + FRIEND_TEST_ALL_PREFIXES(DriveAPIParserTest, TeamDriveListParser); + + // Parses and initializes data members from content of |value|. + // Return false if parsing fails. + bool Parse(const base::Value& value); + + std::string next_page_token_; + std::vector<std::unique_ptr<TeamDriveResource>> items_; + + DISALLOW_COPY_AND_ASSIGN(TeamDriveList); +}; // ParentReference represents a directory. // https://developers.google.com/drive/v2/reference/parents @@ -751,6 +801,11 @@ class FileList { // https://developers.google.com/drive/v2/reference/changes class ChangeResource { public: + enum ChangeType { + UNKNOWN, // Uninitialized state. + FILE, + TEAM_DRIVE, + }; ChangeResource(); ~ChangeResource(); @@ -766,20 +821,52 @@ class ChangeResource { // number. int64_t change_id() const { return change_id_; } + // Returns whether this is a change of a file or a team drive. + ChangeType type() const { return type_; } + // Returns a string file ID for corresponding file of the change. - const std::string& file_id() const { return file_id_; } + // Valid only when type == FILE. + const std::string& file_id() const { + DCHECK_EQ(FILE, type_); + return file_id_; + } // Returns true if this file is deleted in the change. bool is_deleted() const { return deleted_; } // Returns FileResource of the file which the change refers to. - const FileResource* file() const { return file_.get(); } - FileResource* mutable_file() { return file_.get(); } + // Valid only when type == FILE. + const FileResource* file() const { + DCHECK_EQ(FILE, type_); + return file_.get(); + } + FileResource* mutable_file() { + DCHECK_EQ(FILE, type_); + return file_.get(); + } + + // Returns TeamDriveResource which the change refers to. + // Valid only when type == TEAM_DRIVE. + const TeamDriveResource* team_drive() const { + DCHECK_EQ(TEAM_DRIVE, type_); + return team_drive_.get(); + } + TeamDriveResource* mutable_team_drive() { + DCHECK_EQ(TEAM_DRIVE, type_); + return team_drive_.get(); + } + + // Returns the ID of the Team Drive. Valid only when type == TEAM_DRIVE. + const std::string& team_drive_id() const { + DCHECK_EQ(TEAM_DRIVE, type_); + return team_drive_id_; + } // Returns the time of this modification. const base::Time& modification_date() const { return modification_date_; } void set_change_id(int64_t change_id) { change_id_ = change_id; } + void set_type(ChangeType type) { type_ = type; } void set_file_id(const std::string& file_id) { file_id_ = file_id; } @@ -787,6 +874,12 @@ class ChangeResource { deleted_ = deleted; } void set_file(std::unique_ptr<FileResource> file) { file_ = std::move(file); } + void set_team_drive(std::unique_ptr<TeamDriveResource> team_drive) { + team_drive_ = std::move(team_drive); + } + void set_team_drive_id(const std::string& team_drive_id) { + team_drive_id_ = team_drive_id; + } void set_modification_date(const base::Time& modification_date) { modification_date_ = modification_date; } @@ -799,11 +892,19 @@ class ChangeResource { // Return false if parsing fails. bool Parse(const base::Value& value); + // Extracts the change type from the given string. Returns false and does + // not change |result| when |type_name| has an unrecognizable value. + static bool GetType(const base::StringPiece& type_name, + ChangeResource::ChangeType* result); + int64_t change_id_; + ChangeType type_; std::string file_id_; bool deleted_; std::unique_ptr<FileResource> file_; base::Time modification_date_; + std::string team_drive_id_; + std::unique_ptr<TeamDriveResource> team_drive_; DISALLOW_COPY_AND_ASSIGN(ChangeResource); }; diff --git a/chromium/google_apis/drive/drive_api_parser_unittest.cc b/chromium/google_apis/drive/drive_api_parser_unittest.cc index 77579bc2b68..443b692dbd9 100644 --- a/chromium/google_apis/drive/drive_api_parser_unittest.cc +++ b/chromium/google_apis/drive/drive_api_parser_unittest.cc @@ -135,6 +135,19 @@ TEST(DriveAPIParserTest, TeamDriveResourceParser) { EXPECT_TRUE(capabilities.can_share()); } +TEST(DriveAPIParserTest, TeamDriveListParser) { + std::unique_ptr<base::Value> document( + test_util::LoadJSONFile("drive/team_drive_list.json")); + ASSERT_TRUE(document.get()); + EXPECT_TRUE(TeamDriveList::HasTeamDriveListKind(*document)); + + ASSERT_EQ(base::Value::Type::DICTIONARY, document->GetType()); + std::unique_ptr<TeamDriveList> resource(new TeamDriveList()); + EXPECT_TRUE(resource->Parse(*document)); + EXPECT_EQ(3U, resource->items().size()); + EXPECT_EQ("theNextPageToken", resource->next_page_token()); +} + // Test file list parsing. TEST(DriveAPIParserTest, FileListParser) { std::string error; @@ -252,10 +265,11 @@ TEST(DriveAPIParserTest, ChangeListParser) { changelist->next_link().spec()); EXPECT_EQ(13664, changelist->largest_change_id()); - ASSERT_EQ(4U, changelist->items().size()); + ASSERT_EQ(5U, changelist->items().size()); const ChangeResource& change1 = *changelist->items()[0]; EXPECT_EQ(8421, change1.change_id()); + EXPECT_EQ(ChangeResource::FILE, change1.type()); EXPECT_FALSE(change1.is_deleted()); EXPECT_EQ("1Pc8jzfU1ErbN_eucMMqdqzY3eBm0v8sxXm_1CtLxABC", change1.file_id()); EXPECT_EQ(change1.file_id(), change1.file()->file_id()); @@ -264,6 +278,7 @@ TEST(DriveAPIParserTest, ChangeListParser) { const ChangeResource& change2 = *changelist->items()[1]; EXPECT_EQ(8424, change2.change_id()); + EXPECT_EQ(ChangeResource::FILE, change2.type()); EXPECT_FALSE(change2.is_deleted()); EXPECT_EQ("0B4v7G8yEYAWHUmRrU2lMS2hLABC", change2.file_id()); EXPECT_EQ(change2.file_id(), change2.file()->file_id()); @@ -272,6 +287,7 @@ TEST(DriveAPIParserTest, ChangeListParser) { const ChangeResource& change3 = *changelist->items()[2]; EXPECT_EQ(8429, change3.change_id()); + EXPECT_EQ(ChangeResource::FILE, change3.type()); EXPECT_FALSE(change3.is_deleted()); EXPECT_EQ("0B4v7G8yEYAWHYW1OcExsUVZLABC", change3.file_id()); EXPECT_EQ(change3.file_id(), change3.file()->file_id()); @@ -281,12 +297,26 @@ TEST(DriveAPIParserTest, ChangeListParser) { // Deleted entry. const ChangeResource& change4 = *changelist->items()[3]; EXPECT_EQ(8430, change4.change_id()); + EXPECT_EQ(ChangeResource::FILE, change4.type()); EXPECT_EQ("ABCv7G8yEYAWHc3Y5X0hMSkJYXYZ", change4.file_id()); EXPECT_TRUE(change4.is_deleted()); base::Time modification_time; ASSERT_TRUE(util::GetTimeFromString("2012-07-27T12:34:56.789Z", &modification_time)); EXPECT_EQ(modification_time, change4.modification_date()); + + // Team Drive entry. + const ChangeResource& change5 = *changelist->items()[4]; + EXPECT_EQ(8431, change5.change_id()); + EXPECT_EQ(ChangeResource::TEAM_DRIVE, change5.type()); + EXPECT_EQ("id-of-team-drive-test-data", change5.team_drive()->id()); + EXPECT_EQ("id-of-team-drive-test-data", change5.team_drive_id()); + EXPECT_FALSE(change5.is_deleted()); + ASSERT_TRUE( + util::GetTimeFromString("2017-07-27T12:34:56.789Z", &modification_time)); + EXPECT_EQ(modification_time, change5.modification_date()); + // capabilities resource inside team_drive should be parsed + EXPECT_TRUE(change5.team_drive()->capabilities().can_share()); } TEST(DriveAPIParserTest, HasKind) { diff --git a/chromium/google_apis/drive/drive_api_requests.cc b/chromium/google_apis/drive/drive_api_requests.cc index f534efa021e..bc7baccc229 100644 --- a/chromium/google_apis/drive/drive_api_requests.cc +++ b/chromium/google_apis/drive/drive_api_requests.cc @@ -537,6 +537,24 @@ bool FilesCopyRequest::GetContentData(std::string* upload_content_type, return true; } +//========================= TeamDriveListRequest ============================= + +TeamDriveListRequest::TeamDriveListRequest( + RequestSender* sender, + const DriveApiUrlGenerator& url_generator, + const TeamDriveListCallback& callback) + : DriveApiDataRequest<TeamDriveList>(sender, callback), + url_generator_(url_generator), + max_results_(30) { + DCHECK(!callback.is_null()); +} + +TeamDriveListRequest::~TeamDriveListRequest() {} + +GURL TeamDriveListRequest::GetURLInternal() const { + return url_generator_.GetTeamDriveListUrl(max_results_, page_token_); +} + //============================= FilesListRequest ============================= FilesListRequest::FilesListRequest( diff --git a/chromium/google_apis/drive/drive_api_requests.h b/chromium/google_apis/drive/drive_api_requests.h index 1a2945bbdc2..9f19955e922 100644 --- a/chromium/google_apis/drive/drive_api_requests.h +++ b/chromium/google_apis/drive/drive_api_requests.h @@ -26,6 +26,12 @@ namespace google_apis { +// Callback used for requests that the server returns TeamDrive data +// formatted into JSON value. +typedef base::Callback<void(DriveApiErrorCode error, + std::unique_ptr<TeamDriveList> entry)> + TeamDriveListCallback; + // Callback used for requests that the server returns FileList data // formatted into JSON value. typedef base::Callback<void(DriveApiErrorCode error, @@ -466,6 +472,42 @@ class FilesCopyRequest : public DriveApiDataRequest<FileResource> { DISALLOW_COPY_AND_ASSIGN(FilesCopyRequest); }; +//========================== TeamDriveListRequest ============================= + +// This class performs the request for fetching TeamDrive list. +// The result may contain only first part of the result. The remaining result +// should be able to be fetched by ContinueGetFileListRequest defined below, +// or by TeamDriveListRequest with setting page token. +// This request is mapped to +// https://developers.google.com/drive/v2/teamdrives/ +class TeamDriveListRequest : public DriveApiDataRequest<TeamDriveList> { + public: + TeamDriveListRequest(RequestSender* sender, + const DriveApiUrlGenerator& url_generator, + const TeamDriveListCallback& callback); + ~TeamDriveListRequest() override; + + // Optional parameter + int max_results() const { return max_results_; } + void set_max_results(int max_results) { max_results_ = max_results; } + + const std::string& page_token() const { return page_token_; } + void set_page_token(const std::string& page_token) { + page_token_ = page_token; + } + + protected: + // Overridden from DriveApiDataRequest. + GURL GetURLInternal() const override; + + private: + const DriveApiUrlGenerator url_generator_; + int max_results_; + std::string page_token_; + + DISALLOW_COPY_AND_ASSIGN(TeamDriveListRequest); +}; + //============================= FilesListRequest ============================= // This class performs the request for fetching FileList. diff --git a/chromium/google_apis/drive/drive_api_requests_unittest.cc b/chromium/google_apis/drive/drive_api_requests_unittest.cc index 27cd0ebe15b..0ad1815f5d1 100644 --- a/chromium/google_apis/drive/drive_api_requests_unittest.cc +++ b/chromium/google_apis/drive/drive_api_requests_unittest.cc @@ -27,6 +27,7 @@ #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request_test_util.h" #include "testing/gtest/include/gtest/gtest.h" @@ -132,10 +133,10 @@ class DriveApiRequestsTest : public testing::Test { request_context_getter_ = new net::TestURLRequestContextGetter( message_loop_.task_runner()); - request_sender_.reset(new RequestSender(new DummyAuthService, - request_context_getter_.get(), - message_loop_.task_runner(), - kTestUserAgent)); + request_sender_.reset( + new RequestSender(new DummyAuthService, request_context_getter_.get(), + message_loop_.task_runner(), kTestUserAgent, + TRAFFIC_ANNOTATION_FOR_TESTS)); ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); @@ -900,6 +901,35 @@ TEST_F(DriveApiRequestsTest, FilesCopyRequest_EmptyParentResourceId) { EXPECT_TRUE(file_resource); } +TEST_F(DriveApiRequestsTest, TeamDriveListRequest) { + // Set an expected data file containing valid result. + expected_data_file_path_ = + test_util::GetTestFilePath("drive/team_drive_list.json"); + + DriveApiErrorCode error = DRIVE_OTHER_ERROR; + std::unique_ptr<TeamDriveList> result; + + { + base::RunLoop run_loop; + std::unique_ptr<drive::TeamDriveListRequest> request = + base::MakeUnique<drive::TeamDriveListRequest>( + request_sender_.get(), *url_generator_, + test_util::CreateQuitCallback( + &run_loop, + test_util::CreateCopyResultCallback(&error, &result))); + request->set_max_results(50); + request->set_page_token("PAGE_TOKEN"); + request_sender_->StartRequestWithAuthRetry(std::move(request)); + run_loop.Run(); + } + + EXPECT_EQ(HTTP_SUCCESS, error); + EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method); + EXPECT_EQ("/drive/v2/teamdrives?maxResults=50&pageToken=PAGE_TOKEN", + http_request_.relative_url); + EXPECT_TRUE(result); +} + TEST_F(DriveApiRequestsTest, FilesListRequest) { // Set an expected data file containing valid result. expected_data_file_path_ = test_util::GetTestFilePath( diff --git a/chromium/google_apis/drive/drive_api_url_generator.cc b/chromium/google_apis/drive/drive_api_url_generator.cc index fc520972881..1e09309704a 100644 --- a/chromium/google_apis/drive/drive_api_url_generator.cc +++ b/chromium/google_apis/drive/drive_api_url_generator.cc @@ -23,11 +23,8 @@ namespace { const char kDriveV2AboutUrl[] = "drive/v2/about"; const char kDriveV2AppsUrl[] = "drive/v2/apps"; const char kDriveV2ChangelistUrl[] = "drive/v2/changes"; -const char kDriveV2BetaChangelistUrl[] = "drive/v2beta/changes"; const char kDriveV2FilesUrl[] = "drive/v2/files"; -const char kDriveV2BetaFilesUrl[] = "drive/v2beta/files"; const char kDriveV2FileUrlPrefix[] = "drive/v2/files/"; -const char kDriveV2BetaFileUrlPrefix[] = "drive/v2beta/files/"; const char kDriveV2ChildrenUrlFormat[] = "drive/v2/files/%s/children"; const char kDriveV2ChildrenUrlForRemovalFormat[] = "drive/v2/files/%s/children/%s"; @@ -41,6 +38,7 @@ const char kDriveV2PermissionsUrlFormat[] = "drive/v2/files/%s/permissions"; const char kDriveV2DownloadUrlFormat[] = "drive/v2/files/%s?alt=media"; const char kDriveV2ThumbnailUrlFormat[] = "d/%s=w%d-h%d"; const char kDriveV2ThumbnailUrlWithCropFormat[] = "d/%s=w%d-h%d-c"; +const char kDriveV2TeamDrivesUrl[] = "drive/v2/teamdrives"; const char kIncludeTeamDriveItems[] = "includeTeamDriveItems"; const char kSupportsTeamDrives[] = "supportsTeamDrives"; @@ -106,8 +104,6 @@ GURL DriveApiUrlGenerator::GetFilesGetUrl(const std::string& file_id, const char* url_prefix = nullptr; if (use_internal_endpoint) url_prefix = kDriveV2InternalFileUrlPrefix; - else if (enable_team_drives_) - url_prefix = kDriveV2BetaFileUrlPrefix; else url_prefix = kDriveV2FileUrlPrefix; @@ -134,15 +130,20 @@ GURL DriveApiUrlGenerator::GetFilesGetUrl(const std::string& file_id, GURL DriveApiUrlGenerator::GetFilesAuthorizeUrl( const std::string& file_id, const std::string& app_id) const { - return base_url_.Resolve(base::StringPrintf(kDriveV2FilesAuthorizeUrlFormat, - net::EscapePath(file_id).c_str(), - net::EscapePath(app_id).c_str())); + GURL url = base_url_.Resolve(base::StringPrintf( + kDriveV2FilesAuthorizeUrlFormat, net::EscapePath(file_id).c_str(), + net::EscapePath(app_id).c_str())); + if (enable_team_drives_) + url = net::AppendOrReplaceQueryParameter(url, kSupportsTeamDrives, "true"); + return url; } GURL DriveApiUrlGenerator::GetFilesInsertUrl( const std::string& visibility) const { GURL url = base_url_.Resolve(kDriveV2FilesUrl); + if (enable_team_drives_) + url = net::AppendOrReplaceQueryParameter(url, kSupportsTeamDrives, "true"); if (!visibility.empty()) url = net::AppendOrReplaceQueryParameter(url, "visibility", visibility); @@ -155,6 +156,8 @@ GURL DriveApiUrlGenerator::GetFilesPatchUrl(const std::string& file_id, GURL url = base_url_.Resolve(kDriveV2FileUrlPrefix + net::EscapePath(file_id)); + if (enable_team_drives_) + url = net::AppendOrReplaceQueryParameter(url, kSupportsTeamDrives, "true"); // setModifiedDate is "false" by default. if (set_modified_date) url = net::AppendOrReplaceQueryParameter(url, "setModifiedDate", "true"); @@ -172,6 +175,8 @@ GURL DriveApiUrlGenerator::GetFilesCopyUrl( GURL url = base_url_.Resolve(base::StringPrintf( kDriveV2FileCopyUrlFormat, net::EscapePath(file_id).c_str())); + if (enable_team_drives_) + url = net::AppendOrReplaceQueryParameter(url, kSupportsTeamDrives, "true"); if (!visibility.empty()) url = net::AppendOrReplaceQueryParameter(url, "visibility", visibility); @@ -181,14 +186,11 @@ GURL DriveApiUrlGenerator::GetFilesCopyUrl( GURL DriveApiUrlGenerator::GetFilesListUrl(int max_results, const std::string& page_token, const std::string& q) const { - GURL url; + GURL url = base_url_.Resolve(kDriveV2FilesUrl); if (enable_team_drives_) { - url = base_url_.Resolve(kDriveV2BetaFilesUrl); url = net::AppendOrReplaceQueryParameter(url, kSupportsTeamDrives, "true"); url = net::AppendOrReplaceQueryParameter(url, kIncludeTeamDriveItems, "true"); - } else { - url = base_url_.Resolve(kDriveV2FilesUrl); } // maxResults is 100 by default. if (max_results != 100) { @@ -206,13 +208,19 @@ GURL DriveApiUrlGenerator::GetFilesListUrl(int max_results, } GURL DriveApiUrlGenerator::GetFilesDeleteUrl(const std::string& file_id) const { - return base_url_.Resolve(base::StringPrintf( + GURL url = base_url_.Resolve(base::StringPrintf( kDriveV2FileDeleteUrlFormat, net::EscapePath(file_id).c_str())); + if (enable_team_drives_) + url = net::AppendOrReplaceQueryParameter(url, kSupportsTeamDrives, "true"); + return url; } GURL DriveApiUrlGenerator::GetFilesTrashUrl(const std::string& file_id) const { - return base_url_.Resolve(base::StringPrintf( + GURL url = base_url_.Resolve(base::StringPrintf( kDriveV2FileTrashUrlFormat, net::EscapePath(file_id).c_str())); + if (enable_team_drives_) + url = net::AppendOrReplaceQueryParameter(url, kSupportsTeamDrives, "true"); + return url; } GURL DriveApiUrlGenerator::GetChangesListUrl(bool include_deleted, @@ -221,14 +229,11 @@ GURL DriveApiUrlGenerator::GetChangesListUrl(bool include_deleted, int64_t start_change_id) const { DCHECK_GE(start_change_id, 0); - GURL url; + GURL url = base_url_.Resolve(kDriveV2ChangelistUrl); if (enable_team_drives_) { - url = base_url_.Resolve(kDriveV2BetaChangelistUrl); url = net::AppendOrReplaceQueryParameter(url, kSupportsTeamDrives, "true"); url = net::AppendOrReplaceQueryParameter(url, kIncludeTeamDriveItems, "true"); - } else { - url = base_url_.Resolve(kDriveV2ChangelistUrl); } // includeDeleted is "true" by default. if (!include_deleted) @@ -252,8 +257,11 @@ GURL DriveApiUrlGenerator::GetChangesListUrl(bool include_deleted, GURL DriveApiUrlGenerator::GetChildrenInsertUrl( const std::string& file_id) const { - return base_url_.Resolve(base::StringPrintf( + GURL url = base_url_.Resolve(base::StringPrintf( kDriveV2ChildrenUrlFormat, net::EscapePath(file_id).c_str())); + if (enable_team_drives_) + url = net::AppendOrReplaceQueryParameter(url, kSupportsTeamDrives, "true"); + return url; } GURL DriveApiUrlGenerator::GetChildrenDeleteUrl( @@ -269,6 +277,8 @@ GURL DriveApiUrlGenerator::GetInitiateUploadNewFileUrl( GURL url = AddResumableUploadParam( base_url_.Resolve(kDriveV2UploadNewFileUrl)); + if (enable_team_drives_) + url = net::AppendOrReplaceQueryParameter(url, kSupportsTeamDrives, "true"); // setModifiedDate is "false" by default. if (set_modified_date) url = net::AppendOrReplaceQueryParameter(url, "setModifiedDate", "true"); @@ -284,6 +294,8 @@ GURL DriveApiUrlGenerator::GetInitiateUploadExistingFileUrl( net::EscapePath(resource_id)); url = AddResumableUploadParam(url); + if (enable_team_drives_) + url = net::AppendOrReplaceQueryParameter(url, kSupportsTeamDrives, "true"); // setModifiedDate is "false" by default. if (set_modified_date) url = net::AppendOrReplaceQueryParameter(url, "setModifiedDate", "true"); @@ -296,6 +308,8 @@ GURL DriveApiUrlGenerator::GetMultipartUploadNewFileUrl( GURL url = AddMultipartUploadParam( base_url_.Resolve(kDriveV2UploadNewFileUrl)); + if (enable_team_drives_) + url = net::AppendOrReplaceQueryParameter(url, kSupportsTeamDrives, "true"); // setModifiedDate is "false" by default. if (set_modified_date) url = net::AppendOrReplaceQueryParameter(url, "setModifiedDate", "true"); @@ -311,6 +325,8 @@ GURL DriveApiUrlGenerator::GetMultipartUploadExistingFileUrl( net::EscapePath(resource_id)); url = AddMultipartUploadParam(url); + if (enable_team_drives_) + url = net::AppendOrReplaceQueryParameter(url, kSupportsTeamDrives, "true"); // setModifiedDate is "false" by default. if (set_modified_date) url = net::AppendOrReplaceQueryParameter(url, "setModifiedDate", "true"); @@ -320,15 +336,20 @@ GURL DriveApiUrlGenerator::GetMultipartUploadExistingFileUrl( GURL DriveApiUrlGenerator::GenerateDownloadFileUrl( const std::string& resource_id) const { - return base_url_.Resolve(base::StringPrintf( + GURL url = base_url_.Resolve(base::StringPrintf( kDriveV2DownloadUrlFormat, net::EscapePath(resource_id).c_str())); + if (enable_team_drives_) + url = net::AppendOrReplaceQueryParameter(url, kSupportsTeamDrives, "true"); + return url; } GURL DriveApiUrlGenerator::GetPermissionsInsertUrl( const std::string& resource_id) const { - return base_url_.Resolve( - base::StringPrintf(kDriveV2PermissionsUrlFormat, - net::EscapePath(resource_id).c_str())); + GURL url = base_url_.Resolve(base::StringPrintf( + kDriveV2PermissionsUrlFormat, net::EscapePath(resource_id).c_str())); + if (enable_team_drives_) + url = net::AppendOrReplaceQueryParameter(url, kSupportsTeamDrives, "true"); + return url; } GURL DriveApiUrlGenerator::GetThumbnailUrl(const std::string& resource_id, @@ -342,7 +363,26 @@ GURL DriveApiUrlGenerator::GetThumbnailUrl(const std::string& resource_id, } GURL DriveApiUrlGenerator::GetBatchUploadUrl() const { - return base_url_.Resolve(kDriveV2BatchUploadUrl); + GURL url = base_url_.Resolve(kDriveV2BatchUploadUrl); + if (enable_team_drives_) + url = net::AppendOrReplaceQueryParameter(url, kSupportsTeamDrives, "true"); + return url; +} + +GURL DriveApiUrlGenerator::GetTeamDriveListUrl( + int max_results, + const std::string& page_token) const { + GURL url = base_url_.Resolve(kDriveV2TeamDrivesUrl); + + // maxResults is 10 by default. + if (max_results != 10) { + url = net::AppendOrReplaceQueryParameter(url, "maxResults", + base::IntToString(max_results)); + } + if (!page_token.empty()) + url = net::AppendOrReplaceQueryParameter(url, "pageToken", page_token); + + return url; } } // namespace google_apis diff --git a/chromium/google_apis/drive/drive_api_url_generator.h b/chromium/google_apis/drive/drive_api_url_generator.h index dd050fe2fc4..6c2985cde4c 100644 --- a/chromium/google_apis/drive/drive_api_url_generator.h +++ b/chromium/google_apis/drive/drive_api_url_generator.h @@ -76,6 +76,10 @@ class DriveApiUrlGenerator { // Returns a URL to trash a resource with the given |file_id|. GURL GetFilesTrashUrl(const std::string& file_id) const; + // Returns a URL to invoke "TeamDrives: list" method. + GURL GetTeamDriveListUrl(int max_results, + const std::string& page_token) const; + // Returns a URL to fetch a list of changes. GURL GetChangesListUrl(bool include_deleted, int max_results, diff --git a/chromium/google_apis/drive/drive_api_url_generator_unittest.cc b/chromium/google_apis/drive/drive_api_url_generator_unittest.cc index e20ba209171..affb9bb052c 100644 --- a/chromium/google_apis/drive/drive_api_url_generator_unittest.cc +++ b/chromium/google_apis/drive/drive_api_url_generator_unittest.cc @@ -64,7 +64,7 @@ TEST_F(DriveApiUrlGeneratorTest, GetFilesGetUrl) { EXPECT_EQ( "https://www.example.com/drive/v2/files/file%3Afile_id", url_generator_.GetFilesGetUrl("file:file_id", false, GURL()).spec()); - EXPECT_EQ("https://www.example.com/drive/v2beta/files/0Bz0bd074" + EXPECT_EQ("https://www.example.com/drive/v2/files/0Bz0bd074" "?supportsTeamDrives=true", team_drives_url_generator_.GetFilesGetUrl( "0Bz0bd074", false, GURL()).spec()); @@ -86,12 +86,22 @@ TEST_F(DriveApiUrlGeneratorTest, GetFilesGetUrl) { "?embedOrigin=chrome-extension%3A%2F%2Ftest", url_generator_.GetFilesGetUrl("0ADK06pfg", true, GURL("chrome-extension://test")).spec()); + + EXPECT_EQ( + "https://www.example.com/drive/v2/files/0ADK06pfg?" + "supportsTeamDrives=true", + team_drives_url_generator_.GetFilesGetUrl("0ADK06pfg", false, GURL()) + .spec()); } TEST_F(DriveApiUrlGeneratorTest, GetFilesAuthorizeUrl) { EXPECT_EQ( "https://www.example.com/drive/v2internal/files/aa/authorize?appId=bb", url_generator_.GetFilesAuthorizeUrl("aa", "bb").spec()); + EXPECT_EQ( + "https://www.example.com/drive/v2internal/files/aa/authorize?appId=bb&" + "supportsTeamDrives=true", + team_drives_url_generator_.GetFilesAuthorizeUrl("aa", "bb").spec()); } TEST_F(DriveApiUrlGeneratorTest, GetFilesInsertUrl) { @@ -101,6 +111,9 @@ TEST_F(DriveApiUrlGeneratorTest, GetFilesInsertUrl) { url_generator_.GetFilesInsertUrl("DEFAULT").spec()); EXPECT_EQ("https://www.example.com/drive/v2/files?visibility=PRIVATE", url_generator_.GetFilesInsertUrl("PRIVATE").spec()); + + EXPECT_EQ("https://www.example.com/drive/v2/files?supportsTeamDrives=true", + team_drives_url_generator_.GetFilesInsertUrl("").spec()); } TEST_F(DriveApiUrlGeneratorTest, GetFilePatchUrl) { @@ -138,6 +151,12 @@ TEST_F(DriveApiUrlGeneratorTest, GetFilePatchUrl) { "file:file_id", kTestPatterns[i].set_modified_date, kTestPatterns[i].update_viewed_date).spec()); } + + EXPECT_EQ( + "https://www.example.com/drive/v2/files/0ADK06pfg?" + "supportsTeamDrives=true", + team_drives_url_generator_.GetFilesPatchUrl("0ADK06pfg", false, true) + .spec()); } TEST_F(DriveApiUrlGeneratorTest, GetFilesCopyUrl) { @@ -154,6 +173,11 @@ TEST_F(DriveApiUrlGeneratorTest, GetFilesCopyUrl) { EXPECT_EQ("https://www.example.com/drive/v2/files/file%3Afile_id/copy" "?visibility=PRIVATE", url_generator_.GetFilesCopyUrl("file:file_id", "PRIVATE").spec()); + + EXPECT_EQ( + "https://www.example.com/drive/v2/files/0ADK06pfg/copy?" + "supportsTeamDrives=true", + team_drives_url_generator_.GetFilesCopyUrl("0ADK06pfg", "").spec()); } TEST_F(DriveApiUrlGeneratorTest, GetFilesListUrl) { @@ -179,8 +203,8 @@ TEST_F(DriveApiUrlGeneratorTest, GetFilesListUrl) { }; const std::string kV2FilesUrlPrefix = "https://www.example.com/drive/v2/files"; - const std::string kV2BetaFilesUrlPrefix = - "https://www.example.com/drive/v2beta/files?" + const std::string kV2FilesUrlPrefixWithTeamDrives = + "https://www.example.com/drive/v2/files?" "supportsTeamDrives=true&includeTeamDriveItems=true"; for (size_t i = 0; i < arraysize(kTestPatterns); ++i) { @@ -190,7 +214,7 @@ TEST_F(DriveApiUrlGeneratorTest, GetFilesListUrl) { url_generator_.GetFilesListUrl(kTestPatterns[i].max_results, kTestPatterns[i].page_token, kTestPatterns[i].q).spec()); - EXPECT_EQ(kV2BetaFilesUrlPrefix + + EXPECT_EQ(kV2FilesUrlPrefixWithTeamDrives + (kTestPatterns[i].expected_query.empty() ? "" : "&") + kTestPatterns[i].expected_query, team_drives_url_generator_.GetFilesListUrl( @@ -208,6 +232,11 @@ TEST_F(DriveApiUrlGeneratorTest, GetFilesDeleteUrl) { url_generator_.GetFilesDeleteUrl("0Bz0bd074").spec()); EXPECT_EQ("https://www.example.com/drive/v2/files/file%3Afile_id", url_generator_.GetFilesDeleteUrl("file:file_id").spec()); + + EXPECT_EQ( + "https://www.example.com/drive/v2/files/0ADK06pfg?" + "supportsTeamDrives=true", + team_drives_url_generator_.GetFilesDeleteUrl("0ADK06pfg").spec()); } TEST_F(DriveApiUrlGeneratorTest, GetFilesTrashUrl) { @@ -218,6 +247,11 @@ TEST_F(DriveApiUrlGeneratorTest, GetFilesTrashUrl) { url_generator_.GetFilesTrashUrl("0Bz0bd074").spec()); EXPECT_EQ("https://www.example.com/drive/v2/files/file%3Afile_id/trash", url_generator_.GetFilesTrashUrl("file:file_id").spec()); + + EXPECT_EQ( + "https://www.example.com/drive/v2/files/0ADK06pfg/trash?" + "supportsTeamDrives=true", + team_drives_url_generator_.GetFilesTrashUrl("0ADK06pfg").spec()); } TEST_F(DriveApiUrlGeneratorTest, GetChangesListUrl) { @@ -271,8 +305,8 @@ TEST_F(DriveApiUrlGeneratorTest, GetChangesListUrl) { const std::string kV2ChangesUrlPrefix = "https://www.example.com/drive/v2/changes"; - const std::string kV2BetaChangesUrlPrefix = - "https://www.example.com/drive/v2beta/changes?" + const std::string kV2ChangesUrlPrefixWithTeamDrives = + "https://www.example.com/drive/v2/changes?" "supportsTeamDrives=true&includeTeamDriveItems=true"; for (size_t i = 0; i < arraysize(kTestPatterns); ++i) { EXPECT_EQ(kV2ChangesUrlPrefix + @@ -283,7 +317,7 @@ TEST_F(DriveApiUrlGeneratorTest, GetChangesListUrl) { kTestPatterns[i].page_token, kTestPatterns[i].start_change_id) .spec()); - EXPECT_EQ(kV2BetaChangesUrlPrefix + + EXPECT_EQ(kV2ChangesUrlPrefixWithTeamDrives + (kTestPatterns[i].expected_query.empty() ? "" : "&") + kTestPatterns[i].expected_query, team_drives_url_generator_.GetChangesListUrl( @@ -303,6 +337,11 @@ TEST_F(DriveApiUrlGeneratorTest, GetChildrenInsertUrl) { url_generator_.GetChildrenInsertUrl("0Bz0bd074").spec()); EXPECT_EQ("https://www.example.com/drive/v2/files/file%3Afolder_id/children", url_generator_.GetChildrenInsertUrl("file:folder_id").spec()); + + EXPECT_EQ( + "https://www.example.com/drive/v2/files/0ADK06pfg/children?" + "supportsTeamDrives=true", + team_drives_url_generator_.GetChildrenInsertUrl("0ADK06pfg").spec()); } TEST_F(DriveApiUrlGeneratorTest, GetChildrenDeleteUrl) { @@ -330,6 +369,12 @@ TEST_F(DriveApiUrlGeneratorTest, GetInitiateUploadNewFileUrl) { "https://www.example.com/upload/drive/v2/files?uploadType=resumable&" "setModifiedDate=true", url_generator_.GetInitiateUploadNewFileUrl(kSetModifiedDate).spec()); + + EXPECT_EQ( + "https://www.example.com/upload/drive/v2/files?uploadType=resumable" + "&supportsTeamDrives=true", + team_drives_url_generator_.GetInitiateUploadNewFileUrl(!kSetModifiedDate) + .spec()); } TEST_F(DriveApiUrlGeneratorTest, GetInitiateUploadExistingFileUrl) { @@ -356,6 +401,13 @@ TEST_F(DriveApiUrlGeneratorTest, GetInitiateUploadExistingFileUrl) { "?uploadType=resumable&setModifiedDate=true", url_generator_.GetInitiateUploadExistingFileUrl("file:file_id", kSetModifiedDate).spec()); + + EXPECT_EQ( + "https://www.example.com/upload/drive/v2/files/0ADK06pfg" + "?uploadType=resumable&supportsTeamDrives=true", + team_drives_url_generator_ + .GetInitiateUploadExistingFileUrl("0ADK06pfg", !kSetModifiedDate) + .spec()); } TEST_F(DriveApiUrlGeneratorTest, GetMultipartUploadNewFileUrl) { @@ -368,6 +420,12 @@ TEST_F(DriveApiUrlGeneratorTest, GetMultipartUploadNewFileUrl) { "https://www.example.com/upload/drive/v2/files?uploadType=multipart&" "setModifiedDate=true", url_generator_.GetMultipartUploadNewFileUrl(kSetModifiedDate).spec()); + + EXPECT_EQ( + "https://www.example.com/upload/drive/v2/files?uploadType=multipart" + "&supportsTeamDrives=true", + team_drives_url_generator_.GetMultipartUploadNewFileUrl(!kSetModifiedDate) + .spec()); } TEST_F(DriveApiUrlGeneratorTest, GetMultipartUploadExistingFileUrl) { @@ -394,6 +452,13 @@ TEST_F(DriveApiUrlGeneratorTest, GetMultipartUploadExistingFileUrl) { "?uploadType=multipart&setModifiedDate=true", url_generator_.GetMultipartUploadExistingFileUrl( "file:file_id", kSetModifiedDate).spec()); + + EXPECT_EQ( + "https://www.example.com/upload/drive/v2/files/0ADK06pfg" + "?uploadType=multipart&supportsTeamDrives=true", + team_drives_url_generator_ + .GetMultipartUploadExistingFileUrl("0ADK06pfg", !kSetModifiedDate) + .spec()); } TEST_F(DriveApiUrlGeneratorTest, GenerateDownloadFileUrl) { @@ -403,11 +468,20 @@ TEST_F(DriveApiUrlGeneratorTest, GenerateDownloadFileUrl) { EXPECT_EQ( "https://www.example.com/drive/v2/files/file%3AresourceId?alt=media", url_generator_.GenerateDownloadFileUrl("file:resourceId").spec()); + + EXPECT_EQ( + "https://www.example.com/drive/v2/files/resourceId?" + "alt=media&supportsTeamDrives=true", + team_drives_url_generator_.GenerateDownloadFileUrl("resourceId").spec()); } TEST_F(DriveApiUrlGeneratorTest, GeneratePermissionsInsertUrl) { EXPECT_EQ("https://www.example.com/drive/v2/files/0ADK06pfg/permissions", url_generator_.GetPermissionsInsertUrl("0ADK06pfg").spec()); + EXPECT_EQ( + "https://www.example.com/drive/v2/files/0ADK06pfg/permissions?" + "supportsTeamDrives=true", + team_drives_url_generator_.GetPermissionsInsertUrl("0ADK06pfg").spec()); } TEST_F(DriveApiUrlGeneratorTest, GenerateThumbnailUrl) { @@ -423,6 +497,19 @@ TEST_F(DriveApiUrlGeneratorTest, GenerateThumbnailUrl) { TEST_F(DriveApiUrlGeneratorTest, BatchUploadUrl) { EXPECT_EQ("https://www.example.com/upload/drive", url_generator_.GetBatchUploadUrl().spec()); + EXPECT_EQ("https://www.example.com/upload/drive?supportsTeamDrives=true", + team_drives_url_generator_.GetBatchUploadUrl().spec()); +} + +TEST_F(DriveApiUrlGeneratorTest, GenerateTeamDriveListUrl) { + EXPECT_EQ("https://www.example.com/drive/v2/teamdrives", + team_drives_url_generator_.GetTeamDriveListUrl(10, "").spec()); + EXPECT_EQ("https://www.example.com/drive/v2/teamdrives?maxResults=100", + team_drives_url_generator_.GetTeamDriveListUrl(100, "").spec()); + EXPECT_EQ( + "https://www.example.com/drive/v2/" + "teamdrives?maxResults=100&pageToken=theToken", + team_drives_url_generator_.GetTeamDriveListUrl(100, "theToken").spec()); } } // namespace google_apis diff --git a/chromium/google_apis/drive/drive_switches.cc b/chromium/google_apis/drive/drive_switches.cc index 581e06804aa..33d4ac117fe 100644 --- a/chromium/google_apis/drive/drive_switches.cc +++ b/chromium/google_apis/drive/drive_switches.cc @@ -6,11 +6,8 @@ #include "google_apis/drive/drive_switches.h" namespace google_apis { -namespace { // Enables or disables Team Drives integration. -constexpr char kEnableTeamDrives[] = "team-drives"; - -} +const char kEnableTeamDrives[] = "team-drives"; TeamDrivesIntegrationStatus GetTeamDrivesIntegrationSwitch() { return base::CommandLine::ForCurrentProcess()->HasSwitch(kEnableTeamDrives) ? diff --git a/chromium/google_apis/drive/drive_switches.h b/chromium/google_apis/drive/drive_switches.h index 1c7460f61e8..a4143ad799d 100644 --- a/chromium/google_apis/drive/drive_switches.h +++ b/chromium/google_apis/drive/drive_switches.h @@ -15,6 +15,9 @@ enum TeamDrivesIntegrationStatus { // Whether Team Drives integration is enabled or not. TeamDrivesIntegrationStatus GetTeamDrivesIntegrationSwitch(); +// For tests which require specific commandline switch settings. +extern const char kEnableTeamDrives[]; + } // namespace switches #endif // GOOGLE_APIS_DRIVE_DRIVE_SWITHES_H_ diff --git a/chromium/google_apis/drive/files_list_request_runner_unittest.cc b/chromium/google_apis/drive/files_list_request_runner_unittest.cc index a6719f45e7a..89e7f3acf8a 100644 --- a/chromium/google_apis/drive/files_list_request_runner_unittest.cc +++ b/chromium/google_apis/drive/files_list_request_runner_unittest.cc @@ -18,6 +18,7 @@ #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request_test_util.h" #include "testing/gtest/include/gtest/gtest.h" @@ -70,7 +71,8 @@ class FilesListRequestRunnerTest : public testing::Test { request_sender_.reset( new RequestSender(new DummyAuthService, request_context_getter_.get(), - message_loop_.task_runner(), kTestUserAgent)); + message_loop_.task_runner(), kTestUserAgent, + TRAFFIC_ANNOTATION_FOR_TESTS)); test_server_.RegisterRequestHandler( base::Bind(&FilesListRequestRunnerTest::OnFilesListRequest, diff --git a/chromium/google_apis/drive/request_sender.cc b/chromium/google_apis/drive/request_sender.cc index dc946881c0d..9681f657ff2 100644 --- a/chromium/google_apis/drive/request_sender.cc +++ b/chromium/google_apis/drive/request_sender.cc @@ -18,13 +18,14 @@ RequestSender::RequestSender( AuthServiceInterface* auth_service, net::URLRequestContextGetter* url_request_context_getter, const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner, - const std::string& custom_user_agent) + const std::string& custom_user_agent, + const net::NetworkTrafficAnnotationTag& traffic_annotation) : auth_service_(auth_service), url_request_context_getter_(url_request_context_getter), blocking_task_runner_(blocking_task_runner), custom_user_agent_(custom_user_agent), - weak_ptr_factory_(this) { -} + traffic_annotation_(traffic_annotation), + weak_ptr_factory_(this) {} RequestSender::~RequestSender() { DCHECK(thread_checker_.CalledOnValidThread()); diff --git a/chromium/google_apis/drive/request_sender.h b/chromium/google_apis/drive/request_sender.h index 6fb7437a006..c5705e6a590 100644 --- a/chromium/google_apis/drive/request_sender.h +++ b/chromium/google_apis/drive/request_sender.h @@ -15,6 +15,7 @@ #include "base/memory/weak_ptr.h" #include "base/threading/thread_checker.h" #include "google_apis/drive/drive_api_error_codes.h" +#include "net/traffic_annotation/network_traffic_annotation.h" namespace base { class SequencedTaskRunner; @@ -48,7 +49,8 @@ class RequestSender { AuthServiceInterface* auth_service, net::URLRequestContextGetter* url_request_context_getter, const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner, - const std::string& custom_user_agent); + const std::string& custom_user_agent, + const net::NetworkTrafficAnnotationTag& traffic_annotation); ~RequestSender(); AuthServiceInterface* auth_service() { return auth_service_.get(); } @@ -74,6 +76,11 @@ class RequestSender { // TODO(kinaba): refactor the life time management and make this at private. void RequestFinished(AuthenticatedRequestInterface* request); + // Returns traffic annotation tag asssigned to this object. + const net::NetworkTrafficAnnotationTag& get_traffic_annotation_tag() const { + return traffic_annotation_; + } + private: base::Closure StartRequestWithAuthRetryInternal( AuthenticatedRequestInterface* request); @@ -102,6 +109,8 @@ class RequestSender { base::ThreadChecker thread_checker_; + const net::NetworkTrafficAnnotationTag traffic_annotation_; + // Note: This should remain the last member so it'll be destroyed and // invalidate its weak pointers before any other members are destroyed. base::WeakPtrFactory<RequestSender> weak_ptr_factory_; diff --git a/chromium/google_apis/drive/request_sender_unittest.cc b/chromium/google_apis/drive/request_sender_unittest.cc index 97839008296..6e32eb0ee76 100644 --- a/chromium/google_apis/drive/request_sender_unittest.cc +++ b/chromium/google_apis/drive/request_sender_unittest.cc @@ -9,6 +9,7 @@ #include "base/strings/string_number_conversions.h" #include "google_apis/drive/base_requests.h" #include "google_apis/drive/dummy_auth_service.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" namespace google_apis { @@ -58,8 +59,12 @@ class TestAuthService : public DummyAuthService { class RequestSenderTest : public testing::Test { protected: RequestSenderTest() - : auth_service_(new TestAuthService), - request_sender_(auth_service_, NULL, NULL, "dummy-user-agent") { + : auth_service_(new TestAuthService), + request_sender_(auth_service_, + NULL, + NULL, + "dummy-user-agent", + TRAFFIC_ANNOTATION_FOR_TESTS) { auth_service_->set_refresh_token(kTestRefreshToken); auth_service_->set_access_token(kTestAccessToken); } diff --git a/chromium/google_apis/gaia/OWNERS b/chromium/google_apis/gaia/OWNERS index 38f087d1924..3708c4285b4 100644 --- a/chromium/google_apis/gaia/OWNERS +++ b/chromium/google_apis/gaia/OWNERS @@ -1,3 +1,5 @@ msarda@chromium.org rogerta@chromium.org zelidrag@chromium.org + +# COMPONENT: Services>SignIn diff --git a/chromium/google_apis/gaia/fake_gaia.cc b/chromium/google_apis/gaia/fake_gaia.cc index 7ec5af739ec..3c91f25c685 100644 --- a/chromium/google_apis/gaia/fake_gaia.cc +++ b/chromium/google_apis/gaia/fake_gaia.cc @@ -17,6 +17,7 @@ #include "base/memory/linked_ptr.h" #include "base/path_service.h" #include "base/strings/string_number_conversions.h" +#include "base/strings/string_piece.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" @@ -748,8 +749,8 @@ void FakeGaia::HandleTokenInfo(const HttpRequest& request, response_dict.SetString("issued_to", token_info->issued_to); response_dict.SetString("audience", token_info->audience); response_dict.SetString("user_id", token_info->user_id); - std::vector<std::string> scope_vector(token_info->scopes.begin(), - token_info->scopes.end()); + std::vector<base::StringPiece> scope_vector(token_info->scopes.begin(), + token_info->scopes.end()); response_dict.SetString("scope", base::JoinString(scope_vector, " ")); response_dict.SetInteger("expires_in", token_info->expires_in); response_dict.SetString("email", token_info->email); diff --git a/chromium/google_apis/gaia/gaia_auth_fetcher.cc b/chromium/google_apis/gaia/gaia_auth_fetcher.cc index 03bd8a4526d..c5c3f1c71d0 100644 --- a/chromium/google_apis/gaia/gaia_auth_fetcher.cc +++ b/chromium/google_apis/gaia/gaia_auth_fetcher.cc @@ -499,7 +499,7 @@ bool GaiaAuthFetcher::ParseListIdpSessionsResponse(const std::string& data, iter != sessionsList->end(); iter++) { base::DictionaryValue* sessionDictionary; - if (!(*iter)->GetAsDictionary(&sessionDictionary)) + if (!iter->GetAsDictionary(&sessionDictionary)) continue; if (sessionDictionary->GetString("login_hint", login_hint)) diff --git a/chromium/google_apis/gaia/oauth2_access_token_fetcher_impl_unittest.cc b/chromium/google_apis/gaia/oauth2_access_token_fetcher_impl_unittest.cc index b1cae64a421..f62cf6be9ce 100644 --- a/chromium/google_apis/gaia/oauth2_access_token_fetcher_impl_unittest.cc +++ b/chromium/google_apis/gaia/oauth2_access_token_fetcher_impl_unittest.cc @@ -10,6 +10,7 @@ #include <string> #include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "google_apis/gaia/gaia_urls.h" @@ -124,7 +125,7 @@ class OAuth2AccessTokenFetcherImplTest : public testing::Test { } protected: - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment scoped_task_environment_; MockUrlFetcherFactory factory_; MockOAuth2AccessTokenConsumer consumer_; scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_; diff --git a/chromium/google_apis/gaia/oauth2_token_service_unittest.cc b/chromium/google_apis/gaia/oauth2_token_service_unittest.cc index bd770cf6b7e..b233d898a96 100644 --- a/chromium/google_apis/gaia/oauth2_token_service_unittest.cc +++ b/chromium/google_apis/gaia/oauth2_token_service_unittest.cc @@ -36,8 +36,8 @@ class RetryingTestingOAuth2TokenServiceConsumer void OnGetTokenFailure(const OAuth2TokenService::Request* request, const GoogleServiceAuthError& error) override { TestingOAuth2TokenServiceConsumer::OnGetTokenFailure(request, error); - request_.reset(oauth2_service_->StartRequest( - account_id_, OAuth2TokenService::ScopeSet(), this).release()); + request_ = oauth2_service_->StartRequest( + account_id_, OAuth2TokenService::ScopeSet(), this); } OAuth2TokenService* oauth2_service_; diff --git a/chromium/google_apis/gaia/ubertoken_fetcher.cc b/chromium/google_apis/gaia/ubertoken_fetcher.cc index 0e65e917d58..eb13798cddc 100644 --- a/chromium/google_apis/gaia/ubertoken_fetcher.cc +++ b/chromium/google_apis/gaia/ubertoken_fetcher.cc @@ -7,6 +7,7 @@ #include <vector> #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" #include "base/rand_util.h" #include "base/time/time.h" @@ -16,11 +17,11 @@ #include "google_apis/gaia/oauth2_token_service.h" namespace { -GaiaAuthFetcher* CreateGaiaAuthFetcher( +std::unique_ptr<GaiaAuthFetcher> CreateGaiaAuthFetcher( GaiaAuthConsumer* consumer, const std::string& source, net::URLRequestContextGetter* request_context) { - return new GaiaAuthFetcher(consumer, source, request_context); + return base::MakeUnique<GaiaAuthFetcher>(consumer, source, request_context); } } @@ -149,7 +150,7 @@ void UbertokenFetcher::RequestAccessToken() { } void UbertokenFetcher::ExchangeTokens() { - gaia_auth_fetcher_.reset( - gaia_auth_fetcher_factory_.Run(this, source_, request_context_)); + gaia_auth_fetcher_ = + gaia_auth_fetcher_factory_.Run(this, source_, request_context_); gaia_auth_fetcher_->StartTokenFetchForUberAuthExchange(access_token_); } diff --git a/chromium/google_apis/gaia/ubertoken_fetcher.h b/chromium/google_apis/gaia/ubertoken_fetcher.h index 6fef55b6c93..b5968af5d6d 100644 --- a/chromium/google_apis/gaia/ubertoken_fetcher.h +++ b/chromium/google_apis/gaia/ubertoken_fetcher.h @@ -28,10 +28,10 @@ namespace net { class URLRequestContextGetter; } -typedef base::Callback<GaiaAuthFetcher*(GaiaAuthConsumer*, - const std::string&, - net::URLRequestContextGetter*)> - GaiaAuthFetcherFactory; +using GaiaAuthFetcherFactory = base::Callback<std::unique_ptr<GaiaAuthFetcher>( + GaiaAuthConsumer*, + const std::string&, + net::URLRequestContextGetter*)>; // Callback for the |UbertokenFetcher| class. class UbertokenConsumer { diff --git a/chromium/google_apis/gcm/engine/checkin_request.cc b/chromium/google_apis/gcm/engine/checkin_request.cc index ad13923d72e..452e28466ef 100644 --- a/chromium/google_apis/gcm/engine/checkin_request.cc +++ b/chromium/google_apis/gcm/engine/checkin_request.cc @@ -11,6 +11,7 @@ #include "google_apis/gcm/monitoring/gcm_stats_recorder.h" #include "google_apis/gcm/protocol/checkin.pb.h" #include "net/base/load_flags.h" +#include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_status.h" @@ -144,9 +145,40 @@ void CheckinRequest::Start() { std::string upload_data; CHECK(request.SerializeToString(&upload_data)); - - url_fetcher_ = - net::URLFetcher::Create(checkin_url_, net::URLFetcher::POST, this); + net::NetworkTrafficAnnotationTag traffic_annotation = + net::DefineNetworkTrafficAnnotation("gcm_checkin", R"( + semantics { + sender: "GCM Driver" + description: + "Chromium interacts with Google Cloud Messaging to receive push " + "messages for various browser features, as well as on behalf of " + "websites and extensions. The check-in periodically verifies the " + "client's validity with Google servers, and receive updates to " + "configuration regarding interacting with Google services." + trigger: + "Immediately after a feature creates the first Google Cloud " + "Messaging registration. By default, Chromium will check in with " + "Google Cloud Messaging every two days. Google can adjust this " + "interval when it deems necessary." + data: + "The profile-bound Android ID and associated secret and account " + "tokens. A structure containing the Chromium version, channel, and " + "platform of the host operating system." + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: false + setting: + "Support for interacting with Google Cloud Messaging is enabled by " + "default, and there is no configuration option to completely " + "disable it. Websites wishing to receive push messages must " + "acquire express permission from the user for the 'Notification' " + "permission." + policy_exception_justification: + "Not implemented, considered not useful." + })"); + url_fetcher_ = net::URLFetcher::Create(checkin_url_, net::URLFetcher::POST, + this, traffic_annotation); url_fetcher_->SetRequestContext(request_context_getter_); url_fetcher_->SetUploadData(kRequestContentType, upload_data); url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | diff --git a/chromium/google_apis/gcm/engine/registration_request.cc b/chromium/google_apis/gcm/engine/registration_request.cc index 386af0e7eab..a2882b383db 100644 --- a/chromium/google_apis/gcm/engine/registration_request.cc +++ b/chromium/google_apis/gcm/engine/registration_request.cc @@ -20,6 +20,7 @@ #include "net/base/load_flags.h" #include "net/http/http_request_headers.h" #include "net/http/http_status_code.h" +#include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_status.h" @@ -144,9 +145,37 @@ RegistrationRequest::~RegistrationRequest() {} void RegistrationRequest::Start() { DCHECK(!callback_.is_null()); DCHECK(!url_fetcher_.get()); - - url_fetcher_ = - net::URLFetcher::Create(registration_url_, net::URLFetcher::POST, this); + net::NetworkTrafficAnnotationTag traffic_annotation = + net::DefineNetworkTrafficAnnotation("gcm_registration", R"( + semantics { + sender: "GCM Driver" + description: + "Chromium interacts with Google Cloud Messaging to receive push " + "messages for various browser features, as well as on behalf of " + "websites and extensions. This requests Google Cloud Messaging to " + "create a new subscription through which messages can be sent to " + "the registering entity, through Chromium." + trigger: + "Immediately after a feature, website or extension creates a new " + "registration with the GCM Driver. Repeated registration requests " + "will be served from the cache instead." + data: + "The profile-bound Android ID and associated secret, and the " + "identifiers for the feature, website or extension that is " + "creating the registration." + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: false + setting: + "Support for interacting with Google Cloud Messaging is enabled by " + "default, and there is no configuration option to completely " + "disable it." + policy_exception_justification: + "Not implemented, considered not useful." + })"); + url_fetcher_ = net::URLFetcher::Create( + registration_url_, net::URLFetcher::POST, this, traffic_annotation); url_fetcher_->SetRequestContext(request_context_getter_.get()); url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); diff --git a/chromium/google_apis/gcm/engine/unregistration_request.cc b/chromium/google_apis/gcm/engine/unregistration_request.cc index b7a07e4e6a6..3d0d4774c25 100644 --- a/chromium/google_apis/gcm/engine/unregistration_request.cc +++ b/chromium/google_apis/gcm/engine/unregistration_request.cc @@ -18,6 +18,7 @@ #include "net/base/load_flags.h" #include "net/http/http_request_headers.h" #include "net/http/http_status_code.h" +#include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_status.h" @@ -127,9 +128,36 @@ UnregistrationRequest::~UnregistrationRequest() {} void UnregistrationRequest::Start() { DCHECK(!callback_.is_null()); DCHECK(!url_fetcher_.get()); - - url_fetcher_ = - net::URLFetcher::Create(registration_url_, net::URLFetcher::POST, this); + net::NetworkTrafficAnnotationTag traffic_annotation = + net::DefineNetworkTrafficAnnotation("gcm_unregistration", R"( + semantics { + sender: "GCM Driver" + description: + "Chromium interacts with Google Cloud Messaging to receive push " + "messages for various browser features, as well as on behalf of " + "websites and extensions. This requests Google Cloud Messaging to " + "invalidate the included registration so that it can no longer be " + "used to distribute messages to Chromium." + trigger: + "Immediately after a feature, website or extension removes a " + "registration they previously created with the GCM Driver." + data: + "The profile-bound Android ID and associated secret, and the " + "identifiers for the feature, website or extension that is " + "removing the registration." + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: false + setting: + "Support for interacting with Google Cloud Messaging is enabled by " + "default, and there is no configuration option to completely " + "disable it." + policy_exception_justification: + "Not implemented, considered not useful." + })"); + url_fetcher_ = net::URLFetcher::Create( + registration_url_, net::URLFetcher::POST, this, traffic_annotation); url_fetcher_->SetRequestContext(request_context_getter_.get()); url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); diff --git a/chromium/google_apis/google_api_keys.cc b/chromium/google_apis/google_api_keys.cc index f107fd8f0e5..06a53e2476f 100644 --- a/chromium/google_apis/google_api_keys.cc +++ b/chromium/google_apis/google_api_keys.cc @@ -289,7 +289,7 @@ class APIKeyCache { std::string client_secrets_[CLIENT_NUM_ITEMS]; }; -static base::LazyInstance<APIKeyCache> g_api_key_cache = +static base::LazyInstance<APIKeyCache>::DestructorAtExit g_api_key_cache = LAZY_INSTANCE_INITIALIZER; bool HasKeysConfigured() { |