fake_drive_service.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
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" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/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; 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::AuthorizeAppCallback; 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::CancelCallback; 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::DownloadActionCallback; 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::EntryActionCallback; 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDataErrorCode; 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_FILE_ERROR; 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_NO_CONNECTION; 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_OTHER_ERROR; 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetAboutResourceCallback; 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetAppListCallback; 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetContentCallback; 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetResourceEntryCallback; 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetResourceListCallback; 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_BAD_REQUEST; 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_CREATED; 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_NOT_FOUND; 47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_PRECONDITION; 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_RESUME_INCOMPLETE; 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_SUCCESS; 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::InitiateUploadCallback; 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::Link; 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ProgressCallback; 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ResourceEntry; 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ResourceList; 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::UploadRangeCallback; 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::UploadRangeResponse; 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace test_util = google_apis::test_util; 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace util = google_apis::util; 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace drive { 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Rel property of upload link in the entries dictionary value. 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kUploadUrlRel[] = 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "http://schemas.google.com/g/2005#resumable-create-media"; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns true if a resource entry matches with the search query. 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Supports queries consist of following format. 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Phrases quoted by double/single quotes 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - AND search for multiple words/phrases segmented by space 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Limited attribute search. Only "title:" is supported. 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool EntryMatchWithQuery(const ResourceEntry& entry, 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& query) { 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringTokenizer tokenizer(query, " "); 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tokenizer.set_quote_chars("\"'"); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (tokenizer.GetNext()) { 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string key, value; 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& token = tokenizer.token(); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (token.find(':') == std::string::npos) { 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TrimString(token, "\"'", &value); 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringTokenizer key_value(token, ":"); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key_value.set_quote_chars("\"'"); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!key_value.GetNext()) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key = key_value.token(); 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!key_value.GetNext()) 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TrimString(key_value.token(), "\"'", &value); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(peria): Deal with other attributes than title. 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!key.empty() && key != "title") 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Search query in the title. 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry.title().find(value) == std::string::npos) 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Returns |url| without query parameter. 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)GURL RemoveQueryParameter(const GURL& url) { 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GURL::Replacements replacements; 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) replacements.ClearQuery(); 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return url.ReplaceComponents(replacements); 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ScheduleUploadRangeCallback(const UploadRangeCallback& callback, 110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 start_position, 111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 end_position, 112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GDataErrorCode error, 113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<ResourceEntry> entry) { 114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::MessageLoop::current()->PostTask( 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FROM_HERE, 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(callback, 117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UploadRangeResponse(error, 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch start_position, 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch end_position), 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Passed(&entry))); 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstruct FakeDriveService::UploadSession { 126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string content_type; 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 content_length; 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string parent_resource_id; 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string resource_id; 130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string etag; 131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string title; 132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 uploaded_size; 134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UploadSession() 136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : content_length(0), 137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uploaded_size(0) {} 138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UploadSession( 140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string content_type, 141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 content_length, 142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string parent_resource_id, 143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string resource_id, 144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string etag, 145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string title) 146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : content_type(content_type), 147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch content_length(content_length), 148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch parent_resource_id(parent_resource_id), 149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch resource_id(resource_id), 150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch etag(etag), 151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch title(title), 152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uploaded_size(0) { 153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FakeDriveService::FakeDriveService() 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : largest_changestamp_(0), 1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) published_date_seq_(0), 159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch next_upload_sequence_number_(0), 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default_max_results_(0), 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_id_count_(0), 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_list_load_count_(0), 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) change_list_load_count_(0), 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) directory_load_count_(0), 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) about_resource_load_count_(0), 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) offline_(false) { 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FakeDriveService::~FakeDriveService() { 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FakeDriveService::LoadResourceListForWapi( 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& relative_path) { 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Value> raw_value = test_util::LoadJSONFile(relative_path); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* as_dict = NULL; 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Value* feed = NULL; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* feed_as_dict = NULL; 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Extract the "feed" from the raw value and take the ownership. 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note that Remove() transfers the ownership to |feed|. 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (raw_value->GetAsDictionary(&as_dict) && 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) as_dict->Remove("feed", &feed) && 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) feed->GetAsDictionary(&feed_as_dict)) { 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_list_value_.reset(feed_as_dict); 18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Go through entries and convert test$data from a string to a binary blob. 19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::ListValue* entries = NULL; 19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (feed_as_dict->GetList("entry", &entries)) { 19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::DictionaryValue* entry = NULL; 19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string content_data; 19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (entries->GetDictionary(i, &entry) && 19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entry->GetString("test$data", &content_data)) { 19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entry->Set("test$data", base::BinaryValue::CreateWithCopiedBuffer( 19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content_data.c_str(), content_data.size())); 19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return resource_list_value_; 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FakeDriveService::LoadAccountMetadataForWapi( 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& relative_path) { 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) account_metadata_value_ = test_util::LoadJSONFile(relative_path); 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Update the largest_changestamp_. 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AccountMetadata> account_metadata = 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AccountMetadata::CreateFrom(*account_metadata_value_); 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) largest_changestamp_ = account_metadata->largest_changestamp(); 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Add the largest changestamp to the existing entries. 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This will be used to generate change lists in GetResourceList(). 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (resource_list_value_) { 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* entries = NULL; 221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) { 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = NULL; 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entries->GetDictionary(i, &entry)) { 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->SetString("docs$changestamp.value", 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Int64ToString(largest_changestamp_)); 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return account_metadata_value_; 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FakeDriveService::LoadAppListForDriveApi( 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& relative_path) { 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app_info_value_ = test_util::LoadJSONFile(relative_path); 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return app_info_value_; 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GURL FakeDriveService::GetFakeLinkUrl(const std::string& resource_id) { 243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return GURL("https://fake_server/" + net::EscapePath(resource_id)); 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FakeDriveService::Initialize(Profile* profile) { 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FakeDriveService::AddObserver(DriveServiceObserver* observer) { 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FakeDriveService::RemoveObserver(DriveServiceObserver* observer) { 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool FakeDriveService::CanSendRequest() const { 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string FakeDriveService::CanonicalizeResourceId( 26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& resource_id) const { 26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return resource_id; 26690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FakeDriveService::HasAccessToken() const { 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FakeDriveService::HasRefreshToken() const { 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FakeDriveService::ClearAccessToken() { 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FakeDriveService::ClearRefreshToken() { 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string FakeDriveService::GetRootResourceId() const { 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "fake_root"; 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetAllResourceList( 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetResourceListCallback& callback) { 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetResourceListInternal(0, // start changestamp 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // empty search query 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // no directory resource id, 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, // start offset 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default_max_results_, 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &resource_list_load_count_, 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 3027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetResourceListInDirectory( 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& directory_resource_id, 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetResourceListCallback& callback) { 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!directory_resource_id.empty()); 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetResourceListInternal(0, // start changestamp 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // empty search query 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) directory_resource_id, 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, // start offset 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default_max_results_, 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &directory_load_count_, 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 3197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::Search( 3237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& search_query, 3247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const GetResourceListCallback& callback) { 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!search_query.empty()); 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetResourceListInternal(0, // start changestamp 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) search_query, 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // no directory resource id, 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, // start offset 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default_max_results_, 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NULL, 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 3367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::SearchByTitle( 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& title, 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& directory_resource_id, 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetResourceListCallback& callback) { 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!title.empty()); 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Note: the search implementation here doesn't support quotation unescape, 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // so don't escape here. 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetResourceListInternal(0, // start changestamp 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::StringPrintf("title:'%s'", title.c_str()), 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) directory_resource_id, 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, // start offset 353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default_max_results_, 354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NULL, 355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 3567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetChangeList( 3607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int64 start_changestamp, 3617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const GetResourceListCallback& callback) { 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetResourceListInternal(start_changestamp, 366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // empty search query 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // no directory resource id, 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, // start offset 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default_max_results_, 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &change_list_load_count_, 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 3727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::ContinueGetResourceList( 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GURL& override_url, 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetResourceListCallback& callback) { 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!override_url.is_empty()); 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // "changestamp", "q", "parent" and "start-offset" are parameters to 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // implement "paging" of the result on FakeDriveService. 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The URL should be the one filled in GetResourceListInternal of the 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // previous method invocation, so it should start with "http://localhost/?". 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // See also GetResourceListInternal. 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(override_url.host(), "localhost"); 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(override_url.path(), "/"); 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 start_changestamp = 0; 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string search_query; 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string directory_resource_id; 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int start_offset = 0; 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int max_results = default_max_results_; 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::pair<std::string, std::string> > parameters; 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (base::SplitStringIntoKeyValuePairs( 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) override_url.query(), '=', '&', ¶meters)) { 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < parameters.size(); ++i) { 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (parameters[i].first == "changestamp") { 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::StringToInt64(parameters[i].second, &start_changestamp); 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (parameters[i].first == "q") { 402868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) search_query = 403868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::UnescapeURLComponent(parameters[i].second, 404868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::UnescapeRule::URL_SPECIAL_CHARS); 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (parameters[i].first == "parent") { 406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) directory_resource_id = 407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::UnescapeURLComponent(parameters[i].second, 408868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::UnescapeRule::URL_SPECIAL_CHARS); 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (parameters[i].first == "start-offset") { 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringToInt(parameters[i].second, &start_offset); 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (parameters[i].first == "max-results") { 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringToInt(parameters[i].second, &max_results); 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetResourceListInternal( 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) start_changestamp, search_query, directory_resource_id, 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) start_offset, max_results, NULL, callback); 4207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetResourceEntry( 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetResourceEntryCallback& callback) { 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 43190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&null))); 4367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry) { 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> resource_entry = 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResourceEntry::CreateFrom(*entry); 44390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_SUCCESS, base::Passed(&resource_entry))); 4467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 45090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, base::Passed(&null))); 4537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetAboutResource( 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetAboutResourceCallback& callback) { 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AboutResource> null; 46690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, base::Passed(&null))); 4707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++about_resource_load_count_; 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AboutResource> about_resource( 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AboutResource::CreateFromAccountMetadata( 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *AccountMetadata::CreateFrom(*account_metadata_value_), 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRootResourceId())); 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Overwrite the change id. 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) about_resource->set_largest_change_id(largest_changestamp_); 48090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HTTP_SUCCESS, base::Passed(&about_resource))); 4847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetAppList( 4887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const GetAppListCallback& callback) { 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 49190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(app_info_value_); 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AppList> null; 49590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&null))); 5007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AppList> app_list(AppList::CreateFrom(*app_info_value_)); 50490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_SUCCESS, base::Passed(&app_list))); 5077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::DeleteResource( 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& etag, 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const EntryActionCallback& callback) { 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 51890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, GDATA_NO_CONNECTION)); 5207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* entries = NULL; 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Go through entries and remove the one that matches |resource_id|. 525868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) { 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = NULL; 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string current_resource_id; 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entries->GetDictionary(i, &entry) && 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("gd$resourceId.$t", ¤t_resource_id) && 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_id == current_resource_id) { 532eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 533eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (entry->HasKey("gd$deleted")) { 534eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch error = HTTP_NOT_FOUND; 535eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 536eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry->Set("gd$deleted", new DictionaryValue); 537eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddNewChangestampAndETag(entry); 538eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch error = HTTP_SUCCESS; 539eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 54090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 541eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FROM_HERE, base::Bind(callback, error)); 5427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 54790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND)); 5497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::DownloadFile( 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& local_cache_path, 554eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& resource_id, 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DownloadActionCallback& download_action_callback, 556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetContentCallback& get_content_callback, 557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ProgressCallback& progress_callback) { 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!download_action_callback.is_null()); 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 56290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(download_action_callback, 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath())); 5677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The field content.src is the URL to download the file. 571eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!entry) { 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(download_action_callback, HTTP_NOT_FOUND, base::FilePath())); 5767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Write "x"s of the file size specified in the entry. 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string file_size_string; 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("docs$size.$t", &file_size_string); 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 file_size = 0; 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (base::StringToInt64(file_size_string, &file_size)) { 58490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::BinaryValue* content_binary_data; 58590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string content_data; 58690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (entry->GetBinary("test$data", &content_binary_data)) { 58790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content_data = std::string(content_binary_data->GetBuffer(), 58890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content_binary_data->GetSize()); 58990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 59090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_EQ(static_cast<size_t>(file_size), content_data.size()); 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!get_content_callback.is_null()) { 593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int64 kBlockSize = 5; 594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (int64 i = 0; i < file_size; i += kBlockSize) { 595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int64 size = std::min(kBlockSize, file_size - i); 596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<std::string> content_for_callback( 59790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new std::string(content_data.substr(i, size))); 598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(get_content_callback, HTTP_SUCCESS, 601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&content_for_callback))); 602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 60590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (test_util::WriteStringToFile(local_cache_path, content_data)) { 606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!progress_callback.is_null()) { 607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // See also the comment in ResumeUpload(). For testing that clients 608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // can handle the case progress_callback is called multiple times, 609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // here we invoke the callback twice. 610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(progress_callback, file_size / 2, file_size)); 613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(progress_callback, file_size, file_size)); 616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(download_action_callback, 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HTTP_SUCCESS, 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_cache_path)); 6227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Failed to write the content. 6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(download_action_callback, GDATA_FILE_ERROR, base::FilePath())); 6307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::CopyResource( 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 63590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& in_parent_resource_id, 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& new_name, 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetResourceEntryCallback& callback) { 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 64390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&null))); 6487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 65190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& parent_resource_id = in_parent_resource_id.empty() ? 65290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetRootResourceId() : in_parent_resource_id; 65390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* entries = NULL; 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Go through entries and copy the one that matches |resource_id|. 656868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) { 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = NULL; 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string current_resource_id; 6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entries->GetDictionary(i, &entry) && 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("gd$resourceId.$t", ¤t_resource_id) && 66290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) resource_id == current_resource_id) { 66390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Make a copy and set the new resource ID and the new title. 66490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<DictionaryValue> copied_entry(entry->DeepCopy()); 66590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) copied_entry->SetString("gd$resourceId.$t", 66690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) resource_id + "_copied"); 66790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) copied_entry->SetString("title.$t", new_name); 66890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 66990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Reset parent directory. 67090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::ListValue* links = NULL; 67190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!entry->GetList("link", &links)) { 67290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) links = new base::ListValue; 67390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entry->Set("link", links); 6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 67590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) links->Clear(); 67690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 67790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::DictionaryValue* link = new base::DictionaryValue; 67890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) link->SetString( 67990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "rel", "http://schemas.google.com/docs/2007#parent"); 68090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) link->SetString("href", GetFakeLinkUrl(parent_resource_id).spec()); 68190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) links->Append(link); 68290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 683eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddNewChangestampAndETag(copied_entry.get()); 68490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 68590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Parse the new entry. 68690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<ResourceEntry> resource_entry = 68790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ResourceEntry::CreateFrom(*copied_entry); 68890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Add it to the resource list. 68990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entries->Append(copied_entry.release()); 69090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 69190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 69290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, 69390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(callback, 69490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) HTTP_SUCCESS, 69590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Passed(&resource_entry))); 6967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 70290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, base::Passed(&null))); 7057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::CopyHostedDocument( 70990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& resource_id, 71090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& new_name, 71190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const GetResourceEntryCallback& callback) { 71290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 71390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!callback.is_null()); 71490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CopyResource(resource_id, std::string(), new_name, callback); 71690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 71790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::RenameResource( 7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& new_name, 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const EntryActionCallback& callback) { 7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 72690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, GDATA_NO_CONNECTION)); 7287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry) { 7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->SetString("title.$t", new_name); 734eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddNewChangestampAndETag(entry); 73590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_SUCCESS)); 7377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 74090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND)); 7427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::TouchResource( 74690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& resource_id, 74790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::Time& modified_date, 74890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::Time& last_viewed_by_me_date, 74990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const GetResourceEntryCallback& callback) { 75090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 75190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!modified_date.is_null()); 75290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!last_viewed_by_me_date.is_null()); 75390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!callback.is_null()); 75490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 75590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (offline_) { 75690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 75790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, 75890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(callback, GDATA_NO_CONNECTION, 75990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Passed(scoped_ptr<ResourceEntry>()))); 7607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 76190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 76290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 76390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 76490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!entry) { 76590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 76690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, 76790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, 76890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Passed(scoped_ptr<ResourceEntry>()))); 7697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 77090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 77190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 77290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entry->SetString("updated.$t", 77390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) util::FormatTimeAsString(modified_date)); 77490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entry->SetString("gd$lastViewed.$t", 77590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) util::FormatTimeAsString(last_viewed_by_me_date)); 776eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddNewChangestampAndETag(entry); 77790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 77890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<ResourceEntry> parsed_entry(ResourceEntry::CreateFrom(*entry)); 77990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 78090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, 78190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(callback, HTTP_SUCCESS, base::Passed(&parsed_entry))); 7827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 78390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 78490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::AddResourceToDirectory( 7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& parent_resource_id, 7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const EntryActionCallback& callback) { 7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 79390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, GDATA_NO_CONNECTION)); 7957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry) { 8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* links = NULL; 8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!entry->GetList("link", &links)) { 8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) links = new base::ListValue; 8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->Set("link", links); 8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // On the real Drive server, resources do not necessary shape a tree 8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // structure. That is, each resource can have multiple parent. 8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We mimic the behavior here; AddResourceToDirectoy just adds 8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // one more parent link, not overwriting old links. 8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* link = new base::DictionaryValue; 8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) link->SetString("rel", "http://schemas.google.com/docs/2007#parent"); 8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) link->SetString( 8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "href", GetFakeLinkUrl(parent_resource_id).spec()); 8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) links->Append(link); 8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 816eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddNewChangestampAndETag(entry); 81790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_SUCCESS)); 8197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 82290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND)); 8247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::RemoveResourceFromDirectory( 8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& parent_resource_id, 8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const EntryActionCallback& callback) { 8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 83590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, GDATA_NO_CONNECTION)); 8377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry) { 8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* links = NULL; 8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry->GetList("link", &links)) { 8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL parent_content_url = GetFakeLinkUrl(parent_resource_id); 8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < links->GetSize(); ++i) { 8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* link = NULL; 8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string rel; 8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string href; 8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (links->GetDictionary(i, &link) && 8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) link->GetString("rel", &rel) && 8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) link->GetString("href", &href) && 8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rel == "http://schemas.google.com/docs/2007#parent" && 8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL(href) == parent_content_url) { 8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) links->Remove(i, NULL); 855eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddNewChangestampAndETag(entry); 85690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_SUCCESS)); 8587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 86490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND)); 8667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::AddNewDirectory( 8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& parent_resource_id, 8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& directory_name, 8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetResourceEntryCallback& callback) { 8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 87890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, 8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&null))); 8837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char kContentType[] = "application/atom+xml;type=feed"; 887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::DictionaryValue* new_entry = AddNewEntry(kContentType, 88890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "", // content_data 889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parent_resource_id, 890c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) directory_name, 891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) false, // shared_with_me 892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "folder"); 893c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!new_entry) { 894c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 89590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 896c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 897c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, base::Passed(&null))); 8987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 901c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> parsed_entry(ResourceEntry::CreateFrom(*new_entry)); 90290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_CREATED, base::Passed(&parsed_entry))); 9057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::InitiateUploadNewFile( 9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& content_type, 9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 content_length, 9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& parent_resource_id, 9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& title, 9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const InitiateUploadCallback& callback) { 9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 91890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, GDATA_NO_CONNECTION, GURL())); 9217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 924eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (parent_resource_id != GetRootResourceId() && 925eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch !FindEntryByResourceId(parent_resource_id)) { 92690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, GURL())); 9297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 931eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 932eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL session_url = GetNewUploadSessionUrl(); 933eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch upload_sessions_[session_url] = 934eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UploadSession(content_type, content_length, 935eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch parent_resource_id, 936eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "", // resource_id 937eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "", // etag 938eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch title); 9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 94090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 942eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(callback, HTTP_SUCCESS, session_url)); 9437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::InitiateUploadExistingFile( 9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& content_type, 9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 content_length, 9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& etag, 9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const InitiateUploadCallback& callback) { 9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 95690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, GDATA_NO_CONNECTION, GURL())); 9597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DictionaryValue* entry = FindEntryByResourceId(resource_id); 9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!entry) { 96490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 9662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, GURL())); 9677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string entry_etag; 9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("gd$etag", &entry_etag); 972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!etag.empty() && etag != entry_etag) { 97390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_PRECONDITION, GURL())); 9767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 979eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL session_url = GetNewUploadSessionUrl(); 980eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch upload_sessions_[session_url] = 981eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UploadSession(content_type, content_length, 982eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "", // parent_resource_id 983eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch resource_id, 984eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry_etag, 985eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "" /* title */); 9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 98790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 989eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(callback, HTTP_SUCCESS, session_url)); 9907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetUploadStatus( 9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& upload_url, 9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 content_length, 9962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const UploadRangeCallback& callback) { 9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 9982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 9997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::ResumeUpload( 10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& upload_url, 10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 start_position, 10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 end_position, 10062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 content_length, 10072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& content_type, 1008a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const base::FilePath& local_file_path, 1009c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const UploadRangeCallback& callback, 1010c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ProgressCallback& progress_callback) { 10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 10132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1014eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GetResourceEntryCallback completion_callback 1015eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch = base::Bind(&ScheduleUploadRangeCallback, 1016eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback, start_position, end_position); 10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 1019eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(GDATA_NO_CONNECTION, scoped_ptr<ResourceEntry>()); 10207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1023eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!upload_sessions_.count(upload_url)) { 1024eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_NOT_FOUND, scoped_ptr<ResourceEntry>()); 10257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1028eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UploadSession* session = &upload_sessions_[upload_url]; 1029eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1030c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Chunks are required to be sent in such a ways that they fill from the start 1031c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // of the not-yet-uploaded part with no gaps nor overlaps. 1032eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (session->uploaded_size != start_position) { 1033eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_BAD_REQUEST, scoped_ptr<ResourceEntry>()); 10347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 1035c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1036c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1037c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!progress_callback.is_null()) { 1038c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // In the real GDataWapi/Drive DriveService, progress is reported in 1039c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // nondeterministic timing. In this fake implementation, we choose to call 1040c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // it twice per one ResumeUpload. This is for making sure that client code 1041c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // works fine even if the callback is invoked more than once; it is the 1042c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // crucial difference of the progress callback from others. 1043c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Note that progress is notified in the relative offset in each chunk. 1044c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int64 chunk_size = end_position - start_position; 104590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1046c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, base::Bind(progress_callback, chunk_size / 2, chunk_size)); 104790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1048c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, base::Bind(progress_callback, chunk_size, chunk_size)); 1049c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1050c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (content_length != end_position) { 1052eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->uploaded_size = end_position; 1053eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_RESUME_INCOMPLETE, 1054eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<ResourceEntry>()); 10557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1058eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string content_data; 1059eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!file_util::ReadFileToString(local_file_path, &content_data)) { 1060eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->uploaded_size = end_position; 1061eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(GDATA_FILE_ERROR, scoped_ptr<ResourceEntry>()); 1062eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return CancelCallback(); 1063eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1064eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->uploaded_size = end_position; 1065eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1066eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // |resource_id| is empty if the upload is for new file. 1067eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (session->resource_id.empty()) { 1068eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(!session->parent_resource_id.empty()); 1069eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(!session->title.empty()); 1070eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const DictionaryValue* new_entry = AddNewEntry( 1071eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->content_type, 1072eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch content_data, 1073eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->parent_resource_id, 1074eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->title, 1075eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch false, // shared_with_me 1076eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "file"); 1077eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!new_entry) { 1078eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_NOT_FOUND, scoped_ptr<ResourceEntry>()); 1079eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return CancelCallback(); 1080eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1082eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_CREATED, 1083eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ResourceEntry::CreateFrom(*new_entry)); 1084eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return CancelCallback(); 1085eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1086eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1087eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DictionaryValue* entry = FindEntryByResourceId(session->resource_id); 1088eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!entry) { 1089eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_NOT_FOUND, scoped_ptr<ResourceEntry>()); 1090eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return CancelCallback(); 1091eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 109290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1093eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string entry_etag; 1094eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry->GetString("gd$etag", &entry_etag); 1095eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (entry_etag.empty() || session->etag != entry_etag) { 1096eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_PRECONDITION, scoped_ptr<ResourceEntry>()); 1097eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return CancelCallback(); 1098eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry->SetString("docs$md5Checksum.$t", base::MD5String(content_data)); 1101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry->Set("test$data", 1102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::BinaryValue::CreateWithCopiedBuffer( 1103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch content_data.data(), content_data.size())); 1104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry->SetString("docs$size.$t", base::Int64ToString(end_position)); 1105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddNewChangestampAndETag(entry); 1106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_SUCCESS, ResourceEntry::CreateFrom(*entry)); 11087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::AuthorizeApp( 11127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& resource_id, 11137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& app_id, 11147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const AuthorizeAppCallback& callback) { 11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 11177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 11192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void FakeDriveService::AddNewFile(const std::string& content_type, 112190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& content_data, 1122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& parent_resource_id, 1123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& title, 1124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool shared_with_me, 1125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetResourceEntryCallback& callback) { 1126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 1128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (offline_) { 1130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 113190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, 1134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GDATA_NO_CONNECTION, 1135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&null))); 1136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Prepare "kind" for hosted documents. This only supports Google Document. 1140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string entry_kind; 1141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (content_type == "application/vnd.google-apps.document") 1142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry_kind = "document"; 1143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 1144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry_kind = "file"; 1145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::DictionaryValue* new_entry = AddNewEntry(content_type, 114790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content_data, 1148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parent_resource_id, 1149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) title, 1150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shared_with_me, 1151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry_kind); 1152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!new_entry) { 1153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 115490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, base::Passed(&null))); 1157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> parsed_entry( 1161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceEntry::CreateFrom(*new_entry)); 116290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_CREATED, base::Passed(&parsed_entry))); 1165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void FakeDriveService::SetLastModifiedTime( 1168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& resource_id, 1169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Time& last_modified_time, 1170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetResourceEntryCallback& callback) { 1171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 1173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (offline_) { 1175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 117690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, 1179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GDATA_NO_CONNECTION, 1180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&null))); 1181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 1185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!entry) { 1186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 118790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, base::Passed(&null))); 1190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (last_modified_time.is_null()) { 1194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry->Remove("updated.$t", NULL); 1195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 1196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry->SetString("updated.$t", 1197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) util::FormatTimeAsString(last_modified_time)); 1198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> parsed_entry( 1201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceEntry::CreateFrom(*entry)); 120290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_SUCCESS, base::Passed(&parsed_entry))); 1205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::DictionaryValue* FakeDriveService::FindEntryByResourceId( 12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id) { 12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 12102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* entries = NULL; 12122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Go through entries and return the one that matches |resource_id|. 1213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) { 12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 12152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = NULL; 12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string current_resource_id; 12172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entries->GetDictionary(i, &entry) && 12182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("gd$resourceId.$t", ¤t_resource_id) && 12192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_id == current_resource_id) { 12202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return entry; 12212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 12262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 12272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::DictionaryValue* FakeDriveService::FindEntryByContentUrl( 12292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& content_url) { 12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* entries = NULL; 12332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Go through entries and return the one that matches |content_url|. 1234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) { 12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 12362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = NULL; 12372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string current_content_url; 12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entries->GetDictionary(i, &entry) && 12392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("content.src", ¤t_content_url) && 12402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_url == GURL(current_content_url)) { 12412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return entry; 12422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string FakeDriveService::GetNewResourceId() { 12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++resource_id_count_; 12532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::StringPrintf("resource_id_%d", resource_id_count_); 12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 12552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1256eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid FakeDriveService::AddNewChangestampAndETag(base::DictionaryValue* entry) { 12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++largest_changestamp_; 12582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->SetString("docs$changestamp.value", 12592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Int64ToString(largest_changestamp_)); 1260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry->SetString("gd$etag", 1261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "etag_" + base::Int64ToString(largest_changestamp_)); 12622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 12632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::DictionaryValue* FakeDriveService::AddNewEntry( 1265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& content_type, 126690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& content_data, 1267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& parent_resource_id, 1268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& title, 1269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool shared_with_me, 1270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& entry_kind) { 1271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (parent_resource_id != GetRootResourceId() && 1274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !FindEntryByResourceId(parent_resource_id)) { 1275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return NULL; 1276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string resource_id = GetNewResourceId(); 1279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL upload_url = GURL("https://xxx/upload/" + resource_id); 1280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::DictionaryValue> new_entry(new base::DictionaryValue); 1282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Set the resource ID and the title 1283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->SetString("gd$resourceId.$t", resource_id); 1284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->SetString("title.$t", title); 1285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->SetString("docs$filename", title); 128690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Set the contents, size and MD5 for a file. 1287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (entry_kind == "file") { 128890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new_entry->Set("test$data", 128990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::BinaryValue::CreateWithCopiedBuffer( 129090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content_data.c_str(), content_data.size())); 129190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new_entry->SetString("docs$size.$t", 129290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Int64ToString(content_data.size())); 1293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->SetString("docs$md5Checksum.$t", 1294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::MD5String(content_data)); 1295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add "category" which sets the resource type to |entry_kind|. 1298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue* categories = new base::ListValue; 1299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* category = new base::DictionaryValue; 1300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) category->SetString("scheme", "http://schemas.google.com/g/2005#kind"); 1301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) category->SetString("term", "http://schemas.google.com/docs/2007#" + 1302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry_kind); 1303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) categories->Append(category); 1304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->Set("category", categories); 1305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (shared_with_me) { 1306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* shared_with_me_label = new base::DictionaryValue; 1307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shared_with_me_label->SetString("label", "shared-with-me"); 1308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shared_with_me_label->SetString("scheme", 1309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://schemas.google.com/g/2005/labels"); 1310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shared_with_me_label->SetString( 1311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "term", "http://schemas.google.com/g/2005/labels#shared"); 1312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) categories->Append(shared_with_me_label); 1313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string escaped_resource_id = net::EscapePath(resource_id); 1316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add "content" which sets the content URL. 1318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* content = new base::DictionaryValue; 1319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) content->SetString("src", "https://xxx/content/" + escaped_resource_id); 1320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content->SetString("type", content_type); 1321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->Set("content", content); 1322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add "link" which sets the parent URL, the edit URL and the upload URL. 1324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue* links = new base::ListValue; 1325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* parent_link = new base::DictionaryValue; 1327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parent_link->SetString("href", GetFakeLinkUrl(parent_resource_id).spec()); 1328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parent_link->SetString("rel", 1329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://schemas.google.com/docs/2007#parent"); 1330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) links->Append(parent_link); 1331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* edit_link = new base::DictionaryValue; 1333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) edit_link->SetString("href", "https://xxx/edit/" + escaped_resource_id); 1334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) edit_link->SetString("rel", "edit"); 1335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) links->Append(edit_link); 1336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* upload_link = new base::DictionaryValue; 1338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) upload_link->SetString("href", upload_url.spec()); 1339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) upload_link->SetString("rel", kUploadUrlRel); 1340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) links->Append(upload_link); 1341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->Set("link", links); 1342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddNewChangestampAndETag(new_entry.get()); 1344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 13457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Time published_date = 13467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Time() + base::TimeDelta::FromMilliseconds(++published_date_seq_); 13477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) new_entry->SetString("published.$t", 13487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) util::FormatTimeAsString(published_date)); 13497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If there are no entries, prepare an empty entry to add. 1351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!resource_list_value_->HasKey("entry")) 1352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) resource_list_value_->Set("entry", new ListValue); 1353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* raw_new_entry = new_entry.release(); 1355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue* entries = NULL; 1356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) 1357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entries->Append(raw_new_entry); 1358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return raw_new_entry; 1360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void FakeDriveService::GetResourceListInternal( 1363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 start_changestamp, 1364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& search_query, 1365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& directory_resource_id, 1366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int start_offset, 1367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int max_results, 1368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int* load_counter, 1369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetResourceListCallback& callback) { 1370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (offline_) { 1371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceList> null; 137290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, 1375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GDATA_NO_CONNECTION, 1376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&null))); 1377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceList> resource_list = 1381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceList::CreateFrom(*resource_list_value_); 1382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Filter out entries per parameters like |directory_resource_id| and 1384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |search_query|. 1385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ScopedVector<ResourceEntry>* entries = resource_list->mutable_entries(); 1386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int num_entries_matched = 0; 1388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < entries->size();) { 1389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceEntry* entry = (*entries)[i]; 1390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool should_exclude = false; 1391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If |directory_resource_id| is set, exclude the entry if it's not in 1393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // the target directory. 1394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!directory_resource_id.empty()) { 1395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Get the parent resource ID of the entry. 1396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string parent_resource_id; 1397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const google_apis::Link* parent_link = 1398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry->GetLinkByType(Link::LINK_PARENT); 1399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (parent_link) { 1400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parent_resource_id = 1401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::UnescapeURLComponent(parent_link->href().ExtractFileName(), 1402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::UnescapeRule::URL_SPECIAL_CHARS); 1403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (directory_resource_id != parent_resource_id) 1405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_exclude = true; 1406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If |search_query| is set, exclude the entry if it does not contain the 1409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // search query in the title. 1410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!should_exclude && !search_query.empty() && 1411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !EntryMatchWithQuery(*entry, search_query)) { 1412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_exclude = true; 1413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If |start_changestamp| is set, exclude the entry if the 1416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // changestamp is older than |largest_changestamp|. 1417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // See https://developers.google.com/google-apps/documents-list/ 1418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // #retrieving_all_changes_since_a_given_changestamp 1419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (start_changestamp > 0 && entry->changestamp() < start_changestamp) 1420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_exclude = true; 1421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1422eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // If the caller requests other list than change list by specifying 1423eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // zero-|start_changestamp|, exclude deleted entry from the result. 1424eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!start_changestamp && entry->deleted()) 1425eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch should_exclude = true; 1426eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The entry matched the criteria for inclusion. 1428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!should_exclude) 1429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ++num_entries_matched; 1430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If |start_offset| is set, exclude the entry if the entry is before the 1432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // start index. <= instead of < as |num_entries_matched| was 1433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // already incremented. 1434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (start_offset > 0 && num_entries_matched <= start_offset) 1435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_exclude = true; 1436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (should_exclude) 1438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entries->erase(entries->begin() + i); 1439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 1440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ++i; 1441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If |max_results| is set, trim the entries if the number exceeded the max 1444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // results. 1445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (max_results > 0 && entries->size() > static_cast<size_t>(max_results)) { 1446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entries->erase(entries->begin() + max_results, entries->end()); 1447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Adds the next URL. 1448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Here, we embed information which is needed for continuing the 1449868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // GetResourceList request in the next invocation into url query 1450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // parameters. 1451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL next_url(base::StringPrintf( 1452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://localhost/?start-offset=%d&max-results=%d", 1453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) start_offset + max_results, 1454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) max_results)); 1455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (start_changestamp > 0) { 1456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url = net::AppendOrReplaceQueryParameter( 1457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url, "changestamp", 1458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Int64ToString(start_changestamp).c_str()); 1459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!search_query.empty()) { 1461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url = net::AppendOrReplaceQueryParameter( 1462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url, "q", search_query); 1463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!directory_resource_id.empty()) { 1465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url = net::AppendOrReplaceQueryParameter( 1466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url, "parent", directory_resource_id); 1467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Link* link = new Link; 1470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) link->set_type(Link::LINK_NEXT); 1471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) link->set_href(next_url); 1472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) resource_list->mutable_links()->push_back(link); 1473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (load_counter) 1476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *load_counter += 1; 147790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, 1480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) HTTP_SUCCESS, 1481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&resource_list))); 1482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1484eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochGURL FakeDriveService::GetNewUploadSessionUrl() { 1485eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return GURL("https://upload_session_url/" + 1486eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Int64ToString(next_upload_sequence_number_++)); 1487eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 1488eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1489eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace drive 1490