fake_drive_service.cc revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
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) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/message_loop.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_tokenizer.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/google_apis/drive_api_parser.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/google_apis/gdata_wapi_parser.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/google_apis/test_util.h" 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/google_apis/time_util.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/escape.h" 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/base/url_util.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::BrowserThread; 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace google_apis { 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Rel property of upload link in the entries dictionary value. 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kUploadUrlRel[] = 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "http://schemas.google.com/g/2005#resumable-create-media"; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns true if a resource entry matches with the search query. 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Supports queries consist of following format. 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Phrases quoted by double/single quotes 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - AND search for multiple words/phrases segmented by space 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Limited attribute search. Only "title:" is supported. 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool EntryMatchWithQuery(const ResourceEntry& entry, 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& query) { 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringTokenizer tokenizer(query, " "); 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tokenizer.set_quote_chars("\"'"); 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (tokenizer.GetNext()) { 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string key, value; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& token = tokenizer.token(); 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (token.find(':') == std::string::npos) { 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TrimString(token, "\"'", &value); 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringTokenizer key_value(token, ":"); 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key_value.set_quote_chars("\"'"); 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!key_value.GetNext()) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key = key_value.token(); 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!key_value.GetNext()) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TrimString(key_value.token(), "\"'", &value); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(peria): Deal with other attributes than title. 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!key.empty() && key != "title") 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Search query in the title. 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry.title().find(value) == std::string::npos) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Gets the upload URL from the given entry. Returns an empty URL if not 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found. 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GURL GetUploadUrl(const base::DictionaryValue& entry) { 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string upload_url; 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::ListValue* links = NULL; 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (entry.GetList("link", &links) && links) { 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t link_index = 0; 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) link_index < links->GetSize(); 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ++link_index) { 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::DictionaryValue* link = NULL; 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string rel; 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (links->GetDictionary(link_index, &link) && 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) link && link->GetString("rel", &rel) && 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rel == kUploadUrlRel && 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) link->GetString("href", &upload_url)) { 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return GURL(upload_url); 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Returns |url| without query parameter. 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)GURL RemoveQueryParameter(const GURL& url) { 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GURL::Replacements replacements; 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) replacements.ClearQuery(); 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return url.ReplaceComponents(replacements); 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FakeDriveService::FakeDriveService() 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : largest_changestamp_(0), 1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) published_date_seq_(0), 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default_max_results_(0), 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_id_count_(0), 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_list_load_count_(0), 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) change_list_load_count_(0), 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) directory_load_count_(0), 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) about_resource_load_count_(0), 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) offline_(false) { 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FakeDriveService::~FakeDriveService() { 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FakeDriveService::LoadResourceListForWapi( 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& relative_path) { 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Value> raw_value = test_util::LoadJSONFile(relative_path); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* as_dict = NULL; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Value* feed = NULL; 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* feed_as_dict = NULL; 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Extract the "feed" from the raw value and take the ownership. 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note that Remove() transfers the ownership to |feed|. 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (raw_value->GetAsDictionary(&as_dict) && 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) as_dict->Remove("feed", &feed) && 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) feed->GetAsDictionary(&feed_as_dict)) { 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_list_value_.reset(feed_as_dict); 13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Go through entries and convert test$data from a string to a binary blob. 13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::ListValue* entries = NULL; 13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (feed_as_dict->GetList("entry", &entries)) { 13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::DictionaryValue* entry = NULL; 13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string content_data; 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (entries->GetDictionary(i, &entry) && 13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entry->GetString("test$data", &content_data)) { 14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entry->Set("test$data", base::BinaryValue::CreateWithCopiedBuffer( 14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content_data.c_str(), content_data.size())); 14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return resource_list_value_; 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FakeDriveService::LoadAccountMetadataForWapi( 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& relative_path) { 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) account_metadata_value_ = test_util::LoadJSONFile(relative_path); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Update the largest_changestamp_. 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AccountMetadata> account_metadata = 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AccountMetadata::CreateFrom(*account_metadata_value_); 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) largest_changestamp_ = account_metadata->largest_changestamp(); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Add the largest changestamp to the existing entries. 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This will be used to generate change lists in GetResourceList(). 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (resource_list_value_) { 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* entries = NULL; 164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) { 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = NULL; 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entries->GetDictionary(i, &entry)) { 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->SetString("docs$changestamp.value", 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Int64ToString(largest_changestamp_)); 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return account_metadata_value_; 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FakeDriveService::LoadAppListForDriveApi( 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& relative_path) { 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app_info_value_ = test_util::LoadJSONFile(relative_path); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return app_info_value_; 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GURL FakeDriveService::GetFakeLinkUrl(const std::string& resource_id) { 186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return GURL("https://fake_server/" + net::EscapePath(resource_id)); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FakeDriveService::Initialize(Profile* profile) { 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FakeDriveService::AddObserver(DriveServiceObserver* observer) { 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FakeDriveService::RemoveObserver(DriveServiceObserver* observer) { 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool FakeDriveService::CanSendRequest() const { 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string FakeDriveService::CanonicalizeResourceId( 20790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& resource_id) const { 20890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return resource_id; 20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FakeDriveService::HasAccessToken() const { 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FakeDriveService::HasRefreshToken() const { 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FakeDriveService::ClearAccessToken() { 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FakeDriveService::ClearRefreshToken() { 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string FakeDriveService::GetRootResourceId() const { 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "fake_root"; 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetAllResourceList( 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetResourceListCallback& callback) { 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetResourceListInternal(0, // start changestamp 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // empty search query 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // no directory resource id, 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, // start offset 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default_max_results_, 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &resource_list_load_count_, 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 2457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetResourceListInDirectory( 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& directory_resource_id, 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetResourceListCallback& callback) { 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!directory_resource_id.empty()); 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetResourceListInternal(0, // start changestamp 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // empty search query 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) directory_resource_id, 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, // start offset 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default_max_results_, 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &directory_load_count_, 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 2627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::Search( 2667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& search_query, 2677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const GetResourceListCallback& callback) { 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!search_query.empty()); 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetResourceListInternal(0, // start changestamp 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) search_query, 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // no directory resource id, 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, // start offset 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default_max_results_, 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NULL, 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 2797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::SearchByTitle( 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& title, 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& directory_resource_id, 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetResourceListCallback& callback) { 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!title.empty()); 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Note: the search implementation here doesn't support quotation unescape, 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // so don't escape here. 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetResourceListInternal(0, // start changestamp 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::StringPrintf("title:'%s'", title.c_str()), 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) directory_resource_id, 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, // start offset 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default_max_results_, 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NULL, 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 2997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetChangeList( 3037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int64 start_changestamp, 3047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const GetResourceListCallback& callback) { 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetResourceListInternal(start_changestamp, 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // empty search query 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // no directory resource id, 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, // start offset 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default_max_results_, 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &change_list_load_count_, 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 3157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::ContinueGetResourceList( 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GURL& override_url, 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetResourceListCallback& callback) { 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!override_url.is_empty()); 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // "changestamp", "q", "parent" and "start-offset" are parameters to 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // implement "paging" of the result on FakeDriveService. 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The URL should be the one filled in GetResourceListInternal of the 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // previous method invocation, so it should start with "http://localhost/?". 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // See also GetResourceListInternal. 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(override_url.host(), "localhost"); 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(override_url.path(), "/"); 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 start_changestamp = 0; 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string search_query; 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string directory_resource_id; 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int start_offset = 0; 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int max_results = default_max_results_; 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::pair<std::string, std::string> > parameters; 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (base::SplitStringIntoKeyValuePairs( 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) override_url.query(), '=', '&', ¶meters)) { 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < parameters.size(); ++i) { 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (parameters[i].first == "changestamp") { 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::StringToInt64(parameters[i].second, &start_changestamp); 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (parameters[i].first == "q") { 345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) search_query = 346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::UnescapeURLComponent(parameters[i].second, 347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::UnescapeRule::URL_SPECIAL_CHARS); 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (parameters[i].first == "parent") { 349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) directory_resource_id = 350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::UnescapeURLComponent(parameters[i].second, 351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::UnescapeRule::URL_SPECIAL_CHARS); 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (parameters[i].first == "start-offset") { 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringToInt(parameters[i].second, &start_offset); 354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (parameters[i].first == "max-results") { 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringToInt(parameters[i].second, &max_results); 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetResourceListInternal( 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) start_changestamp, search_query, directory_resource_id, 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) start_offset, max_results, NULL, callback); 3637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetResourceEntry( 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetResourceEntryCallback& callback) { 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 37490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&null))); 3797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry) { 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> resource_entry = 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResourceEntry::CreateFrom(*entry); 38690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_SUCCESS, base::Passed(&resource_entry))); 3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 39390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, base::Passed(&null))); 3967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetAboutResource( 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetAboutResourceCallback& callback) { 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AboutResource> null; 40990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, base::Passed(&null))); 4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++about_resource_load_count_; 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AboutResource> about_resource( 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AboutResource::CreateFromAccountMetadata( 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *AccountMetadata::CreateFrom(*account_metadata_value_), 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRootResourceId())); 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Overwrite the change id. 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) about_resource->set_largest_change_id(largest_changestamp_); 42390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HTTP_SUCCESS, base::Passed(&about_resource))); 4277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetAppList( 4317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const GetAppListCallback& callback) { 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 43490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(app_info_value_); 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AppList> null; 43890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&null))); 4437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AppList> app_list(AppList::CreateFrom(*app_info_value_)); 44790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_SUCCESS, base::Passed(&app_list))); 4507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::DeleteResource( 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& etag, 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const EntryActionCallback& callback) { 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 46190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, GDATA_NO_CONNECTION)); 4637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* entries = NULL; 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Go through entries and remove the one that matches |resource_id|. 468868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) { 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = NULL; 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string current_resource_id; 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entries->GetDictionary(i, &entry) && 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("gd$resourceId.$t", ¤t_resource_id) && 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_id == current_resource_id) { 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entries->Remove(i, NULL); 47690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_SUCCESS)); 4787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(satorux): Add support for returning "deleted" entries in 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // changelists from GetResourceList(). 48590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND)); 4877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::DownloadFile( 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& virtual_path, 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& local_cache_path, 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& download_url, 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DownloadActionCallback& download_action_callback, 495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetContentCallback& get_content_callback, 496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ProgressCallback& progress_callback) { 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!download_action_callback.is_null()); 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 50190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(download_action_callback, 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath())); 5067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The field content.src is the URL to download the file. 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByContentUrl(download_url); 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!entry) { 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(download_action_callback, HTTP_NOT_FOUND, base::FilePath())); 5157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Write "x"s of the file size specified in the entry. 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string file_size_string; 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("docs$size.$t", &file_size_string); 521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(satorux): To be correct, we should update docs$md5Checksum.$t here. 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 file_size = 0; 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (base::StringToInt64(file_size_string, &file_size)) { 52490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::BinaryValue* content_binary_data; 52590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string content_data; 52690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (entry->GetBinary("test$data", &content_binary_data)) { 52790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content_data = std::string(content_binary_data->GetBuffer(), 52890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content_binary_data->GetSize()); 52990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 53090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_EQ(static_cast<size_t>(file_size), content_data.size()); 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!get_content_callback.is_null()) { 533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int64 kBlockSize = 5; 534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (int64 i = 0; i < file_size; i += kBlockSize) { 535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int64 size = std::min(kBlockSize, file_size - i); 536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<std::string> content_for_callback( 53790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new std::string(content_data.substr(i, size))); 538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(get_content_callback, HTTP_SUCCESS, 541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&content_for_callback))); 542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 54590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (test_util::WriteStringToFile(local_cache_path, content_data)) { 546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!progress_callback.is_null()) { 547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // See also the comment in ResumeUpload(). For testing that clients 548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // can handle the case progress_callback is called multiple times, 549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // here we invoke the callback twice. 550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(progress_callback, file_size / 2, file_size)); 553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(progress_callback, file_size, file_size)); 556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(download_action_callback, 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HTTP_SUCCESS, 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_cache_path)); 5627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Failed to write the content. 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(download_action_callback, GDATA_FILE_ERROR, base::FilePath())); 5707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::CopyResource( 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 57590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& in_parent_resource_id, 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& new_name, 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetResourceEntryCallback& callback) { 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 58390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&null))); 5887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 59190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& parent_resource_id = in_parent_resource_id.empty() ? 59290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetRootResourceId() : in_parent_resource_id; 59390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* entries = NULL; 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Go through entries and copy the one that matches |resource_id|. 596868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) { 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = NULL; 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string current_resource_id; 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entries->GetDictionary(i, &entry) && 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("gd$resourceId.$t", ¤t_resource_id) && 60290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) resource_id == current_resource_id) { 60390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Make a copy and set the new resource ID and the new title. 60490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<DictionaryValue> copied_entry(entry->DeepCopy()); 60590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) copied_entry->SetString("gd$resourceId.$t", 60690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) resource_id + "_copied"); 60790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) copied_entry->SetString("title.$t", new_name); 60890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 60990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Reset parent directory. 61090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::ListValue* links = NULL; 61190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!entry->GetList("link", &links)) { 61290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) links = new base::ListValue; 61390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entry->Set("link", links); 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 61590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) links->Clear(); 61690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 61790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::DictionaryValue* link = new base::DictionaryValue; 61890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) link->SetString( 61990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "rel", "http://schemas.google.com/docs/2007#parent"); 62090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) link->SetString("href", GetFakeLinkUrl(parent_resource_id).spec()); 62190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) links->Append(link); 62290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 62390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) AddNewChangestamp(copied_entry.get()); 62490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 62590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Parse the new entry. 62690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<ResourceEntry> resource_entry = 62790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ResourceEntry::CreateFrom(*copied_entry); 62890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Add it to the resource list. 62990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entries->Append(copied_entry.release()); 63090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 63190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 63290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, 63390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(callback, 63490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) HTTP_SUCCESS, 63590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Passed(&resource_entry))); 6367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 64290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, base::Passed(&null))); 6457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::CopyHostedDocument( 64990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& resource_id, 65090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& new_name, 65190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const GetResourceEntryCallback& callback) { 65290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 65390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!callback.is_null()); 65490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CopyResource(resource_id, std::string(), new_name, callback); 65690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 65790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::RenameResource( 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& new_name, 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const EntryActionCallback& callback) { 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 66690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, GDATA_NO_CONNECTION)); 6687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry) { 6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->SetString("title.$t", new_name); 6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddNewChangestamp(entry); 67590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_SUCCESS)); 6777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 68090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND)); 6827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::TouchResource( 68690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& resource_id, 68790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::Time& modified_date, 68890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::Time& last_viewed_by_me_date, 68990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const GetResourceEntryCallback& callback) { 69090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 69190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!modified_date.is_null()); 69290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!last_viewed_by_me_date.is_null()); 69390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!callback.is_null()); 69490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 69590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (offline_) { 69690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 69790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, 69890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(callback, GDATA_NO_CONNECTION, 69990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Passed(scoped_ptr<ResourceEntry>()))); 7007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 70190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 70290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 70390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 70490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!entry) { 70590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 70690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, 70790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, 70890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Passed(scoped_ptr<ResourceEntry>()))); 7097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 71090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 71190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 71290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entry->SetString("updated.$t", 71390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) util::FormatTimeAsString(modified_date)); 71490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entry->SetString("gd$lastViewed.$t", 71590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) util::FormatTimeAsString(last_viewed_by_me_date)); 71690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) AddNewChangestamp(entry); 71790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 71890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<ResourceEntry> parsed_entry(ResourceEntry::CreateFrom(*entry)); 71990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 72090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, 72190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(callback, HTTP_SUCCESS, base::Passed(&parsed_entry))); 7227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 72390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 72490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::AddResourceToDirectory( 7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& parent_resource_id, 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const EntryActionCallback& callback) { 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 73390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, GDATA_NO_CONNECTION)); 7357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry) { 7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* links = NULL; 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!entry->GetList("link", &links)) { 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) links = new base::ListValue; 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->Set("link", links); 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // On the real Drive server, resources do not necessary shape a tree 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // structure. That is, each resource can have multiple parent. 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We mimic the behavior here; AddResourceToDirectoy just adds 7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // one more parent link, not overwriting old links. 7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* link = new base::DictionaryValue; 7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) link->SetString("rel", "http://schemas.google.com/docs/2007#parent"); 7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) link->SetString( 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "href", GetFakeLinkUrl(parent_resource_id).spec()); 7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) links->Append(link); 7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddNewChangestamp(entry); 75790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_SUCCESS)); 7597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 76290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND)); 7647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::RemoveResourceFromDirectory( 7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& parent_resource_id, 7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const EntryActionCallback& callback) { 7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 77590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, GDATA_NO_CONNECTION)); 7777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry) { 7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* links = NULL; 7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry->GetList("link", &links)) { 7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL parent_content_url = GetFakeLinkUrl(parent_resource_id); 7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < links->GetSize(); ++i) { 7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* link = NULL; 7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string rel; 7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string href; 7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (links->GetDictionary(i, &link) && 7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) link->GetString("rel", &rel) && 7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) link->GetString("href", &href) && 7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rel == "http://schemas.google.com/docs/2007#parent" && 7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL(href) == parent_content_url) { 7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) links->Remove(i, NULL); 7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddNewChangestamp(entry); 79690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_SUCCESS)); 7987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 80490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND)); 8067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::AddNewDirectory( 8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& parent_resource_id, 8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& directory_name, 8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetResourceEntryCallback& callback) { 8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 81890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, 8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&null))); 8237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 826c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char kContentType[] = "application/atom+xml;type=feed"; 827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::DictionaryValue* new_entry = AddNewEntry(kContentType, 82890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "", // content_data 829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parent_resource_id, 830c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) directory_name, 831c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) false, // shared_with_me 832c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "folder"); 833c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!new_entry) { 834c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 83590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 836c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 837c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, base::Passed(&null))); 8387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 841c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> parsed_entry(ResourceEntry::CreateFrom(*new_entry)); 84290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_CREATED, base::Passed(&parsed_entry))); 8457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::InitiateUploadNewFile( 8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& drive_file_path, 8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& content_type, 8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 content_length, 8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& parent_resource_id, 8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& title, 8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const InitiateUploadCallback& callback) { 8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 85990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, GDATA_NO_CONNECTION, GURL())); 8627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 865c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Content length should be zero, as we'll create an empty file first. The 866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // content will be added in ResumeUpload(). 867c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::DictionaryValue* new_entry = AddNewEntry(content_type, 86890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "", // content_data 869c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parent_resource_id, 870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) title, 871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) false, // shared_with_me 872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "file"); 873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!new_entry) { 87490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, GURL())); 8777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 879c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GURL upload_url = GetUploadUrl(*new_entry); 880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(upload_url.is_valid()); 8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 88290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 88490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(callback, HTTP_SUCCESS, 88590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::AppendQueryParameter(upload_url, "mode", "newfile"))); 8867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::InitiateUploadExistingFile( 8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& drive_file_path, 8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& content_type, 8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 content_length, 8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& etag, 8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const InitiateUploadCallback& callback) { 8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 90090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, GDATA_NO_CONNECTION, GURL())); 9037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DictionaryValue* entry = FindEntryByResourceId(resource_id); 9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!entry) { 90890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, GURL())); 9117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string entry_etag; 9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("gd$etag", &entry_etag); 916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!etag.empty() && etag != entry_etag) { 91790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_PRECONDITION, GURL())); 9207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry->SetString("docs$size.$t", "0"); 9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GURL upload_url = GetUploadUrl(*entry); 925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(upload_url.is_valid()); 9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 92790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 92990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(callback, HTTP_SUCCESS, 93090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::AppendQueryParameter(upload_url, "mode", "existing"))); 9317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetUploadStatus( 9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& drive_file_path, 9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& upload_url, 9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 content_length, 9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const UploadRangeCallback& callback) { 9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 9417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::ResumeUpload( 9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& drive_file_path, 9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& upload_url, 9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 start_position, 9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 end_position, 9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 content_length, 9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& content_type, 951a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const base::FilePath& local_file_path, 952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const UploadRangeCallback& callback, 953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ProgressCallback& progress_callback) { 9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> result_entry; 9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 96090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UploadRangeResponse(GDATA_NO_CONNECTION, 9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) start_position, 9652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) end_position), 9662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&result_entry))); 9677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DictionaryValue* entry = NULL; 97190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entry = FindEntryByUploadUrl(RemoveQueryParameter(upload_url)); 9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!entry) { 97390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UploadRangeResponse(HTTP_NOT_FOUND, 9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) start_position, 9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) end_position), 9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&result_entry))); 9807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 983c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Chunks are required to be sent in such a ways that they fill from the start 984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // of the not-yet-uploaded part with no gaps nor overlaps. 985c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string current_size_string; 986c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 current_size; 987c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!entry->GetString("docs$size.$t", ¤t_size_string) || 988c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !base::StringToInt64(current_size_string, ¤t_size) || 989c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) current_size != start_position) { 99090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 991c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 992c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, 993c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UploadRangeResponse(HTTP_BAD_REQUEST, 994c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) start_position, 995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) end_position), 996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&result_entry))); 9977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 998c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 999c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->SetString("docs$size.$t", base::Int64ToString(end_position)); 10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1002c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!progress_callback.is_null()) { 1003c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // In the real GDataWapi/Drive DriveService, progress is reported in 1004c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // nondeterministic timing. In this fake implementation, we choose to call 1005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // it twice per one ResumeUpload. This is for making sure that client code 1006c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // works fine even if the callback is invoked more than once; it is the 1007c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // crucial difference of the progress callback from others. 1008c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Note that progress is notified in the relative offset in each chunk. 1009c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int64 chunk_size = end_position - start_position; 101090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1011c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, base::Bind(progress_callback, chunk_size / 2, chunk_size)); 101290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1013c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, base::Bind(progress_callback, chunk_size, chunk_size)); 1014c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1015c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 10162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (content_length != end_position) { 101790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UploadRangeResponse(HTTP_RESUME_INCOMPLETE, 10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) start_position, 10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) end_position), 10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&result_entry))); 10247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 102790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) AddNewChangestamp(entry); 10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result_entry = ResourceEntry::CreateFrom(*entry).Pass(); 10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 103090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string upload_mode; 103190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool upload_mode_found = 103290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::GetValueForKeyInQuery(upload_url, "mode", &upload_mode); 103390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(upload_mode_found && 103490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) (upload_mode == "newfile" || upload_mode == "existing")); 103590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 103690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GDataErrorCode return_code = 103790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) upload_mode == "newfile" ? HTTP_CREATED : HTTP_SUCCESS; 10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 103990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UploadRangeResponse(return_code, 10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) start_position, 10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) end_position), 10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&result_entry))); 10467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::AuthorizeApp( 10507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& resource_id, 10517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& app_id, 10527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const AuthorizeAppCallback& callback) { 10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 10542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 10557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1058c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void FakeDriveService::AddNewFile(const std::string& content_type, 105990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& content_data, 1060c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& parent_resource_id, 1061c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& title, 1062c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool shared_with_me, 1063c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetResourceEntryCallback& callback) { 1064c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1065c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 1066c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1067c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (offline_) { 1068c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 106990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1070c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1071c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, 1072c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GDATA_NO_CONNECTION, 1073c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&null))); 1074c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1075c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1076c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1077c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Prepare "kind" for hosted documents. This only supports Google Document. 1078c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string entry_kind; 1079c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (content_type == "application/vnd.google-apps.document") 1080c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry_kind = "document"; 1081c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 1082c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry_kind = "file"; 1083c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1084c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::DictionaryValue* new_entry = AddNewEntry(content_type, 108590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content_data, 1086c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parent_resource_id, 1087c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) title, 1088c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shared_with_me, 1089c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry_kind); 1090c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!new_entry) { 1091c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 109290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1093c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1094c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, base::Passed(&null))); 1095c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1096c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1097c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1098c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> parsed_entry( 1099c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceEntry::CreateFrom(*new_entry)); 110090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_CREATED, base::Passed(&parsed_entry))); 1103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void FakeDriveService::SetLastModifiedTime( 1106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& resource_id, 1107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Time& last_modified_time, 1108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetResourceEntryCallback& callback) { 1109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 1111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (offline_) { 1113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 111490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, 1117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GDATA_NO_CONNECTION, 1118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&null))); 1119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 1123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!entry) { 1124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 112590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, base::Passed(&null))); 1128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (last_modified_time.is_null()) { 1132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry->Remove("updated.$t", NULL); 1133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 1134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry->SetString("updated.$t", 1135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) util::FormatTimeAsString(last_modified_time)); 1136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> parsed_entry( 1139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceEntry::CreateFrom(*entry)); 114090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_SUCCESS, base::Passed(&parsed_entry))); 1143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 11452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::DictionaryValue* FakeDriveService::FindEntryByResourceId( 11462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id) { 11472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 11482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* entries = NULL; 11502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Go through entries and return the one that matches |resource_id|. 1151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) { 11522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 11532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = NULL; 11542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string current_resource_id; 11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entries->GetDictionary(i, &entry) && 11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("gd$resourceId.$t", ¤t_resource_id) && 11572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_id == current_resource_id) { 11582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return entry; 11592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::DictionaryValue* FakeDriveService::FindEntryByContentUrl( 11672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& content_url) { 11682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 11692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* entries = NULL; 11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Go through entries and return the one that matches |content_url|. 1172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) { 11732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 11742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = NULL; 11752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string current_content_url; 11762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entries->GetDictionary(i, &entry) && 11772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("content.src", ¤t_content_url) && 11782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_url == GURL(current_content_url)) { 11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return entry; 11802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 11852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 11862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::DictionaryValue* FakeDriveService::FindEntryByUploadUrl( 11882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& upload_url) { 11892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 11902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* entries = NULL; 11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Go through entries and return the one that matches |upload_url|. 1193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) { 11942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 11952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = NULL; 11962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* links = NULL; 11972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entries->GetDictionary(i, &entry) && 11982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetList("link", &links) && 11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) links) { 12002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t link_index = 0; 12012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) link_index < links->GetSize(); 12022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++link_index) { 12032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* link = NULL; 12042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string rel; 12052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string found_upload_url; 12062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (links->GetDictionary(link_index, &link) && 12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) link && link->GetString("rel", &rel) && 12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rel == kUploadUrlRel && 12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) link->GetString("href", &found_upload_url) && 12102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL(found_upload_url) == upload_url) { 12112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return entry; 12122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 12192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 12202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string FakeDriveService::GetNewResourceId() { 12222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 12232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++resource_id_count_; 12252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::StringPrintf("resource_id_%d", resource_id_count_); 12262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 12272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FakeDriveService::AddNewChangestamp(base::DictionaryValue* entry) { 12292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++largest_changestamp_; 12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->SetString("docs$changestamp.value", 12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Int64ToString(largest_changestamp_)); 12322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 12332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::DictionaryValue* FakeDriveService::AddNewEntry( 1235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& content_type, 123690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& content_data, 1237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& parent_resource_id, 1238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& title, 1239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool shared_with_me, 1240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& entry_kind) { 1241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (parent_resource_id != GetRootResourceId() && 1244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !FindEntryByResourceId(parent_resource_id)) { 1245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return NULL; 1246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string resource_id = GetNewResourceId(); 1249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL upload_url = GURL("https://xxx/upload/" + resource_id); 1250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::DictionaryValue> new_entry(new base::DictionaryValue); 1252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Set the resource ID and the title 1253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->SetString("gd$resourceId.$t", resource_id); 1254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->SetString("title.$t", title); 1255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->SetString("docs$filename", title); 125690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Set the contents, size and MD5 for a file. 1257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (entry_kind == "file") { 125890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new_entry->Set("test$data", 125990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::BinaryValue::CreateWithCopiedBuffer( 126090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content_data.c_str(), content_data.size())); 126190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new_entry->SetString("docs$size.$t", 126290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Int64ToString(content_data.size())); 1263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(satorux): Set the correct MD5 here. 1264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->SetString("docs$md5Checksum.$t", 1265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "3b4385ebefec6e743574c76bbd0575de"); 1266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add "category" which sets the resource type to |entry_kind|. 1269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue* categories = new base::ListValue; 1270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* category = new base::DictionaryValue; 1271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) category->SetString("scheme", "http://schemas.google.com/g/2005#kind"); 1272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) category->SetString("term", "http://schemas.google.com/docs/2007#" + 1273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry_kind); 1274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) categories->Append(category); 1275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->Set("category", categories); 1276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (shared_with_me) { 1277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* shared_with_me_label = new base::DictionaryValue; 1278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shared_with_me_label->SetString("label", "shared-with-me"); 1279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shared_with_me_label->SetString("scheme", 1280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://schemas.google.com/g/2005/labels"); 1281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shared_with_me_label->SetString( 1282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "term", "http://schemas.google.com/g/2005/labels#shared"); 1283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) categories->Append(shared_with_me_label); 1284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string escaped_resource_id = net::EscapePath(resource_id); 1287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add "content" which sets the content URL. 1289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* content = new base::DictionaryValue; 1290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) content->SetString("src", "https://xxx/content/" + escaped_resource_id); 1291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content->SetString("type", content_type); 1292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->Set("content", content); 1293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add "link" which sets the parent URL, the edit URL and the upload URL. 1295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue* links = new base::ListValue; 1296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* parent_link = new base::DictionaryValue; 1298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parent_link->SetString("href", GetFakeLinkUrl(parent_resource_id).spec()); 1299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parent_link->SetString("rel", 1300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://schemas.google.com/docs/2007#parent"); 1301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) links->Append(parent_link); 1302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* edit_link = new base::DictionaryValue; 1304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) edit_link->SetString("href", "https://xxx/edit/" + escaped_resource_id); 1305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) edit_link->SetString("rel", "edit"); 1306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) links->Append(edit_link); 1307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* upload_link = new base::DictionaryValue; 1309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) upload_link->SetString("href", upload_url.spec()); 1310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) upload_link->SetString("rel", kUploadUrlRel); 1311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) links->Append(upload_link); 1312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->Set("link", links); 1313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AddNewChangestamp(new_entry.get()); 1315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 13167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Time published_date = 13177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Time() + base::TimeDelta::FromMilliseconds(++published_date_seq_); 13187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) new_entry->SetString("published.$t", 13197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) util::FormatTimeAsString(published_date)); 13207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If there are no entries, prepare an empty entry to add. 1322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!resource_list_value_->HasKey("entry")) 1323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) resource_list_value_->Set("entry", new ListValue); 1324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* raw_new_entry = new_entry.release(); 1326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue* entries = NULL; 1327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) 1328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entries->Append(raw_new_entry); 1329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return raw_new_entry; 1331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void FakeDriveService::GetResourceListInternal( 1334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 start_changestamp, 1335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& search_query, 1336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& directory_resource_id, 1337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int start_offset, 1338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int max_results, 1339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int* load_counter, 1340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetResourceListCallback& callback) { 1341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (offline_) { 1342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceList> null; 134390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, 1346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GDATA_NO_CONNECTION, 1347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&null))); 1348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceList> resource_list = 1352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceList::CreateFrom(*resource_list_value_); 1353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Filter out entries per parameters like |directory_resource_id| and 1355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |search_query|. 1356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ScopedVector<ResourceEntry>* entries = resource_list->mutable_entries(); 1357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int num_entries_matched = 0; 1359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < entries->size();) { 1360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceEntry* entry = (*entries)[i]; 1361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool should_exclude = false; 1362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If |directory_resource_id| is set, exclude the entry if it's not in 1364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // the target directory. 1365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!directory_resource_id.empty()) { 1366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Get the parent resource ID of the entry. 1367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string parent_resource_id; 1368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const google_apis::Link* parent_link = 1369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry->GetLinkByType(Link::LINK_PARENT); 1370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (parent_link) { 1371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parent_resource_id = 1372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::UnescapeURLComponent(parent_link->href().ExtractFileName(), 1373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::UnescapeRule::URL_SPECIAL_CHARS); 1374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (directory_resource_id != parent_resource_id) 1376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_exclude = true; 1377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If |search_query| is set, exclude the entry if it does not contain the 1380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // search query in the title. 1381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!should_exclude && !search_query.empty() && 1382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !EntryMatchWithQuery(*entry, search_query)) { 1383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_exclude = true; 1384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If |start_changestamp| is set, exclude the entry if the 1387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // changestamp is older than |largest_changestamp|. 1388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // See https://developers.google.com/google-apps/documents-list/ 1389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // #retrieving_all_changes_since_a_given_changestamp 1390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (start_changestamp > 0 && entry->changestamp() < start_changestamp) 1391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_exclude = true; 1392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The entry matched the criteria for inclusion. 1394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!should_exclude) 1395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ++num_entries_matched; 1396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If |start_offset| is set, exclude the entry if the entry is before the 1398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // start index. <= instead of < as |num_entries_matched| was 1399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // already incremented. 1400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (start_offset > 0 && num_entries_matched <= start_offset) 1401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_exclude = true; 1402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (should_exclude) 1404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entries->erase(entries->begin() + i); 1405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 1406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ++i; 1407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If |max_results| is set, trim the entries if the number exceeded the max 1410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // results. 1411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (max_results > 0 && entries->size() > static_cast<size_t>(max_results)) { 1412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entries->erase(entries->begin() + max_results, entries->end()); 1413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Adds the next URL. 1414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Here, we embed information which is needed for continuing the 1415868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // GetResourceList request in the next invocation into url query 1416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // parameters. 1417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL next_url(base::StringPrintf( 1418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://localhost/?start-offset=%d&max-results=%d", 1419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) start_offset + max_results, 1420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) max_results)); 1421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (start_changestamp > 0) { 1422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url = net::AppendOrReplaceQueryParameter( 1423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url, "changestamp", 1424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Int64ToString(start_changestamp).c_str()); 1425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!search_query.empty()) { 1427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url = net::AppendOrReplaceQueryParameter( 1428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url, "q", search_query); 1429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!directory_resource_id.empty()) { 1431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url = net::AppendOrReplaceQueryParameter( 1432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url, "parent", directory_resource_id); 1433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Link* link = new Link; 1436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) link->set_type(Link::LINK_NEXT); 1437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) link->set_href(next_url); 1438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) resource_list->mutable_links()->push_back(link); 1439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (load_counter) 1442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *load_counter += 1; 144390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, 1446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) HTTP_SUCCESS, 1447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&resource_list))); 1448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 14502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace google_apis 1451