1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930 |
- // Copyright (c) 2012 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 "components/drive/service/fake_drive_service.h"
- #include <stddef.h>
- #include <memory>
- #include <string>
- #include <utility>
- #include <vector>
- #include "base/bind.h"
- #include "base/check_op.h"
- #include "base/files/file_util.h"
- #include "base/hash/md5.h"
- #include "base/json/json_string_value_serializer.h"
- #include "base/memory/ptr_util.h"
- #include "base/notreached.h"
- #include "base/strings/escape.h"
- #include "base/strings/string_number_conversions.h"
- #include "base/strings/string_split.h"
- #include "base/strings/string_tokenizer.h"
- #include "base/strings/string_util.h"
- #include "base/strings/stringprintf.h"
- #include "base/strings/utf_string_conversions.h"
- #include "base/threading/thread_restrictions.h"
- #include "base/threading/thread_task_runner_handle.h"
- #include "base/values.h"
- #include "components/drive/drive_api_util.h"
- #include "components/drive/file_system_core_util.h"
- #include "google_apis/common/test_util.h"
- #include "google_apis/drive/drive_api_parser.h"
- #include "google_apis/drive/drive_common_callbacks.h"
- #include "net/base/url_util.h"
- using google_apis::AboutResource;
- using google_apis::AboutResourceCallback;
- using google_apis::ApiErrorCode;
- using google_apis::AuthStatusCallback;
- using google_apis::CancelCallbackOnce;
- using google_apis::ChangeList;
- using google_apis::ChangeListCallback;
- using google_apis::ChangeListOnceCallback;
- using google_apis::ChangeResource;
- using google_apis::DownloadActionCallback;
- using google_apis::DRIVE_FILE_ERROR;
- using google_apis::EntryActionCallback;
- using google_apis::FileList;
- using google_apis::FileListCallback;
- using google_apis::FileResource;
- using google_apis::FileResourceCallback;
- using google_apis::GetContentCallback;
- using google_apis::HTTP_BAD_REQUEST;
- using google_apis::HTTP_CREATED;
- using google_apis::HTTP_FORBIDDEN;
- using google_apis::HTTP_NO_CONTENT;
- using google_apis::HTTP_NOT_FOUND;
- using google_apis::HTTP_PRECONDITION;
- using google_apis::HTTP_RESUME_INCOMPLETE;
- using google_apis::HTTP_SUCCESS;
- using google_apis::InitiateUploadCallback;
- using google_apis::NO_CONNECTION;
- using google_apis::OTHER_ERROR;
- using google_apis::ParentReference;
- using google_apis::ProgressCallback;
- using google_apis::StartPageToken;
- using google_apis::TeamDriveList;
- using google_apis::TeamDriveListCallback;
- using google_apis::TeamDriveResource;
- using google_apis::UploadRangeResponse;
- using google_apis::drive::UploadRangeCallback;
- namespace test_util = google_apis::test_util;
- namespace drive {
- namespace {
- // Returns true if the entry matches with the search query.
- // Supports queries consist of following format.
- // - Phrases quoted by double/single quotes
- // - AND search for multiple words/phrases segmented by space
- // - Limited attribute search. Only "title:" is supported.
- bool EntryMatchWithQuery(const ChangeResource& entry,
- const std::string& query) {
- base::StringTokenizer tokenizer(query, " ");
- tokenizer.set_quote_chars("\"'");
- while (tokenizer.GetNext()) {
- std::string key, value;
- const std::string& token = tokenizer.token();
- if (token.find(':') == std::string::npos) {
- base::TrimString(token, "\"'", &value);
- } else {
- base::StringTokenizer key_value(token, ":");
- key_value.set_quote_chars("\"'");
- if (!key_value.GetNext())
- return false;
- key = key_value.token();
- if (!key_value.GetNext())
- return false;
- base::TrimString(key_value.token(), "\"'", &value);
- }
- // TODO(peria): Deal with other attributes than title.
- if (!key.empty() && key != "title")
- return false;
- // Search query in the title.
- if (!entry.file() || entry.file()->title().find(value) == std::string::npos)
- return false;
- }
- return true;
- }
- void ScheduleUploadRangeCallback(UploadRangeCallback callback,
- int64_t start_position,
- int64_t end_position,
- ApiErrorCode error,
- std::unique_ptr<FileResource> entry) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(callback),
- UploadRangeResponse(error, start_position, end_position),
- std::move(entry)));
- }
- void FileListCallbackAdapter(FileListCallback callback,
- ApiErrorCode error,
- std::unique_ptr<ChangeList> change_list) {
- std::unique_ptr<FileList> file_list;
- if (!change_list) {
- std::move(callback).Run(error, std::move(file_list));
- return;
- }
- file_list = std::make_unique<FileList>();
- file_list->set_next_link(change_list->next_link());
- for (size_t i = 0; i < change_list->items().size(); ++i) {
- const ChangeResource& entry = *change_list->items()[i];
- if (entry.type() == ChangeResource::FILE && entry.file())
- file_list->mutable_items()->push_back(
- std::make_unique<FileResource>(*entry.file()));
- }
- std::move(callback).Run(error, std::move(file_list));
- }
- bool UserHasWriteAccess(google_apis::drive::PermissionRole user_permission) {
- switch (user_permission) {
- case google_apis::drive::PERMISSION_ROLE_OWNER:
- case google_apis::drive::PERMISSION_ROLE_WRITER:
- return true;
- case google_apis::drive::PERMISSION_ROLE_READER:
- case google_apis::drive::PERMISSION_ROLE_COMMENTER:
- break;
- }
- return false;
- }
- void CallFileResourceCallback(FileResourceCallback callback,
- const UploadRangeResponse& response,
- std::unique_ptr<FileResource> entry) {
- std::move(callback).Run(response.code, std::move(entry));
- }
- struct CallResumeUpload {
- CallResumeUpload() = default;
- ~CallResumeUpload() = default;
- void Run(ApiErrorCode code, const GURL& upload_url) {
- if (service) {
- service->ResumeUpload(
- upload_url,
- /* start position */ 0,
- /* end position */ content_length, content_length, content_type,
- local_file_path,
- base::BindOnce(&CallFileResourceCallback, std::move(callback)),
- progress_callback);
- }
- }
- base::WeakPtr<FakeDriveService> service;
- int64_t content_length;
- std::string content_type;
- base::FilePath local_file_path;
- FileResourceCallback callback;
- ProgressCallback progress_callback;
- };
- std::string GetTeamDriveId(const google_apis::ChangeResource& change_resource) {
- std::string team_drive_id;
- switch (change_resource.type()) {
- case ChangeResource::FILE:
- team_drive_id = change_resource.file()->team_drive_id();
- break;
- case ChangeResource::TEAM_DRIVE:
- team_drive_id = change_resource.team_drive_id();
- break;
- case ChangeResource::UNKNOWN:
- NOTREACHED();
- break;
- }
- return team_drive_id;
- }
- } // namespace
- struct FakeDriveService::EntryInfo {
- EntryInfo()
- : user_permission(google_apis::drive::PERMISSION_ROLE_OWNER),
- visibility(google_apis::drive::FILE_VISIBILITY_DEFAULT) {}
- google_apis::ChangeResource change_resource;
- GURL share_url;
- std::string content_data;
- // Behaves in the same way as "userPermission" described in
- // https://developers.google.com/drive/v2/reference/files
- google_apis::drive::PermissionRole user_permission;
- google_apis::drive::FileVisibility visibility;
- };
- struct FakeDriveService::UploadSession {
- std::string content_type;
- int64_t content_length;
- std::string parent_resource_id;
- std::string resource_id;
- std::string etag;
- std::string title;
- int64_t uploaded_size;
- UploadSession() : content_length(0), uploaded_size(0) {}
- UploadSession(std::string content_type,
- int64_t content_length,
- std::string parent_resource_id,
- std::string resource_id,
- std::string etag,
- std::string title)
- : content_type(content_type),
- content_length(content_length),
- parent_resource_id(parent_resource_id),
- resource_id(resource_id),
- etag(etag),
- title(title),
- uploaded_size(0) {}
- };
- FakeDriveService::FakeDriveService()
- : about_resource_(new AboutResource),
- start_page_token_(new StartPageToken),
- date_seq_(0),
- next_upload_sequence_number_(0),
- largest_changestamp_(654321),
- default_max_results_(0),
- resource_id_count_(0),
- team_drive_list_load_count_(0),
- file_list_load_count_(0),
- change_list_load_count_(0),
- directory_load_count_(0),
- about_resource_load_count_(0),
- blocked_file_list_load_count_(0),
- start_page_token_load_count_(0),
- offline_(false),
- never_return_all_file_list_(false) {
- UpdateLatestChangelistId(largest_changestamp_, std::string());
- about_resource_->set_quota_bytes_total(9876543210);
- about_resource_->set_quota_bytes_used_aggregate(6789012345);
- about_resource_->set_root_folder_id(GetRootResourceId());
- }
- FakeDriveService::~FakeDriveService() {
- DCHECK(thread_checker_.CalledOnValidThread());
- }
- void FakeDriveService::AddTeamDrive(const std::string& id,
- const std::string& name) {
- AddTeamDrive(id, name, "");
- }
- void FakeDriveService::AddTeamDrive(const std::string& id,
- const std::string& name,
- const std::string& start_page_token) {
- DCHECK(entries_.find(id) == entries_.end());
- auto team_drive = std::make_unique<TeamDriveResource>();
- team_drive->set_id(id);
- team_drive->set_name(name);
- team_drive_value_.push_back(std::move(team_drive));
- team_drive_start_page_tokens_[id] = std::make_unique<StartPageToken>();
- team_drive_start_page_tokens_[id]->set_start_page_token(start_page_token);
- const EntryInfo* new_entry = AddNewTeamDriveEntry(id, name);
- DCHECK(new_entry);
- }
- void FakeDriveService::SetQuotaValue(int64_t used, int64_t total) {
- DCHECK(thread_checker_.CalledOnValidThread());
- about_resource_->set_quota_bytes_used_aggregate(used);
- about_resource_->set_quota_bytes_total(total);
- }
- void FakeDriveService::Initialize(const CoreAccountId& account_id) {
- DCHECK(thread_checker_.CalledOnValidThread());
- }
- void FakeDriveService::AddObserver(DriveServiceObserver* observer) {
- DCHECK(thread_checker_.CalledOnValidThread());
- }
- void FakeDriveService::RemoveObserver(DriveServiceObserver* observer) {
- DCHECK(thread_checker_.CalledOnValidThread());
- }
- bool FakeDriveService::CanSendRequest() const {
- DCHECK(thread_checker_.CalledOnValidThread());
- return true;
- }
- bool FakeDriveService::HasAccessToken() const {
- DCHECK(thread_checker_.CalledOnValidThread());
- return true;
- }
- void FakeDriveService::RequestAccessToken(AuthStatusCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(callback);
- std::move(callback).Run(google_apis::HTTP_NOT_MODIFIED, "fake_access_token");
- }
- bool FakeDriveService::HasRefreshToken() const {
- DCHECK(thread_checker_.CalledOnValidThread());
- return true;
- }
- void FakeDriveService::ClearAccessToken() {
- DCHECK(thread_checker_.CalledOnValidThread());
- }
- void FakeDriveService::ClearRefreshToken() {
- DCHECK(thread_checker_.CalledOnValidThread());
- }
- std::string FakeDriveService::GetRootResourceId() const {
- return "fake_root";
- }
- void FakeDriveService::GetTeamDriveListInternal(
- int start_offset,
- int max_results,
- int* load_counter,
- google_apis::TeamDriveListCallback callback) {
- if (offline_) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), NO_CONNECTION,
- std::unique_ptr<TeamDriveList>()));
- return;
- }
- if (load_counter)
- ++*load_counter;
- // If max_results is zero then we want to return the entire list.
- if (max_results <= 0) {
- max_results = team_drive_value_.size();
- }
- auto result = std::make_unique<TeamDriveList>();
- size_t next_start_offset = start_offset + max_results;
- if (next_start_offset < team_drive_value_.size()) {
- // Embed next start offset to next page token to be read in
- // GetRemainingTeamDriveList next time.
- result->set_next_page_token(base::NumberToString(next_start_offset));
- }
- for (size_t i = start_offset;
- i < std::min(next_start_offset, team_drive_value_.size()); ++i) {
- std::unique_ptr<TeamDriveResource> team_drive(new TeamDriveResource);
- team_drive->set_id(team_drive_value_[i]->id());
- team_drive->set_name(team_drive_value_[i]->name());
- team_drive->set_capabilities(team_drive_value_[i]->capabilities());
- result->mutable_items()->push_back(std::move(team_drive));
- }
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(callback), HTTP_SUCCESS, std::move(result)));
- }
- CancelCallbackOnce FakeDriveService::GetAllTeamDriveList(
- TeamDriveListCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(callback);
- GetTeamDriveListInternal(0, default_max_results_,
- &team_drive_list_load_count_, std::move(callback));
- return CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::GetAllFileList(
- const std::string& team_drive_id,
- FileListCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- if (never_return_all_file_list_) {
- ++blocked_file_list_load_count_;
- return CancelCallbackOnce();
- }
- GetChangeListInternal(
- 0, // start changestamp
- std::string(), // empty search query
- std::string(), // no directory resource id,
- team_drive_id,
- 0, // start offset
- default_max_results_, &file_list_load_count_,
- base::BindOnce(&FileListCallbackAdapter, std::move(callback)));
- return CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::GetFileListInDirectory(
- const std::string& directory_resource_id,
- FileListCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(!directory_resource_id.empty());
- GetChangeListInternal(
- 0, // start changestamp
- std::string(), // empty search query
- directory_resource_id,
- std::string(), // empty team drive id.
- 0, // start offset
- default_max_results_, &directory_load_count_,
- base::BindOnce(&FileListCallbackAdapter, std::move(callback)));
- return CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::Search(const std::string& search_query,
- FileListCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(!search_query.empty());
- GetChangeListInternal(
- 0, // start changestamp
- search_query,
- std::string(), // no directory resource id,
- std::string(), // empty team drive id.
- 0, // start offset
- default_max_results_, nullptr,
- base::BindOnce(&FileListCallbackAdapter, std::move(callback)));
- return CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::SearchByTitle(
- const std::string& title,
- const std::string& directory_resource_id,
- FileListCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(!title.empty());
- // Note: the search implementation here doesn't support quotation unescape,
- // so don't escape here.
- GetChangeListInternal(
- 0, // start changestamp
- base::StringPrintf("title:'%s'", title.c_str()), directory_resource_id,
- std::string(), // empty team drive id.
- 0, // start offset
- default_max_results_, nullptr,
- base::BindOnce(&FileListCallbackAdapter, std::move(callback)));
- return CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::GetChangeList(
- int64_t start_changestamp,
- ChangeListCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(callback);
- GetChangeListInternal(start_changestamp,
- std::string(), // empty search query
- std::string(), // no directory resource id,
- std::string(), // empty team drive id.
- 0, // start offset
- default_max_results_, &change_list_load_count_,
- std::move(callback));
- return CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::GetChangeListByToken(
- const std::string& team_drive_id,
- const std::string& start_page_token,
- ChangeListCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(callback);
- int64_t changestamp = 0;
- CHECK(base::StringToInt64(start_page_token, &changestamp));
- GetChangeListInternal(changestamp,
- std::string(), // empty search query
- std::string(), // no directory resource id,
- team_drive_id,
- 0, // start offset
- default_max_results_, &change_list_load_count_,
- std::move(callback));
- return CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::GetRemainingChangeList(
- const GURL& next_link,
- ChangeListCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(!next_link.is_empty());
- DCHECK(callback);
- // "changestamp", "q", "parent" and "start-offset" are parameters to
- // implement "paging" of the result on FakeDriveService.
- // The URL should be the one filled in GetChangeListInternal of the
- // previous method invocation, so it should start with "http://localhost/?".
- // See also GetChangeListInternal.
- DCHECK_EQ(next_link.host(), "localhost");
- DCHECK_EQ(next_link.path(), "/");
- int64_t start_changestamp = 0;
- std::string search_query;
- std::string directory_resource_id;
- std::string team_drive_id;
- int start_offset = 0;
- int max_results = default_max_results_;
- base::StringPairs parameters;
- if (base::SplitStringIntoKeyValuePairs(next_link.query(), '=', '&',
- ¶meters)) {
- for (const auto& param : parameters) {
- if (param.first == "changestamp") {
- base::StringToInt64(param.second, &start_changestamp);
- } else if (param.first == "q") {
- search_query = base::UnescapeBinaryURLComponent(param.second);
- } else if (param.first == "parent") {
- directory_resource_id = base::UnescapeBinaryURLComponent(param.second);
- } else if (param.first == "team-drive-id") {
- team_drive_id = base::UnescapeBinaryURLComponent(param.second);
- } else if (param.first == "start-offset") {
- base::StringToInt(param.second, &start_offset);
- } else if (param.first == "max-results") {
- base::StringToInt(param.second, &max_results);
- }
- }
- }
- GetChangeListInternal(start_changestamp, search_query, directory_resource_id,
- team_drive_id, start_offset, max_results, nullptr,
- std::move(callback));
- return CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::GetRemainingTeamDriveList(
- const std::string& page_token,
- TeamDriveListCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(!page_token.empty());
- DCHECK(callback);
- // Next offset index to page token is embedded in the token.
- size_t start_offset;
- bool parse_success = base::StringToSizeT(page_token, &start_offset);
- DCHECK(parse_success);
- GetTeamDriveListInternal(start_offset, default_max_results_, nullptr,
- std::move(callback));
- return CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::GetRemainingFileList(
- const GURL& next_link,
- FileListCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(!next_link.is_empty());
- return GetRemainingChangeList(
- next_link, base::BindOnce(&FileListCallbackAdapter, std::move(callback)));
- }
- CancelCallbackOnce FakeDriveService::GetFileResource(
- const std::string& resource_id,
- FileResourceCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(callback);
- if (offline_) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), NO_CONNECTION,
- std::unique_ptr<FileResource>()));
- return CancelCallbackOnce();
- }
- EntryInfo* entry = FindEntryByResourceId(resource_id);
- if (entry && entry->change_resource.file()) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_SUCCESS,
- std::make_unique<FileResource>(
- *entry->change_resource.file())));
- return CancelCallbackOnce();
- }
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND,
- std::unique_ptr<FileResource>()));
- return CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::GetAboutResource(
- AboutResourceCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(callback);
- if (offline_) {
- std::unique_ptr<AboutResource> null;
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(callback), NO_CONNECTION, std::move(null)));
- return CancelCallbackOnce();
- }
- ++about_resource_load_count_;
- std::unique_ptr<AboutResource> about_resource(
- new AboutResource(*about_resource_));
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_SUCCESS,
- std::move(about_resource)));
- return CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::GetStartPageToken(
- const std::string& team_drive_id,
- google_apis::StartPageTokenCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(callback);
- if (offline_) {
- std::unique_ptr<StartPageToken> null;
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(callback), NO_CONNECTION, std::move(null)));
- return CancelCallbackOnce();
- }
- std::unique_ptr<StartPageToken> start_page_token;
- if (team_drive_id.empty()) {
- start_page_token = std::make_unique<StartPageToken>(*start_page_token_);
- } else {
- auto it = team_drive_start_page_tokens_.find(team_drive_id);
- DCHECK(it != team_drive_start_page_tokens_.end());
- start_page_token = std::make_unique<StartPageToken>(*(it->second));
- }
- ++start_page_token_load_count_;
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_SUCCESS,
- std::move(start_page_token)));
- return CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::DeleteResource(
- const std::string& resource_id,
- const std::string& etag,
- EntryActionCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(callback);
- if (offline_) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), NO_CONNECTION));
- return CancelCallbackOnce();
- }
- EntryInfo* entry = FindEntryByResourceId(resource_id);
- if (!entry) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND));
- return CancelCallbackOnce();
- }
- ChangeResource* change = &entry->change_resource;
- if (change->is_deleted()) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND));
- return CancelCallbackOnce();
- }
- const FileResource* file = change->file();
- if (!etag.empty() && etag != file->etag()) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_PRECONDITION));
- return CancelCallbackOnce();
- }
- if (entry->user_permission != google_apis::drive::PERMISSION_ROLE_OWNER) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_FORBIDDEN));
- return CancelCallbackOnce();
- }
- change->set_deleted(true);
- AddNewChangestamp(change, file->team_drive_id());
- change->set_file(std::unique_ptr<FileResource>());
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_NO_CONTENT));
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(&FakeDriveService::NotifyObservers,
- weak_ptr_factory_.GetWeakPtr()));
- return CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::TrashResource(
- const std::string& resource_id,
- EntryActionCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(callback);
- if (offline_) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), NO_CONNECTION));
- return CancelCallbackOnce();
- }
- EntryInfo* entry = FindEntryByResourceId(resource_id);
- if (!entry) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND));
- return CancelCallbackOnce();
- }
- ChangeResource* change = &entry->change_resource;
- FileResource* file = change->mutable_file();
- if (change->is_deleted() || file->labels().is_trashed()) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND));
- return CancelCallbackOnce();
- }
- if (entry->user_permission != google_apis::drive::PERMISSION_ROLE_OWNER) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_FORBIDDEN));
- return CancelCallbackOnce();
- }
- file->mutable_labels()->set_trashed(true);
- AddNewChangestamp(change, file->team_drive_id());
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_SUCCESS));
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(&FakeDriveService::NotifyObservers,
- weak_ptr_factory_.GetWeakPtr()));
- return CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::DownloadFile(
- const base::FilePath& local_cache_path,
- const std::string& resource_id,
- DownloadActionCallback download_action_callback,
- const GetContentCallback& get_content_callback,
- ProgressCallback progress_callback) {
- base::ThreadRestrictions::ScopedAllowIO allow_io;
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(!download_action_callback.is_null());
- if (offline_) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(download_action_callback),
- NO_CONNECTION, base::FilePath()));
- return CancelCallbackOnce();
- }
- EntryInfo* entry = FindEntryByResourceId(resource_id);
- if (!entry || entry->change_resource.file()->IsHostedDocument()) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(download_action_callback),
- HTTP_NOT_FOUND, base::FilePath()));
- return CancelCallbackOnce();
- }
- const FileResource* file = entry->change_resource.file();
- const std::string& content_data = entry->content_data;
- int64_t file_size = file->file_size();
- DCHECK_EQ(static_cast<size_t>(file_size), content_data.size());
- if (!get_content_callback.is_null()) {
- const int64_t kBlockSize = 5;
- for (int64_t i = 0; i < file_size; i += kBlockSize) {
- const int64_t size = std::min(kBlockSize, file_size - i);
- std::unique_ptr<std::string> content_for_callback(
- new std::string(content_data.substr(i, size)));
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(get_content_callback, HTTP_SUCCESS,
- std::move(content_for_callback), i == 0));
- }
- }
- if (!test_util::WriteStringToFile(local_cache_path, content_data)) {
- // Failed to write the content.
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(download_action_callback),
- DRIVE_FILE_ERROR, base::FilePath()));
- return CancelCallbackOnce();
- }
- if (!progress_callback.is_null()) {
- // See also the comment in ResumeUpload(). For testing that clients
- // can handle the case progress_callback is called multiple times,
- // here we invoke the callback twice.
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(progress_callback, file_size / 2, file_size));
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(progress_callback, file_size, file_size));
- }
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(download_action_callback),
- HTTP_SUCCESS, local_cache_path));
- return google_apis::CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::CopyResource(
- const std::string& resource_id,
- const std::string& in_parent_resource_id,
- const std::string& new_title,
- const base::Time& last_modified,
- FileResourceCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(callback);
- if (offline_) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), NO_CONNECTION,
- std::unique_ptr<FileResource>()));
- return CancelCallbackOnce();
- }
- const std::string& parent_resource_id = in_parent_resource_id.empty()
- ? GetRootResourceId()
- : in_parent_resource_id;
- EntryInfo* entry = FindEntryByResourceId(resource_id);
- if (!entry) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND,
- std::unique_ptr<FileResource>()));
- return CancelCallbackOnce();
- }
- // Make a copy and set the new resource ID and the new title.
- std::unique_ptr<EntryInfo> copied_entry(new EntryInfo);
- copied_entry->content_data = entry->content_data;
- copied_entry->share_url = entry->share_url;
- copied_entry->change_resource.set_type(ChangeResource::FILE);
- copied_entry->change_resource.set_file(
- std::make_unique<FileResource>(*entry->change_resource.file()));
- ChangeResource* new_change = &copied_entry->change_resource;
- FileResource* new_file = new_change->mutable_file();
- const std::string new_resource_id = GetNewResourceId();
- new_change->set_file_id(new_resource_id);
- new_file->set_file_id(new_resource_id);
- new_file->set_title(new_title);
- ParentReference parent;
- parent.set_file_id(parent_resource_id);
- std::vector<ParentReference> parents;
- parents.push_back(parent);
- *new_file->mutable_parents() = parents;
- // Set the team drive for the new entry to the parent.
- if (entries_.count(parent_resource_id) > 0) {
- const ChangeResource& change =
- entries_[parent_resource_id]->change_resource;
- new_file->set_team_drive_id(GetTeamDriveId(change));
- }
- if (!last_modified.is_null()) {
- new_file->set_modified_date(last_modified);
- new_file->set_modified_by_me_date(last_modified);
- } else {
- auto now = base::Time::Now();
- new_file->set_modified_date(now);
- new_file->set_modified_by_me_date(now);
- }
- AddNewChangestamp(new_change, new_file->team_drive_id());
- UpdateETag(new_file);
- // Add the new entry to the map.
- entries_[new_resource_id] = std::move(copied_entry);
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_SUCCESS,
- std::make_unique<FileResource>(*new_file)));
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(&FakeDriveService::NotifyObservers,
- weak_ptr_factory_.GetWeakPtr()));
- return CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::UpdateResource(
- const std::string& resource_id,
- const std::string& parent_resource_id,
- const std::string& new_title,
- const base::Time& last_modified,
- const base::Time& last_viewed_by_me,
- const google_apis::drive::Properties& properties,
- FileResourceCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(callback);
- if (offline_) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), NO_CONNECTION,
- std::unique_ptr<FileResource>()));
- return CancelCallbackOnce();
- }
- EntryInfo* entry = FindEntryByResourceId(resource_id);
- if (!entry) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND,
- std::unique_ptr<FileResource>()));
- return CancelCallbackOnce();
- }
- if (!UserHasWriteAccess(entry->user_permission)) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_FORBIDDEN,
- std::unique_ptr<FileResource>()));
- return CancelCallbackOnce();
- }
- ChangeResource* change = &entry->change_resource;
- FileResource* file = change->mutable_file();
- if (!new_title.empty())
- file->set_title(new_title);
- // Set parent if necessary.
- if (!parent_resource_id.empty()) {
- ParentReference parent;
- parent.set_file_id(parent_resource_id);
- std::vector<ParentReference> parents;
- parents.push_back(parent);
- *file->mutable_parents() = parents;
- }
- if (!last_modified.is_null()) {
- file->set_modified_date(last_modified);
- file->set_modified_by_me_date(last_modified);
- }
- if (!last_viewed_by_me.is_null())
- file->set_last_viewed_by_me_date(last_viewed_by_me);
- AddNewChangestamp(change, file->team_drive_id());
- UpdateETag(file);
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_SUCCESS,
- std::make_unique<FileResource>(*file)));
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(&FakeDriveService::NotifyObservers,
- weak_ptr_factory_.GetWeakPtr()));
- return CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::AddResourceToDirectory(
- const std::string& parent_resource_id,
- const std::string& resource_id,
- EntryActionCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(callback);
- if (offline_) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), NO_CONNECTION));
- return CancelCallbackOnce();
- }
- EntryInfo* entry = FindEntryByResourceId(resource_id);
- if (!entry) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND));
- return CancelCallbackOnce();
- }
- ChangeResource* change = &entry->change_resource;
- // On the real Drive server, resources do not necessary shape a tree
- // structure. That is, each resource can have multiple parent.
- // We mimic the behavior here; AddResourceToDirectoy just adds
- // one more parent, not overwriting old ones.
- ParentReference parent;
- parent.set_file_id(parent_resource_id);
- change->mutable_file()->mutable_parents()->push_back(parent);
- AddNewChangestamp(change, change->file()->team_drive_id());
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_SUCCESS));
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(&FakeDriveService::NotifyObservers,
- weak_ptr_factory_.GetWeakPtr()));
- return CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::RemoveResourceFromDirectory(
- const std::string& parent_resource_id,
- const std::string& resource_id,
- EntryActionCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(callback);
- if (offline_) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), NO_CONNECTION));
- return CancelCallbackOnce();
- }
- EntryInfo* entry = FindEntryByResourceId(resource_id);
- if (!entry) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND));
- return CancelCallbackOnce();
- }
- ChangeResource* change = &entry->change_resource;
- FileResource* file = change->mutable_file();
- std::vector<ParentReference>* parents = file->mutable_parents();
- for (size_t i = 0; i < parents->size(); ++i) {
- if ((*parents)[i].file_id() == parent_resource_id) {
- parents->erase(parents->begin() + i);
- AddNewChangestamp(change, file->team_drive_id());
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_NO_CONTENT));
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(&FakeDriveService::NotifyObservers,
- weak_ptr_factory_.GetWeakPtr()));
- return CancelCallbackOnce();
- }
- }
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND));
- return CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::AddNewDirectory(
- const std::string& parent_resource_id,
- const std::string& directory_title,
- const AddNewDirectoryOptions& options,
- FileResourceCallback callback) {
- return AddNewDirectoryWithResourceId(
- "", parent_resource_id.empty() ? GetRootResourceId() : parent_resource_id,
- directory_title, options, std::move(callback));
- }
- CancelCallbackOnce FakeDriveService::InitiateUploadNewFile(
- const std::string& content_type,
- int64_t content_length,
- const std::string& parent_resource_id,
- const std::string& title,
- const UploadNewFileOptions& options,
- InitiateUploadCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(!callback.is_null());
- if (offline_) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), NO_CONNECTION, GURL()));
- return CancelCallbackOnce();
- }
- if (parent_resource_id != GetRootResourceId() &&
- !entries_.count(parent_resource_id)) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND, GURL()));
- return CancelCallbackOnce();
- }
- GURL session_url = GetNewUploadSessionUrl();
- upload_sessions_[session_url] =
- UploadSession(content_type, content_length, parent_resource_id,
- "", // resource_id
- "", // etag
- title);
- if (title == "never-sync.txt") {
- return CancelCallbackOnce();
- }
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(callback), HTTP_SUCCESS, session_url));
- return CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::InitiateUploadExistingFile(
- const std::string& content_type,
- int64_t content_length,
- const std::string& resource_id,
- const UploadExistingFileOptions& options,
- InitiateUploadCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(!callback.is_null());
- if (offline_) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), NO_CONNECTION, GURL()));
- return CancelCallbackOnce();
- }
- EntryInfo* entry = FindEntryByResourceId(resource_id);
- if (!entry) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND, GURL()));
- return CancelCallbackOnce();
- }
- if (!UserHasWriteAccess(entry->user_permission)) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_FORBIDDEN, GURL()));
- return CancelCallbackOnce();
- }
- FileResource* file = entry->change_resource.mutable_file();
- if (!options.etag.empty() && options.etag != file->etag()) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(callback), HTTP_PRECONDITION, GURL()));
- return CancelCallbackOnce();
- }
- // TODO(hashimoto): Update |file|'s metadata with |options|.
- GURL session_url = GetNewUploadSessionUrl();
- upload_sessions_[session_url] =
- UploadSession(content_type, content_length,
- "", // parent_resource_id
- resource_id, file->etag(), "" /* title */);
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(callback), HTTP_SUCCESS, session_url));
- return CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::GetUploadStatus(
- const GURL& upload_url,
- int64_t content_length,
- UploadRangeCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(callback);
- return CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::ResumeUpload(
- const GURL& upload_url,
- int64_t start_position,
- int64_t end_position,
- int64_t content_length,
- const std::string& content_type,
- const base::FilePath& local_file_path,
- UploadRangeCallback callback,
- ProgressCallback progress_callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(callback);
- FileResourceCallback completion_callback =
- base::BindOnce(&ScheduleUploadRangeCallback, std::move(callback),
- start_position, end_position);
- if (offline_) {
- std::move(completion_callback)
- .Run(NO_CONNECTION, std::unique_ptr<FileResource>());
- return CancelCallbackOnce();
- }
- if (!upload_sessions_.count(upload_url)) {
- std::move(completion_callback)
- .Run(HTTP_NOT_FOUND, std::unique_ptr<FileResource>());
- return CancelCallbackOnce();
- }
- UploadSession* session = &upload_sessions_[upload_url];
- // Chunks are required to be sent in such a ways that they fill from the start
- // of the not-yet-uploaded part with no gaps nor overlaps.
- if (session->uploaded_size != start_position) {
- std::move(completion_callback)
- .Run(HTTP_BAD_REQUEST, std::unique_ptr<FileResource>());
- return CancelCallbackOnce();
- }
- if (!progress_callback.is_null()) {
- // In the real GDataWapi/Drive DriveService, progress is reported in
- // nondeterministic timing. In this fake implementation, we choose to call
- // it twice per one ResumeUpload. This is for making sure that client code
- // works fine even if the callback is invoked more than once; it is the
- // crucial difference of the progress callback from others.
- // Note that progress is notified in the relative offset in each chunk.
- const int64_t chunk_size = end_position - start_position;
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(progress_callback, chunk_size / 2, chunk_size));
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(progress_callback, chunk_size, chunk_size));
- }
- if (content_length != end_position) {
- session->uploaded_size = end_position;
- std::move(completion_callback)
- .Run(HTTP_RESUME_INCOMPLETE, std::unique_ptr<FileResource>());
- return CancelCallbackOnce();
- }
- std::string content_data;
- {
- base::ScopedAllowBlockingForTesting allow_io;
- if (!base::ReadFileToString(local_file_path, &content_data)) {
- session->uploaded_size = end_position;
- std::move(completion_callback)
- .Run(DRIVE_FILE_ERROR, std::unique_ptr<FileResource>());
- return CancelCallbackOnce();
- }
- }
- session->uploaded_size = end_position;
- // |resource_id| is empty if the upload is for new file.
- if (session->resource_id.empty()) {
- DCHECK(!session->parent_resource_id.empty());
- DCHECK(!session->title.empty());
- const EntryInfo* new_entry =
- AddNewEntry("", // auto generate resource id.
- session->content_type, content_data,
- session->parent_resource_id, session->title,
- false); // shared_with_me
- if (!new_entry) {
- std::move(completion_callback)
- .Run(HTTP_NOT_FOUND, std::unique_ptr<FileResource>());
- return CancelCallbackOnce();
- }
- std::move(completion_callback)
- .Run(HTTP_CREATED, std::make_unique<FileResource>(
- *new_entry->change_resource.file()));
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(&FakeDriveService::NotifyObservers,
- weak_ptr_factory_.GetWeakPtr()));
- return CancelCallbackOnce();
- }
- EntryInfo* entry = FindEntryByResourceId(session->resource_id);
- if (!entry) {
- std::move(completion_callback)
- .Run(HTTP_NOT_FOUND, std::unique_ptr<FileResource>());
- return CancelCallbackOnce();
- }
- ChangeResource* change = &entry->change_resource;
- FileResource* file = change->mutable_file();
- if (file->etag().empty() || session->etag != file->etag()) {
- std::move(completion_callback)
- .Run(HTTP_PRECONDITION, std::unique_ptr<FileResource>());
- return CancelCallbackOnce();
- }
- file->set_md5_checksum(base::MD5String(content_data));
- entry->content_data = content_data;
- file->set_file_size(end_position);
- AddNewChangestamp(change, file->team_drive_id());
- UpdateETag(file);
- std::move(completion_callback)
- .Run(HTTP_SUCCESS, std::make_unique<FileResource>(*file));
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(&FakeDriveService::NotifyObservers,
- weak_ptr_factory_.GetWeakPtr()));
- return CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::MultipartUploadNewFile(
- const std::string& content_type,
- int64_t content_length,
- const std::string& parent_resource_id,
- const std::string& title,
- const base::FilePath& local_file_path,
- const UploadNewFileOptions& options,
- FileResourceCallback callback,
- ProgressCallback progress_callback) {
- CallResumeUpload* const call_resume_upload = new CallResumeUpload();
- call_resume_upload->service = weak_ptr_factory_.GetWeakPtr();
- call_resume_upload->content_type = content_type;
- call_resume_upload->content_length = content_length;
- call_resume_upload->local_file_path = local_file_path;
- call_resume_upload->callback = std::move(callback);
- call_resume_upload->progress_callback = progress_callback;
- InitiateUploadNewFile(
- content_type, content_length, parent_resource_id, title, options,
- base::BindOnce(&CallResumeUpload::Run, base::Owned(call_resume_upload)));
- return CancelCallbackOnce();
- }
- CancelCallbackOnce FakeDriveService::MultipartUploadExistingFile(
- const std::string& content_type,
- int64_t content_length,
- const std::string& resource_id,
- const base::FilePath& local_file_path,
- const UploadExistingFileOptions& options,
- FileResourceCallback callback,
- ProgressCallback progress_callback) {
- CallResumeUpload* const call_resume_upload = new CallResumeUpload();
- call_resume_upload->service = weak_ptr_factory_.GetWeakPtr();
- call_resume_upload->content_type = content_type;
- call_resume_upload->content_length = content_length;
- call_resume_upload->local_file_path = local_file_path;
- call_resume_upload->callback = std::move(callback);
- call_resume_upload->progress_callback = progress_callback;
- InitiateUploadExistingFile(
- content_type, content_length, resource_id, options,
- base::BindOnce(&CallResumeUpload::Run, base::Owned(call_resume_upload)));
- return CancelCallbackOnce();
- }
- void FakeDriveService::AddNewFile(const std::string& content_type,
- const std::string& content_data,
- const std::string& parent_resource_id,
- const std::string& title,
- bool shared_with_me,
- FileResourceCallback callback) {
- AddNewFileWithResourceId("", content_type, content_data, parent_resource_id,
- title, shared_with_me, std::move(callback));
- }
- void FakeDriveService::AddNewFileWithResourceId(
- const std::string& resource_id,
- const std::string& content_type,
- const std::string& content_data,
- const std::string& parent_resource_id,
- const std::string& title,
- bool shared_with_me,
- FileResourceCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(callback);
- if (offline_) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), NO_CONNECTION,
- std::unique_ptr<FileResource>()));
- return;
- }
- const EntryInfo* new_entry =
- AddNewEntry(resource_id, content_type, content_data, parent_resource_id,
- title, shared_with_me);
- if (!new_entry) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND,
- std::unique_ptr<FileResource>()));
- return;
- }
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_CREATED,
- std::make_unique<FileResource>(
- *new_entry->change_resource.file())));
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(&FakeDriveService::NotifyObservers,
- weak_ptr_factory_.GetWeakPtr()));
- }
- CancelCallbackOnce FakeDriveService::AddNewDirectoryWithResourceId(
- const std::string& resource_id,
- const std::string& parent_resource_id,
- const std::string& directory_title,
- const AddNewDirectoryOptions& options,
- FileResourceCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(callback);
- if (offline_) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), NO_CONNECTION,
- std::unique_ptr<FileResource>()));
- return CancelCallbackOnce();
- }
- const EntryInfo* new_entry =
- AddNewEntry(resource_id, util::kDriveFolderMimeType,
- "", // content_data
- parent_resource_id, directory_title,
- false); // shared_with_me
- if (!new_entry) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND,
- std::unique_ptr<FileResource>()));
- return CancelCallbackOnce();
- }
- const google_apis::ApiErrorCode result = SetFileVisibility(
- new_entry->change_resource.file_id(), options.visibility);
- DCHECK_EQ(HTTP_SUCCESS, result);
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_CREATED,
- std::make_unique<FileResource>(
- *new_entry->change_resource.file())));
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(&FakeDriveService::NotifyObservers,
- weak_ptr_factory_.GetWeakPtr()));
- return CancelCallbackOnce();
- }
- void FakeDriveService::SetLastModifiedTime(const std::string& resource_id,
- const base::Time& last_modified_time,
- FileResourceCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(callback);
- if (offline_) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), NO_CONNECTION,
- std::unique_ptr<FileResource>()));
- return;
- }
- EntryInfo* entry = FindEntryByResourceId(resource_id);
- if (!entry) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND,
- std::unique_ptr<FileResource>()));
- return;
- }
- ChangeResource* change = &entry->change_resource;
- FileResource* file = change->mutable_file();
- file->set_modified_date(last_modified_time);
- file->set_modified_by_me_date(last_modified_time);
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_SUCCESS,
- std::make_unique<FileResource>(*file)));
- }
- void FakeDriveService::SetFileCapabilities(
- const std::string& resource_id,
- const google_apis::FileResourceCapabilities& capabilities,
- FileResourceCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(callback);
- if (offline_) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), NO_CONNECTION,
- std::unique_ptr<FileResource>()));
- return;
- }
- EntryInfo* entry = FindEntryByResourceId(resource_id);
- if (!entry) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND,
- std::unique_ptr<FileResource>()));
- return;
- }
- ChangeResource& change = entry->change_resource;
- FileResource* file = change.mutable_file();
- file->set_capabilities(capabilities);
- AddNewChangestamp(&change, file->team_drive_id());
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_SUCCESS,
- std::make_unique<FileResource>(*file)));
- }
- bool FakeDriveService::SetTeamDriveCapabilities(
- const std::string& team_drive_id,
- const google_apis::TeamDriveCapabilities& capabilities) {
- DCHECK(thread_checker_.CalledOnValidThread());
- if (offline_) {
- return false;
- }
- EntryInfo* entry = FindEntryByResourceId(team_drive_id);
- if (!entry) {
- return false;
- }
- for (size_t i = 0; i < team_drive_value_.size(); ++i) {
- std::unique_ptr<TeamDriveResource> team_drive(new TeamDriveResource);
- if (team_drive_value_[i]->id() == team_drive_id) {
- team_drive_value_[i]->set_capabilities(capabilities);
- }
- }
- ChangeResource& change = entry->change_resource;
- DCHECK_EQ(ChangeResource::TEAM_DRIVE, change.type());
- TeamDriveResource* team_drive = change.mutable_team_drive();
- team_drive->set_capabilities(capabilities);
- // Changes to Team Drives are added to the default changelist.
- AddNewChangestamp(&change, std::string());
- return true;
- }
- google_apis::ApiErrorCode FakeDriveService::SetUserPermission(
- const std::string& resource_id,
- google_apis::drive::PermissionRole user_permission) {
- DCHECK(thread_checker_.CalledOnValidThread());
- EntryInfo* entry = FindEntryByResourceId(resource_id);
- if (!entry)
- return HTTP_NOT_FOUND;
- entry->user_permission = user_permission;
- return HTTP_SUCCESS;
- }
- google_apis::ApiErrorCode FakeDriveService::SetFileVisibility(
- const std::string& resource_id,
- google_apis::drive::FileVisibility visibility) {
- DCHECK(thread_checker_.CalledOnValidThread());
- EntryInfo* entry = FindEntryByResourceId(resource_id);
- if (!entry)
- return HTTP_NOT_FOUND;
- entry->visibility = visibility;
- return HTTP_SUCCESS;
- }
- google_apis::ApiErrorCode FakeDriveService::GetFileVisibility(
- const std::string& resource_id,
- google_apis::drive::FileVisibility* visibility) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(visibility);
- EntryInfo* entry = FindEntryByResourceId(resource_id);
- if (!entry)
- return HTTP_NOT_FOUND;
- *visibility = entry->visibility;
- return HTTP_SUCCESS;
- }
- google_apis::ApiErrorCode FakeDriveService::SetFileAsSharedWithMe(
- const std::string& resource_id) {
- DCHECK(thread_checker_.CalledOnValidThread());
- EntryInfo* entry = FindEntryByResourceId(resource_id);
- if (!entry)
- return HTTP_NOT_FOUND;
- entry->change_resource.mutable_file()->set_shared_with_me_date(
- base::Time::Now());
- return HTTP_SUCCESS;
- }
- void FakeDriveService::AddChangeObserver(ChangeObserver* change_observer) {
- change_observers_.AddObserver(change_observer);
- }
- void FakeDriveService::RemoveChangeObserver(ChangeObserver* change_observer) {
- change_observers_.RemoveObserver(change_observer);
- }
- FakeDriveService::EntryInfo* FakeDriveService::FindEntryByResourceId(
- const std::string& resource_id) {
- DCHECK(thread_checker_.CalledOnValidThread());
- auto it = entries_.find(resource_id);
- if (it == entries_.end()) {
- return nullptr;
- }
- // Deleted entries don't have FileResource.
- if (it->second->change_resource.type() != ChangeResource::TEAM_DRIVE &&
- !it->second->change_resource.file()) {
- return nullptr;
- }
- return it->second.get();
- }
- std::string FakeDriveService::GetNewResourceId() {
- DCHECK(thread_checker_.CalledOnValidThread());
- ++resource_id_count_;
- return base::StringPrintf("resource_id_%d", resource_id_count_);
- }
- void FakeDriveService::UpdateETag(google_apis::FileResource* file) {
- file->set_etag("etag_" + start_page_token_->start_page_token());
- }
- void FakeDriveService::AddNewChangestamp(google_apis::ChangeResource* change,
- const std::string& team_drive_id) {
- ++largest_changestamp_;
- UpdateLatestChangelistId(largest_changestamp_, team_drive_id);
- change->set_change_id(largest_changestamp_);
- }
- const FakeDriveService::EntryInfo* FakeDriveService::AddNewEntry(
- const std::string& given_resource_id,
- const std::string& content_type,
- const std::string& content_data,
- const std::string& parent_resource_id,
- const std::string& title,
- bool shared_with_me) {
- DCHECK(thread_checker_.CalledOnValidThread());
- if (!parent_resource_id.empty() &&
- parent_resource_id != GetRootResourceId() &&
- !entries_.count(parent_resource_id)) {
- return nullptr;
- }
- // Extract the team drive id from the parent, if there is one.
- std::string team_drive_id;
- if (!parent_resource_id.empty() && entries_.count(parent_resource_id) > 0) {
- const ChangeResource& resource =
- entries_[parent_resource_id]->change_resource;
- team_drive_id = GetTeamDriveId(resource);
- }
- const std::string resource_id =
- given_resource_id.empty() ? GetNewResourceId() : given_resource_id;
- if (entries_.count(resource_id))
- return nullptr;
- GURL upload_url = GURL("https://xxx/upload/" + resource_id);
- std::unique_ptr<EntryInfo> new_entry = std::make_unique<EntryInfo>();
- ChangeResource* new_change = &new_entry->change_resource;
- new_change->set_type(ChangeResource::FILE);
- new_change->set_team_drive_id(team_drive_id);
- FileResource* new_file = new FileResource;
- new_change->set_file(base::WrapUnique(new_file));
- // Set the resource ID and the title
- new_change->set_file_id(resource_id);
- new_file->set_file_id(resource_id);
- new_file->set_title(title);
- // Set the contents, size and MD5 for a file.
- if (content_type != util::kDriveFolderMimeType &&
- !util::IsKnownHostedDocumentMimeType(content_type)) {
- new_entry->content_data = content_data;
- new_file->set_file_size(content_data.size());
- new_file->set_md5_checksum(base::MD5String(content_data));
- }
- if (shared_with_me) {
- // Set current time to mark the file as shared_with_me.
- new_file->set_shared_with_me_date(base::Time::Now());
- }
- std::string escaped_resource_id = base::EscapePath(resource_id);
- // Set mime type.
- new_file->set_mime_type(content_type);
- // Set the team drive id.
- new_file->set_team_drive_id(team_drive_id);
- // Set alternate link.
- if (content_type == util::kGoogleDocumentMimeType) {
- new_file->set_alternate_link(
- GURL("https://document_alternate_link/" + title));
- } else if (content_type == util::kDriveFolderMimeType) {
- new_file->set_alternate_link(
- GURL("https://folder_alternate_link/" + title));
- } else {
- new_file->set_alternate_link(GURL("https://file_alternate_link/" + title));
- }
- // Set parents.
- if (!parent_resource_id.empty()) {
- ParentReference parent;
- parent.set_file_id(parent_resource_id);
- std::vector<ParentReference> parents;
- parents.push_back(parent);
- *new_file->mutable_parents() = parents;
- }
- AddNewChangestamp(new_change, team_drive_id);
- UpdateETag(new_file);
- new_file->set_created_date(base::Time() + base::Milliseconds(++date_seq_));
- new_file->set_modified_by_me_date(base::Time() +
- base::Milliseconds(++date_seq_));
- new_file->set_modified_date(base::Time() + base::Milliseconds(++date_seq_));
- EntryInfo* raw_new_entry = new_entry.get();
- entries_[resource_id] = std::move(new_entry);
- return raw_new_entry;
- }
- const FakeDriveService::EntryInfo* FakeDriveService::AddNewTeamDriveEntry(
- const std::string& team_drive_id,
- const std::string& team_drive_name) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- // Check we do not already have this entry.
- if (entries_.count(team_drive_id) > 0) {
- return nullptr;
- }
- std::unique_ptr<EntryInfo> new_entry = std::make_unique<EntryInfo>();
- ChangeResource& change = new_entry->change_resource;
- change.set_type(ChangeResource::TEAM_DRIVE);
- change.set_team_drive_id(team_drive_id);
- std::unique_ptr<TeamDriveResource> team_drive =
- std::make_unique<TeamDriveResource>();
- team_drive->set_id(team_drive_id);
- team_drive->set_name(team_drive_name);
- change.set_team_drive(std::move(team_drive));
- AddNewChangestamp(&change, std::string());
- change.set_modification_date(base::Time() + base::Milliseconds(++date_seq_));
- EntryInfo* raw_new_entry = new_entry.get();
- entries_[team_drive_id] = std::move(new_entry);
- return raw_new_entry;
- }
- void FakeDriveService::GetChangeListInternal(
- int64_t start_changestamp,
- const std::string& search_query,
- const std::string& directory_resource_id,
- const std::string& team_drive_id,
- int start_offset,
- int max_results,
- int* load_counter,
- ChangeListOnceCallback callback) {
- if (offline_) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), NO_CONNECTION,
- std::unique_ptr<ChangeList>()));
- return;
- }
- // Filter out entries per parameters like |directory_resource_id| and
- // |search_query|.
- std::vector<std::unique_ptr<ChangeResource>> entries;
- int num_entries_matched = 0;
- for (auto it = entries_.begin(); it != entries_.end(); ++it) {
- const ChangeResource& entry = it->second->change_resource;
- bool should_exclude = false;
- // If |directory_resource_id| is set, exclude the entry if it's not in
- // the target directory.
- if (!directory_resource_id.empty()) {
- // Get the parent resource ID of the entry.
- std::string parent_resource_id;
- if (entry.type() == ChangeResource::FILE && entry.file() &&
- !entry.file()->parents().empty())
- parent_resource_id = entry.file()->parents()[0].file_id();
- if (directory_resource_id != parent_resource_id)
- should_exclude = true;
- }
- // If |search_query| is set, exclude the entry if it does not contain the
- // search query in the title.
- if (!should_exclude && !search_query.empty() &&
- !EntryMatchWithQuery(entry, search_query)) {
- should_exclude = true;
- }
- // If the team drive does not match, then exclude the entry.
- switch (entry.type()) {
- case ChangeResource::FILE:
- if (entry.file() && entry.file()->team_drive_id() != team_drive_id) {
- should_exclude = true;
- }
- break;
- case ChangeResource::TEAM_DRIVE:
- // Only include TeamDrive change resources in the default change list.
- if (!team_drive_id.empty()) {
- should_exclude = true;
- }
- break;
- case ChangeResource::UNKNOWN:
- NOTREACHED();
- break;
- }
- // If |start_changestamp| is set, exclude the entry if the
- // changestamp is older than |largest_changestamp|.
- // See https://developers.google.com/google-apps/documents-list/
- // #retrieving_all_changes_since_a_given_changestamp
- if (start_changestamp > 0 && entry.change_id() < start_changestamp)
- should_exclude = true;
- // If the caller requests other list than change list by specifying
- // zero-|start_changestamp|, exclude deleted entry from the result.
- const bool deleted = entry.is_deleted() ||
- (entry.type() == ChangeResource::FILE &&
- entry.file() && entry.file()->labels().is_trashed());
- if (!start_changestamp && deleted)
- should_exclude = true;
- // The entry matched the criteria for inclusion.
- if (!should_exclude)
- ++num_entries_matched;
- // If |start_offset| is set, exclude the entry if the entry is before the
- // start index. <= instead of < as |num_entries_matched| was
- // already incremented.
- if (start_offset > 0 && num_entries_matched <= start_offset)
- should_exclude = true;
- if (!should_exclude) {
- std::unique_ptr<ChangeResource> entry_copied(new ChangeResource);
- entry_copied->set_type(entry.type());
- entry_copied->set_change_id(entry.change_id());
- entry_copied->set_deleted(entry.is_deleted());
- if (entry.type() == ChangeResource::FILE) {
- entry_copied->set_file_id(entry.file_id());
- if (entry.file()) {
- entry_copied->set_file(std::make_unique<FileResource>(*entry.file()));
- }
- }
- if (entry.type() == ChangeResource::TEAM_DRIVE && entry.team_drive()) {
- entry_copied->set_team_drive(
- std::make_unique<TeamDriveResource>(*entry.team_drive()));
- }
- entry_copied->set_modification_date(entry.modification_date());
- entries.push_back(std::move(entry_copied));
- }
- }
- std::unique_ptr<ChangeList> change_list(new ChangeList);
- if (start_changestamp > 0 && start_offset == 0) {
- auto largest_change_id = about_resource_->largest_change_id();
- change_list->set_largest_change_id(largest_change_id);
- change_list->set_new_start_page_token(
- drive::util::ConvertChangestampToStartPageToken(largest_change_id));
- }
- // If |max_results| is set, trim the entries if the number exceeded the max
- // results.
- if (max_results > 0 && entries.size() > static_cast<size_t>(max_results)) {
- entries.erase(entries.begin() + max_results, entries.end());
- // Adds the next URL.
- // Here, we embed information which is needed for continuing the
- // GetChangeList request in the next invocation into url query
- // parameters.
- GURL next_url(
- base::StringPrintf("http://localhost/?start-offset=%d&max-results=%d",
- start_offset + max_results, max_results));
- if (start_changestamp > 0) {
- next_url = net::AppendOrReplaceQueryParameter(
- next_url, "changestamp", base::NumberToString(start_changestamp));
- }
- if (!search_query.empty()) {
- next_url =
- net::AppendOrReplaceQueryParameter(next_url, "q", search_query);
- }
- if (!directory_resource_id.empty()) {
- next_url = net::AppendOrReplaceQueryParameter(next_url, "parent",
- directory_resource_id);
- }
- if (!team_drive_id.empty()) {
- next_url = net::AppendOrReplaceQueryParameter(next_url, "team-drive-id",
- team_drive_id);
- }
- change_list->set_next_link(next_url);
- }
- *change_list->mutable_items() = std::move(entries);
- if (load_counter)
- *load_counter += 1;
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), HTTP_SUCCESS,
- std::move(change_list)));
- }
- GURL FakeDriveService::GetNewUploadSessionUrl() {
- return GURL("https://upload_session_url/" +
- base::NumberToString(next_upload_sequence_number_++));
- }
- CancelCallbackOnce FakeDriveService::AddPermission(
- const std::string& resource_id,
- const std::string& email,
- google_apis::drive::PermissionRole role,
- google_apis::EntryActionCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(callback);
- NOTREACHED();
- return CancelCallbackOnce();
- }
- std::unique_ptr<BatchRequestConfiguratorInterface>
- FakeDriveService::StartBatchRequest() {
- DCHECK(thread_checker_.CalledOnValidThread());
- NOTREACHED();
- return nullptr;
- }
- void FakeDriveService::NotifyObservers() {
- for (auto& observer : change_observers_)
- observer.OnNewChangeAvailable();
- }
- void FakeDriveService::UpdateLatestChangelistId(
- int64_t change_list_id,
- const std::string& team_drive_id) {
- if (team_drive_id.empty()) {
- about_resource_->set_largest_change_id(change_list_id);
- start_page_token_->set_start_page_token(
- drive::util::ConvertChangestampToStartPageToken(change_list_id));
- } else {
- DCHECK_GT(team_drive_start_page_tokens_.count(team_drive_id), 0UL);
- team_drive_start_page_tokens_[team_drive_id]->set_start_page_token(
- drive::util::ConvertChangestampToStartPageToken(change_list_id));
- }
- }
- } // namespace drive
|