12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/drive/fake_drive_service.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/file_util.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/md5.h" 129ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_tokenizer.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/google_apis/drive_api_parser.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/google_apis/gdata_wapi_parser.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/google_apis/test_util.h" 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/google_apis/time_util.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/escape.h" 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/base/url_util.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::BrowserThread; 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::AboutResource; 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::AccountMetadata; 30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::AppList; 317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing google_apis::AuthStatusCallback; 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::AuthorizeAppCallback; 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::CancelCallback; 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::DownloadActionCallback; 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::EntryActionCallback; 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDataErrorCode; 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_FILE_ERROR; 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_NO_CONNECTION; 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_OTHER_ERROR; 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetAboutResourceCallback; 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetAppListCallback; 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetContentCallback; 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetResourceEntryCallback; 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetResourceListCallback; 45bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochusing google_apis::GetShareUrlCallback; 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_BAD_REQUEST; 47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_CREATED; 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_NOT_FOUND; 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_PRECONDITION; 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_RESUME_INCOMPLETE; 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_SUCCESS; 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::InitiateUploadCallback; 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::Link; 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ProgressCallback; 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ResourceEntry; 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ResourceList; 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::UploadRangeCallback; 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::UploadRangeResponse; 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace test_util = google_apis::test_util; 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace util = google_apis::util; 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace drive { 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 652385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Rel property of an upload link in the entries dictionary value. 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kUploadUrlRel[] = 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "http://schemas.google.com/g/2005#resumable-create-media"; 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Rel property of a share link in the entries dictionary value. 702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kShareUrlRel[] = 712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch "http://schemas.google.com/docs/2007#share"; 722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns true if a resource entry matches with the search query. 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Supports queries consist of following format. 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Phrases quoted by double/single quotes 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - AND search for multiple words/phrases segmented by space 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Limited attribute search. Only "title:" is supported. 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool EntryMatchWithQuery(const ResourceEntry& entry, 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& query) { 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringTokenizer tokenizer(query, " "); 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tokenizer.set_quote_chars("\"'"); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (tokenizer.GetNext()) { 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string key, value; 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& token = tokenizer.token(); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (token.find(':') == std::string::npos) { 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TrimString(token, "\"'", &value); 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringTokenizer key_value(token, ":"); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key_value.set_quote_chars("\"'"); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!key_value.GetNext()) 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key = key_value.token(); 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!key_value.GetNext()) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TrimString(key_value.token(), "\"'", &value); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(peria): Deal with other attributes than title. 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!key.empty() && key != "title") 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Search query in the title. 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry.title().find(value) == std::string::npos) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Returns |url| without query parameter. 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)GURL RemoveQueryParameter(const GURL& url) { 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GURL::Replacements replacements; 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) replacements.ClearQuery(); 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return url.ReplaceComponents(replacements); 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ScheduleUploadRangeCallback(const UploadRangeCallback& callback, 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 start_position, 117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 end_position, 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GDataErrorCode error, 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<ResourceEntry> entry) { 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::MessageLoop::current()->PostTask( 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FROM_HERE, 122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(callback, 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UploadRangeResponse(error, 124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch start_position, 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch end_position), 126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Passed(&entry))); 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstruct FakeDriveService::UploadSession { 132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string content_type; 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 content_length; 134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string parent_resource_id; 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string resource_id; 136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string etag; 137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string title; 138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 uploaded_size; 140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UploadSession() 142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : content_length(0), 143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uploaded_size(0) {} 144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UploadSession( 146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string content_type, 147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 content_length, 148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string parent_resource_id, 149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string resource_id, 150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string etag, 151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string title) 152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : content_type(content_type), 153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch content_length(content_length), 154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch parent_resource_id(parent_resource_id), 155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch resource_id(resource_id), 156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch etag(etag), 157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch title(title), 158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uploaded_size(0) { 159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FakeDriveService::FakeDriveService() 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : largest_changestamp_(0), 1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) published_date_seq_(0), 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch next_upload_sequence_number_(0), 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default_max_results_(0), 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_id_count_(0), 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_list_load_count_(0), 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) change_list_load_count_(0), 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) directory_load_count_(0), 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) about_resource_load_count_(0), 1722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch app_list_load_count_(0), 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) offline_(false) { 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FakeDriveService::~FakeDriveService() { 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FakeDriveService::LoadResourceListForWapi( 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& relative_path) { 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Value> raw_value = test_util::LoadJSONFile(relative_path); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* as_dict = NULL; 1863240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch scoped_ptr<base::Value> feed; 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* feed_as_dict = NULL; 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Extract the "feed" from the raw value and take the ownership. 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note that Remove() transfers the ownership to |feed|. 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (raw_value->GetAsDictionary(&as_dict) && 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) as_dict->Remove("feed", &feed) && 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) feed->GetAsDictionary(&feed_as_dict)) { 1943240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch ignore_result(feed.release()); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_list_value_.reset(feed_as_dict); 19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Go through entries and convert test$data from a string to a binary blob. 19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::ListValue* entries = NULL; 19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (feed_as_dict->GetList("entry", &entries)) { 20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::DictionaryValue* entry = NULL; 20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string content_data; 20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (entries->GetDictionary(i, &entry) && 20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entry->GetString("test$data", &content_data)) { 2053240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch entry->Set("test$data", 2063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch base::BinaryValue::CreateWithCopiedBuffer( 2073240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch content_data.c_str(), content_data.size())); 20890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return resource_list_value_; 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FakeDriveService::LoadAccountMetadataForWapi( 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& relative_path) { 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2194311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch 2204311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch // Load JSON data, which must be a dictionary. 2214311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch scoped_ptr<base::Value> value = test_util::LoadJSONFile(relative_path); 2224311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch CHECK_EQ(base::Value::TYPE_DICTIONARY, value->GetType()); 2234311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch account_metadata_value_.reset( 2244311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch static_cast<base::DictionaryValue*>(value.release())); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Update the largest_changestamp_. 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AccountMetadata> account_metadata = 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AccountMetadata::CreateFrom(*account_metadata_value_); 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) largest_changestamp_ = account_metadata->largest_changestamp(); 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Add the largest changestamp to the existing entries. 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This will be used to generate change lists in GetResourceList(). 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (resource_list_value_) { 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* entries = NULL; 235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) { 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = NULL; 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entries->GetDictionary(i, &entry)) { 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->SetString("docs$changestamp.value", 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Int64ToString(largest_changestamp_)); 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return account_metadata_value_; 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FakeDriveService::LoadAppListForDriveApi( 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& relative_path) { 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app_info_value_ = test_util::LoadJSONFile(relative_path); 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return app_info_value_; 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2554311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch 2564311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdochvoid FakeDriveService::SetQuotaValue(int64 used, int64 total) { 2574311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2584311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch DCHECK(account_metadata_value_); 2594311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch 2604311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch account_metadata_value_->SetString("entry.gd$quotaBytesUsed.$t", 2614311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch base::Int64ToString16(used)); 2624311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch account_metadata_value_->SetString("entry.gd$quotaBytesTotal.$t", 2634311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch base::Int64ToString16(total)); 2644311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch} 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GURL FakeDriveService::GetFakeLinkUrl(const std::string& resource_id) { 267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return GURL("https://fake_server/" + net::EscapePath(resource_id)); 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 270558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid FakeDriveService::Initialize() { 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FakeDriveService::AddObserver(DriveServiceObserver* observer) { 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FakeDriveService::RemoveObserver(DriveServiceObserver* observer) { 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool FakeDriveService::CanSendRequest() const { 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string FakeDriveService::CanonicalizeResourceId( 28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& resource_id) const { 28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return resource_id; 29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 29190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FakeDriveService::HasAccessToken() const { 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FakeDriveService::RequestAccessToken(const AuthStatusCallback& callback) { 2987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(!callback.is_null()); 3007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch callback.Run(google_apis::HTTP_NOT_MODIFIED, "fake_access_token"); 3017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 3027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FakeDriveService::HasRefreshToken() const { 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FakeDriveService::ClearAccessToken() { 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FakeDriveService::ClearRefreshToken() { 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string FakeDriveService::GetRootResourceId() const { 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "fake_root"; 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetAllResourceList( 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetResourceListCallback& callback) { 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetResourceListInternal(0, // start changestamp 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // empty search query 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // no directory resource id, 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, // start offset 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default_max_results_, 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &resource_list_load_count_, 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 3327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetResourceListInDirectory( 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& directory_resource_id, 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetResourceListCallback& callback) { 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!directory_resource_id.empty()); 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetResourceListInternal(0, // start changestamp 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // empty search query 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) directory_resource_id, 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, // start offset 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default_max_results_, 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &directory_load_count_, 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 3497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::Search( 3537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& search_query, 3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const GetResourceListCallback& callback) { 355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!search_query.empty()); 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetResourceListInternal(0, // start changestamp 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) search_query, 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // no directory resource id, 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, // start offset 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default_max_results_, 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NULL, 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 3667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::SearchByTitle( 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& title, 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& directory_resource_id, 372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetResourceListCallback& callback) { 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!title.empty()); 375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Note: the search implementation here doesn't support quotation unescape, 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // so don't escape here. 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetResourceListInternal(0, // start changestamp 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::StringPrintf("title:'%s'", title.c_str()), 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) directory_resource_id, 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, // start offset 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default_max_results_, 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NULL, 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 3867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetChangeList( 3907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int64 start_changestamp, 3917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const GetResourceListCallback& callback) { 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetResourceListInternal(start_changestamp, 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // empty search query 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // no directory resource id, 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, // start offset 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default_max_results_, 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &change_list_load_count_, 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 4027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::ContinueGetResourceList( 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GURL& override_url, 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetResourceListCallback& callback) { 408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!override_url.is_empty()); 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // "changestamp", "q", "parent" and "start-offset" are parameters to 413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // implement "paging" of the result on FakeDriveService. 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The URL should be the one filled in GetResourceListInternal of the 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // previous method invocation, so it should start with "http://localhost/?". 416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // See also GetResourceListInternal. 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(override_url.host(), "localhost"); 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(override_url.path(), "/"); 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 start_changestamp = 0; 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string search_query; 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string directory_resource_id; 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int start_offset = 0; 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int max_results = default_max_results_; 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::pair<std::string, std::string> > parameters; 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (base::SplitStringIntoKeyValuePairs( 427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) override_url.query(), '=', '&', ¶meters)) { 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < parameters.size(); ++i) { 429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (parameters[i].first == "changestamp") { 430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::StringToInt64(parameters[i].second, &start_changestamp); 431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (parameters[i].first == "q") { 432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) search_query = 433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::UnescapeURLComponent(parameters[i].second, 434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::UnescapeRule::URL_SPECIAL_CHARS); 435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (parameters[i].first == "parent") { 436868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) directory_resource_id = 437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::UnescapeURLComponent(parameters[i].second, 438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::UnescapeRule::URL_SPECIAL_CHARS); 439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (parameters[i].first == "start-offset") { 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringToInt(parameters[i].second, &start_offset); 441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (parameters[i].first == "max-results") { 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringToInt(parameters[i].second, &max_results); 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetResourceListInternal( 448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) start_changestamp, search_query, directory_resource_id, 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) start_offset, max_results, NULL, callback); 4507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetResourceEntry( 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetResourceEntryCallback& callback) { 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 46190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&null))); 4667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry) { 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> resource_entry = 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResourceEntry::CreateFrom(*entry); 47390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_SUCCESS, base::Passed(&resource_entry))); 4767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 48090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, base::Passed(&null))); 4837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 486bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochCancelCallback FakeDriveService::GetShareUrl( 487bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const std::string& resource_id, 488bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const GURL& /* embed_origin */, 489bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const GetShareUrlCallback& callback) { 490bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 491bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DCHECK(!callback.is_null()); 492bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 493bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (offline_) { 494bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch scoped_ptr<ResourceEntry> null; 495bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::MessageLoop::current()->PostTask( 496bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch FROM_HERE, 497bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::Bind(callback, 498bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch GDATA_NO_CONNECTION, 499bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch GURL())); 500bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch return CancelCallback(); 501bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 502bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 503bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 504bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (entry) { 505bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Share urls are stored in the resource entry, and they do not rely on the 506bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // embedding origin. 507bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch scoped_ptr<ResourceEntry> resource_entry = 508bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch ResourceEntry::CreateFrom(*entry); 509bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const Link* share_url = resource_entry->GetLinkByType(Link::LINK_SHARE); 510bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (share_url) { 511bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::MessageLoop::current()->PostTask( 512bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch FROM_HERE, 513bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::Bind(callback, HTTP_SUCCESS, share_url->href())); 514bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } else { 515bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::MessageLoop::current()->PostTask( 516bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch FROM_HERE, 517bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::Bind(callback, HTTP_SUCCESS, GURL())); 518bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 519bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch return CancelCallback(); 520bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 521bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 522bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch scoped_ptr<ResourceEntry> null; 523bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::MessageLoop::current()->PostTask( 524bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch FROM_HERE, 525bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::Bind(callback, HTTP_NOT_FOUND, GURL())); 526bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch return CancelCallback(); 527bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 528bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 5297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetAboutResource( 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetAboutResourceCallback& callback) { 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AboutResource> null; 53990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, base::Passed(&null))); 5437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++about_resource_load_count_; 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AboutResource> about_resource( 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AboutResource::CreateFromAccountMetadata( 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *AccountMetadata::CreateFrom(*account_metadata_value_), 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRootResourceId())); 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Overwrite the change id. 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) about_resource->set_largest_change_id(largest_changestamp_); 55390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HTTP_SUCCESS, base::Passed(&about_resource))); 5577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetAppList( 5617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const GetAppListCallback& callback) { 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 56490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(app_info_value_); 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AppList> null; 56890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&null))); 5737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch ++app_list_load_count_; 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AppList> app_list(AppList::CreateFrom(*app_info_value_)); 57890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_SUCCESS, base::Passed(&app_list))); 5817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::DeleteResource( 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& etag, 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const EntryActionCallback& callback) { 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 59290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, GDATA_NO_CONNECTION)); 5947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* entries = NULL; 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Go through entries and remove the one that matches |resource_id|. 599868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) { 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = NULL; 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string current_resource_id; 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entries->GetDictionary(i, &entry) && 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("gd$resourceId.$t", ¤t_resource_id) && 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_id == current_resource_id) { 606eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 607eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (entry->HasKey("gd$deleted")) { 608eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch error = HTTP_NOT_FOUND; 609eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 610eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry->Set("gd$deleted", new DictionaryValue); 611eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddNewChangestampAndETag(entry); 612eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch error = HTTP_SUCCESS; 613eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 61490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 615eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FROM_HERE, base::Bind(callback, error)); 6167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 62190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND)); 6237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::DownloadFile( 6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& local_cache_path, 628eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& resource_id, 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DownloadActionCallback& download_action_callback, 630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetContentCallback& get_content_callback, 631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ProgressCallback& progress_callback) { 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!download_action_callback.is_null()); 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 63690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(download_action_callback, 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath())); 6417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The field content.src is the URL to download the file. 645eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!entry) { 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(download_action_callback, HTTP_NOT_FOUND, base::FilePath())); 6507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Write "x"s of the file size specified in the entry. 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string file_size_string; 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("docs$size.$t", &file_size_string); 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 file_size = 0; 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (base::StringToInt64(file_size_string, &file_size)) { 65890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::BinaryValue* content_binary_data; 65990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string content_data; 66090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (entry->GetBinary("test$data", &content_binary_data)) { 66190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content_data = std::string(content_binary_data->GetBuffer(), 66290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content_binary_data->GetSize()); 66390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 66490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_EQ(static_cast<size_t>(file_size), content_data.size()); 6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!get_content_callback.is_null()) { 667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int64 kBlockSize = 5; 668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (int64 i = 0; i < file_size; i += kBlockSize) { 669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int64 size = std::min(kBlockSize, file_size - i); 670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<std::string> content_for_callback( 67190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new std::string(content_data.substr(i, size))); 672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(get_content_callback, HTTP_SUCCESS, 675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&content_for_callback))); 676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 67990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (test_util::WriteStringToFile(local_cache_path, content_data)) { 680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!progress_callback.is_null()) { 681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // See also the comment in ResumeUpload(). For testing that clients 682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // can handle the case progress_callback is called multiple times, 683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // here we invoke the callback twice. 684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(progress_callback, file_size / 2, file_size)); 687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(progress_callback, file_size, file_size)); 690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(download_action_callback, 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HTTP_SUCCESS, 6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_cache_path)); 6967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Failed to write the content. 7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(download_action_callback, GDATA_FILE_ERROR, base::FilePath())); 7047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::CopyResource( 7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 70990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& in_parent_resource_id, 7107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& new_title, 7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetResourceEntryCallback& callback) { 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 71790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&null))); 7227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& parent_resource_id = in_parent_resource_id.empty() ? 72690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetRootResourceId() : in_parent_resource_id; 72790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* entries = NULL; 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Go through entries and copy the one that matches |resource_id|. 730868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) { 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = NULL; 7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string current_resource_id; 7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entries->GetDictionary(i, &entry) && 7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("gd$resourceId.$t", ¤t_resource_id) && 73690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) resource_id == current_resource_id) { 73790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Make a copy and set the new resource ID and the new title. 73890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<DictionaryValue> copied_entry(entry->DeepCopy()); 73990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) copied_entry->SetString("gd$resourceId.$t", 74090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) resource_id + "_copied"); 7417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch copied_entry->SetString("title.$t", new_title); 74290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 74390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Reset parent directory. 74490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::ListValue* links = NULL; 74590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!entry->GetList("link", &links)) { 74690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) links = new base::ListValue; 74790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entry->Set("link", links); 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 74990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) links->Clear(); 75090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 75190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::DictionaryValue* link = new base::DictionaryValue; 75290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) link->SetString( 75390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "rel", "http://schemas.google.com/docs/2007#parent"); 75490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) link->SetString("href", GetFakeLinkUrl(parent_resource_id).spec()); 75590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) links->Append(link); 75690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 757eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddNewChangestampAndETag(copied_entry.get()); 75890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 75990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Parse the new entry. 76090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<ResourceEntry> resource_entry = 76190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ResourceEntry::CreateFrom(*copied_entry); 76290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Add it to the resource list. 76390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entries->Append(copied_entry.release()); 76490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 76590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 76690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, 76790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(callback, 76890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) HTTP_SUCCESS, 76990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Passed(&resource_entry))); 7707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 77690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, base::Passed(&null))); 7797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::CopyHostedDocument( 78390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& resource_id, 7847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& new_title, 78590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const GetResourceEntryCallback& callback) { 78690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 78790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!callback.is_null()); 78890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return CopyResource(resource_id, std::string(), new_title, callback); 79090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 79190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::RenameResource( 7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 7947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& new_title, 7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const EntryActionCallback& callback) { 7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 80090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, GDATA_NO_CONNECTION)); 8027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry) { 8077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch entry->SetString("title.$t", new_title); 808eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddNewChangestampAndETag(entry); 80990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_SUCCESS)); 8117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 81490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND)); 8167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::TouchResource( 82090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& resource_id, 82190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::Time& modified_date, 82290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::Time& last_viewed_by_me_date, 82390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const GetResourceEntryCallback& callback) { 82490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 82590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!modified_date.is_null()); 82690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!last_viewed_by_me_date.is_null()); 82790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!callback.is_null()); 82890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 82990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (offline_) { 83090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 83190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, 83290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(callback, GDATA_NO_CONNECTION, 83390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Passed(scoped_ptr<ResourceEntry>()))); 8347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 83590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 83690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 83790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 83890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!entry) { 83990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 84090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, 84190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, 84290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Passed(scoped_ptr<ResourceEntry>()))); 8437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 84490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 84590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 84690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entry->SetString("updated.$t", 84790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) util::FormatTimeAsString(modified_date)); 84890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entry->SetString("gd$lastViewed.$t", 84990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) util::FormatTimeAsString(last_viewed_by_me_date)); 850eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddNewChangestampAndETag(entry); 85190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 85290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<ResourceEntry> parsed_entry(ResourceEntry::CreateFrom(*entry)); 85390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 85490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, 85590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(callback, HTTP_SUCCESS, base::Passed(&parsed_entry))); 8567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 85790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 85890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::AddResourceToDirectory( 8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& parent_resource_id, 8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const EntryActionCallback& callback) { 8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 86790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, GDATA_NO_CONNECTION)); 8697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry) { 8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* links = NULL; 8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!entry->GetList("link", &links)) { 8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) links = new base::ListValue; 8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->Set("link", links); 8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // On the real Drive server, resources do not necessary shape a tree 8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // structure. That is, each resource can have multiple parent. 8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We mimic the behavior here; AddResourceToDirectoy just adds 8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // one more parent link, not overwriting old links. 8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* link = new base::DictionaryValue; 8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) link->SetString("rel", "http://schemas.google.com/docs/2007#parent"); 8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) link->SetString( 8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "href", GetFakeLinkUrl(parent_resource_id).spec()); 8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) links->Append(link); 8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 890eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddNewChangestampAndETag(entry); 89190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_SUCCESS)); 8937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 89690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND)); 8987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::RemoveResourceFromDirectory( 9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& parent_resource_id, 9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const EntryActionCallback& callback) { 9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 90990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, GDATA_NO_CONNECTION)); 9117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry) { 9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* links = NULL; 9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry->GetList("link", &links)) { 9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL parent_content_url = GetFakeLinkUrl(parent_resource_id); 9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < links->GetSize(); ++i) { 9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* link = NULL; 9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string rel; 9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string href; 9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (links->GetDictionary(i, &link) && 9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) link->GetString("rel", &rel) && 9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) link->GetString("href", &href) && 9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rel == "http://schemas.google.com/docs/2007#parent" && 9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL(href) == parent_content_url) { 9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) links->Remove(i, NULL); 929eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddNewChangestampAndETag(entry); 93090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_SUCCESS)); 9327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 93890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND)); 9407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::AddNewDirectory( 9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& parent_resource_id, 9457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& directory_title, 9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetResourceEntryCallback& callback) { 9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 95290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, 9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&null))); 9577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 960c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char kContentType[] = "application/atom+xml;type=feed"; 961c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::DictionaryValue* new_entry = AddNewEntry(kContentType, 96290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "", // content_data 963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parent_resource_id, 9647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch directory_title, 965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) false, // shared_with_me 966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "folder"); 967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!new_entry) { 968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 96990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 971c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, base::Passed(&null))); 9727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> parsed_entry(ResourceEntry::CreateFrom(*new_entry)); 97690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 978c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_CREATED, base::Passed(&parsed_entry))); 9797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::InitiateUploadNewFile( 9832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& content_type, 9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 content_length, 9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& parent_resource_id, 9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& title, 9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const InitiateUploadCallback& callback) { 9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 99290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, GDATA_NO_CONNECTION, GURL())); 9957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 998eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (parent_resource_id != GetRootResourceId() && 999eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch !FindEntryByResourceId(parent_resource_id)) { 100090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 10022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, GURL())); 10037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1005eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1006eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL session_url = GetNewUploadSessionUrl(); 1007eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch upload_sessions_[session_url] = 1008eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UploadSession(content_type, content_length, 1009eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch parent_resource_id, 1010eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "", // resource_id 1011eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "", // etag 1012eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch title); 10132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 101490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 10152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 1016eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(callback, HTTP_SUCCESS, session_url)); 10177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::InitiateUploadExistingFile( 10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& content_type, 10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 content_length, 10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& etag, 10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const InitiateUploadCallback& callback) { 10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 103090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, GDATA_NO_CONNECTION, GURL())); 10337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DictionaryValue* entry = FindEntryByResourceId(resource_id); 10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!entry) { 103890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, GURL())); 10417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string entry_etag; 10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("gd$etag", &entry_etag); 1046c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!etag.empty() && etag != entry_etag) { 104790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_PRECONDITION, GURL())); 10507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1053eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL session_url = GetNewUploadSessionUrl(); 1054eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch upload_sessions_[session_url] = 1055eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UploadSession(content_type, content_length, 1056eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "", // parent_resource_id 1057eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch resource_id, 1058eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry_etag, 1059eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "" /* title */); 10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 106190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 1063eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(callback, HTTP_SUCCESS, session_url)); 10647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetUploadStatus( 10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& upload_url, 10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 content_length, 10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const UploadRangeCallback& callback) { 10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 10737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::ResumeUpload( 10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& upload_url, 10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 start_position, 10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 end_position, 10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 content_length, 10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& content_type, 1082a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const base::FilePath& local_file_path, 1083c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const UploadRangeCallback& callback, 1084c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ProgressCallback& progress_callback) { 10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1088eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GetResourceEntryCallback completion_callback 1089eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch = base::Bind(&ScheduleUploadRangeCallback, 1090eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback, start_position, end_position); 10912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 1093eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(GDATA_NO_CONNECTION, scoped_ptr<ResourceEntry>()); 10947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1097eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!upload_sessions_.count(upload_url)) { 1098eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_NOT_FOUND, scoped_ptr<ResourceEntry>()); 10997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UploadSession* session = &upload_sessions_[upload_url]; 1103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Chunks are required to be sent in such a ways that they fill from the start 1105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // of the not-yet-uploaded part with no gaps nor overlaps. 1106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (session->uploaded_size != start_position) { 1107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_BAD_REQUEST, scoped_ptr<ResourceEntry>()); 11087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 1109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!progress_callback.is_null()) { 1112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // In the real GDataWapi/Drive DriveService, progress is reported in 1113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // nondeterministic timing. In this fake implementation, we choose to call 1114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // it twice per one ResumeUpload. This is for making sure that client code 1115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // works fine even if the callback is invoked more than once; it is the 1116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // crucial difference of the progress callback from others. 1117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Note that progress is notified in the relative offset in each chunk. 1118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int64 chunk_size = end_position - start_position; 111990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, base::Bind(progress_callback, chunk_size / 2, chunk_size)); 112190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, base::Bind(progress_callback, chunk_size, chunk_size)); 1123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 11252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (content_length != end_position) { 1126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->uploaded_size = end_position; 1127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_RESUME_INCOMPLETE, 1128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<ResourceEntry>()); 11297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string content_data; 1133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!file_util::ReadFileToString(local_file_path, &content_data)) { 1134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->uploaded_size = end_position; 1135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(GDATA_FILE_ERROR, scoped_ptr<ResourceEntry>()); 1136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return CancelCallback(); 1137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->uploaded_size = end_position; 1139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // |resource_id| is empty if the upload is for new file. 1141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (session->resource_id.empty()) { 1142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(!session->parent_resource_id.empty()); 1143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(!session->title.empty()); 1144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const DictionaryValue* new_entry = AddNewEntry( 1145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->content_type, 1146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch content_data, 1147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->parent_resource_id, 1148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->title, 1149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch false, // shared_with_me 1150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "file"); 1151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!new_entry) { 1152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_NOT_FOUND, scoped_ptr<ResourceEntry>()); 1153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return CancelCallback(); 1154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_CREATED, 1157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ResourceEntry::CreateFrom(*new_entry)); 1158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return CancelCallback(); 1159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DictionaryValue* entry = FindEntryByResourceId(session->resource_id); 1162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!entry) { 1163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_NOT_FOUND, scoped_ptr<ResourceEntry>()); 1164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return CancelCallback(); 1165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 116690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string entry_etag; 1168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry->GetString("gd$etag", &entry_etag); 1169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (entry_etag.empty() || session->etag != entry_etag) { 1170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_PRECONDITION, scoped_ptr<ResourceEntry>()); 1171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return CancelCallback(); 1172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 11732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry->SetString("docs$md5Checksum.$t", base::MD5String(content_data)); 1175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry->Set("test$data", 1176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::BinaryValue::CreateWithCopiedBuffer( 1177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch content_data.data(), content_data.size())); 1178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry->SetString("docs$size.$t", base::Int64ToString(end_position)); 1179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddNewChangestampAndETag(entry); 1180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_SUCCESS, ResourceEntry::CreateFrom(*entry)); 11827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 11832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::AuthorizeApp( 11867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& resource_id, 11877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& app_id, 11887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const AuthorizeAppCallback& callback) { 11892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 11902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 11917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 11932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void FakeDriveService::AddNewFile(const std::string& content_type, 119590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& content_data, 1196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& parent_resource_id, 1197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& title, 1198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool shared_with_me, 1199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetResourceEntryCallback& callback) { 1200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 1202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (offline_) { 1204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 120590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, 1208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GDATA_NO_CONNECTION, 1209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&null))); 1210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Prepare "kind" for hosted documents. This only supports Google Document. 1214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string entry_kind; 1215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (content_type == "application/vnd.google-apps.document") 1216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry_kind = "document"; 1217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 1218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry_kind = "file"; 1219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::DictionaryValue* new_entry = AddNewEntry(content_type, 122190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content_data, 1222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parent_resource_id, 1223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) title, 1224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shared_with_me, 1225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry_kind); 1226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!new_entry) { 1227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 122890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, base::Passed(&null))); 1231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> parsed_entry( 1235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceEntry::CreateFrom(*new_entry)); 123690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_CREATED, base::Passed(&parsed_entry))); 1239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void FakeDriveService::SetLastModifiedTime( 1242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& resource_id, 1243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Time& last_modified_time, 1244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetResourceEntryCallback& callback) { 1245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 1247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (offline_) { 1249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 125090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, 1253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GDATA_NO_CONNECTION, 1254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&null))); 1255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 1259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!entry) { 1260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 126190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, base::Passed(&null))); 1264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (last_modified_time.is_null()) { 1268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry->Remove("updated.$t", NULL); 1269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 1270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry->SetString("updated.$t", 1271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) util::FormatTimeAsString(last_modified_time)); 1272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> parsed_entry( 1275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceEntry::CreateFrom(*entry)); 127690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_SUCCESS, base::Passed(&parsed_entry))); 1279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 12812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::DictionaryValue* FakeDriveService::FindEntryByResourceId( 12822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id) { 12832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 12842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* entries = NULL; 12862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Go through entries and return the one that matches |resource_id|. 1287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) { 12882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 12892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = NULL; 12902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string current_resource_id; 12912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entries->GetDictionary(i, &entry) && 12922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("gd$resourceId.$t", ¤t_resource_id) && 12932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_id == current_resource_id) { 12942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return entry; 12952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 13002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 13012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::DictionaryValue* FakeDriveService::FindEntryByContentUrl( 13032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& content_url) { 13042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 13052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* entries = NULL; 13072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Go through entries and return the one that matches |content_url|. 1308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) { 13092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 13102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = NULL; 13112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string current_content_url; 13122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entries->GetDictionary(i, &entry) && 13132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("content.src", ¤t_content_url) && 13142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_url == GURL(current_content_url)) { 13152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return entry; 13162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 13172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 13182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 13192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 13212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 13222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string FakeDriveService::GetNewResourceId() { 13242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 13252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++resource_id_count_; 13272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::StringPrintf("resource_id_%d", resource_id_count_); 13282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 13292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid FakeDriveService::AddNewChangestampAndETag(base::DictionaryValue* entry) { 13312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++largest_changestamp_; 13322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->SetString("docs$changestamp.value", 13332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Int64ToString(largest_changestamp_)); 1334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry->SetString("gd$etag", 1335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "etag_" + base::Int64ToString(largest_changestamp_)); 13362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 13372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::DictionaryValue* FakeDriveService::AddNewEntry( 1339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& content_type, 134090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& content_data, 1341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& parent_resource_id, 1342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& title, 1343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool shared_with_me, 1344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& entry_kind) { 1345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (parent_resource_id != GetRootResourceId() && 1348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !FindEntryByResourceId(parent_resource_id)) { 1349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return NULL; 1350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string resource_id = GetNewResourceId(); 1353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL upload_url = GURL("https://xxx/upload/" + resource_id); 1354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::DictionaryValue> new_entry(new base::DictionaryValue); 1356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Set the resource ID and the title 1357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->SetString("gd$resourceId.$t", resource_id); 1358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->SetString("title.$t", title); 1359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->SetString("docs$filename", title); 136090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Set the contents, size and MD5 for a file. 1361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (entry_kind == "file") { 136290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new_entry->Set("test$data", 136390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::BinaryValue::CreateWithCopiedBuffer( 136490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content_data.c_str(), content_data.size())); 136590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new_entry->SetString("docs$size.$t", 136690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Int64ToString(content_data.size())); 1367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->SetString("docs$md5Checksum.$t", 1368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::MD5String(content_data)); 1369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add "category" which sets the resource type to |entry_kind|. 1372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue* categories = new base::ListValue; 1373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* category = new base::DictionaryValue; 1374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) category->SetString("scheme", "http://schemas.google.com/g/2005#kind"); 1375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) category->SetString("term", "http://schemas.google.com/docs/2007#" + 1376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry_kind); 1377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) categories->Append(category); 1378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->Set("category", categories); 1379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (shared_with_me) { 1380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* shared_with_me_label = new base::DictionaryValue; 1381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shared_with_me_label->SetString("label", "shared-with-me"); 1382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shared_with_me_label->SetString("scheme", 1383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://schemas.google.com/g/2005/labels"); 1384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shared_with_me_label->SetString( 1385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "term", "http://schemas.google.com/g/2005/labels#shared"); 1386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) categories->Append(shared_with_me_label); 1387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string escaped_resource_id = net::EscapePath(resource_id); 1390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add "content" which sets the content URL. 1392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* content = new base::DictionaryValue; 1393868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) content->SetString("src", "https://xxx/content/" + escaped_resource_id); 1394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content->SetString("type", content_type); 1395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->Set("content", content); 1396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add "link" which sets the parent URL, the edit URL and the upload URL. 1398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue* links = new base::ListValue; 1399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* parent_link = new base::DictionaryValue; 1401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parent_link->SetString("href", GetFakeLinkUrl(parent_resource_id).spec()); 1402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parent_link->SetString("rel", 1403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://schemas.google.com/docs/2007#parent"); 1404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) links->Append(parent_link); 1405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* edit_link = new base::DictionaryValue; 1407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) edit_link->SetString("href", "https://xxx/edit/" + escaped_resource_id); 1408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) edit_link->SetString("rel", "edit"); 1409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) links->Append(edit_link); 1410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* upload_link = new base::DictionaryValue; 1412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) upload_link->SetString("href", upload_url.spec()); 1413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) upload_link->SetString("rel", kUploadUrlRel); 1414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) links->Append(upload_link); 14152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 14162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const GURL share_url = net::AppendOrReplaceQueryParameter( 14172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch share_url_base_, "name", title); 14182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch base::DictionaryValue* share_link = new base::DictionaryValue; 14192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch upload_link->SetString("href", share_url.spec()); 14202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch upload_link->SetString("rel", kShareUrlRel); 14212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch links->Append(share_link); 1422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->Set("link", links); 1423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1424eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddNewChangestampAndETag(new_entry.get()); 1425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 14267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Time published_date = 14277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Time() + base::TimeDelta::FromMilliseconds(++published_date_seq_); 14287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) new_entry->SetString("published.$t", 14297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) util::FormatTimeAsString(published_date)); 14307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If there are no entries, prepare an empty entry to add. 1432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!resource_list_value_->HasKey("entry")) 1433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) resource_list_value_->Set("entry", new ListValue); 1434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* raw_new_entry = new_entry.release(); 1436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue* entries = NULL; 1437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) 1438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entries->Append(raw_new_entry); 1439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return raw_new_entry; 1441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void FakeDriveService::GetResourceListInternal( 1444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 start_changestamp, 1445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& search_query, 1446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& directory_resource_id, 1447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int start_offset, 1448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int max_results, 1449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int* load_counter, 1450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetResourceListCallback& callback) { 1451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (offline_) { 145290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, 1455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GDATA_NO_CONNECTION, 14567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Passed(scoped_ptr<ResourceList>()))); 1457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceList> resource_list = 1461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceList::CreateFrom(*resource_list_value_); 1462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 14637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // TODO(hashimoto): Drive API always provides largest changestamp. Remove this 14647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // if-statement after API switch. 14657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (start_changestamp > 0 && start_offset == 0) 14667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch resource_list->set_largest_changestamp(largest_changestamp_); 14677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Filter out entries per parameters like |directory_resource_id| and 1469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |search_query|. 1470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ScopedVector<ResourceEntry>* entries = resource_list->mutable_entries(); 1471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int num_entries_matched = 0; 1473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < entries->size();) { 1474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceEntry* entry = (*entries)[i]; 1475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool should_exclude = false; 1476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If |directory_resource_id| is set, exclude the entry if it's not in 1478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // the target directory. 1479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!directory_resource_id.empty()) { 1480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Get the parent resource ID of the entry. 1481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string parent_resource_id; 1482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const google_apis::Link* parent_link = 1483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry->GetLinkByType(Link::LINK_PARENT); 1484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (parent_link) { 1485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parent_resource_id = 1486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::UnescapeURLComponent(parent_link->href().ExtractFileName(), 1487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::UnescapeRule::URL_SPECIAL_CHARS); 1488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (directory_resource_id != parent_resource_id) 1490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_exclude = true; 1491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If |search_query| is set, exclude the entry if it does not contain the 1494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // search query in the title. 1495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!should_exclude && !search_query.empty() && 1496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !EntryMatchWithQuery(*entry, search_query)) { 1497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_exclude = true; 1498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If |start_changestamp| is set, exclude the entry if the 1501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // changestamp is older than |largest_changestamp|. 1502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // See https://developers.google.com/google-apps/documents-list/ 1503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // #retrieving_all_changes_since_a_given_changestamp 1504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (start_changestamp > 0 && entry->changestamp() < start_changestamp) 1505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_exclude = true; 1506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1507eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // If the caller requests other list than change list by specifying 1508eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // zero-|start_changestamp|, exclude deleted entry from the result. 1509eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!start_changestamp && entry->deleted()) 1510eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch should_exclude = true; 1511eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The entry matched the criteria for inclusion. 1513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!should_exclude) 1514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ++num_entries_matched; 1515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If |start_offset| is set, exclude the entry if the entry is before the 1517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // start index. <= instead of < as |num_entries_matched| was 1518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // already incremented. 1519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (start_offset > 0 && num_entries_matched <= start_offset) 1520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_exclude = true; 1521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (should_exclude) 1523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entries->erase(entries->begin() + i); 1524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 1525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ++i; 1526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If |max_results| is set, trim the entries if the number exceeded the max 1529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // results. 1530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (max_results > 0 && entries->size() > static_cast<size_t>(max_results)) { 1531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entries->erase(entries->begin() + max_results, entries->end()); 1532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Adds the next URL. 1533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Here, we embed information which is needed for continuing the 1534868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // GetResourceList request in the next invocation into url query 1535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // parameters. 1536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL next_url(base::StringPrintf( 1537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://localhost/?start-offset=%d&max-results=%d", 1538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) start_offset + max_results, 1539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) max_results)); 1540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (start_changestamp > 0) { 1541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url = net::AppendOrReplaceQueryParameter( 1542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url, "changestamp", 1543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Int64ToString(start_changestamp).c_str()); 1544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!search_query.empty()) { 1546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url = net::AppendOrReplaceQueryParameter( 1547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url, "q", search_query); 1548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!directory_resource_id.empty()) { 1550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url = net::AppendOrReplaceQueryParameter( 1551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url, "parent", directory_resource_id); 1552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Link* link = new Link; 1555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) link->set_type(Link::LINK_NEXT); 1556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) link->set_href(next_url); 1557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) resource_list->mutable_links()->push_back(link); 1558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (load_counter) 1561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *load_counter += 1; 156290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 15647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(callback, HTTP_SUCCESS, base::Passed(&resource_list))); 1565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1567eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochGURL FakeDriveService::GetNewUploadSessionUrl() { 1568eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return GURL("https://upload_session_url/" + 1569eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Int64ToString(next_upload_sequence_number_++)); 1570eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 1571eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1572eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace drive 1573