12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/drive/fake_drive_service.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/file_util.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/md5.h" 129ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_tokenizer.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/drive/drive_api_util.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/drive_api_parser.h" 22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/gdata_wapi_parser.h" 23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/test_util.h" 24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/time_util.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/escape.h" 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/base/url_util.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::BrowserThread; 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::AboutResource; 30424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::AboutResourceCallback; 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::AccountMetadata; 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::AppList; 33424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::AppListCallback; 347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing google_apis::AuthStatusCallback; 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::AuthorizeAppCallback; 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::CancelCallback; 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::DownloadActionCallback; 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::EntryActionCallback; 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_FILE_ERROR; 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_NO_CONNECTION; 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_OTHER_ERROR; 42424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::GDataErrorCode; 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetContentCallback; 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetResourceEntryCallback; 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetResourceListCallback; 46bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochusing google_apis::GetShareUrlCallback; 47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_BAD_REQUEST; 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_CREATED; 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_NOT_FOUND; 50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using google_apis::HTTP_NO_CONTENT; 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_PRECONDITION; 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_RESUME_INCOMPLETE; 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_SUCCESS; 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::InitiateUploadCallback; 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::Link; 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ProgressCallback; 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ResourceEntry; 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ResourceList; 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::UploadRangeCallback; 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::UploadRangeResponse; 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace test_util = google_apis::test_util; 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace drive { 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Rel property of an upload link in the entries dictionary value. 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kUploadUrlRel[] = 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "http://schemas.google.com/g/2005#resumable-create-media"; 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Rel property of a share link in the entries dictionary value. 712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kShareUrlRel[] = 722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch "http://schemas.google.com/docs/2007#share"; 732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns true if a resource entry matches with the search query. 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Supports queries consist of following format. 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Phrases quoted by double/single quotes 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - AND search for multiple words/phrases segmented by space 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Limited attribute search. Only "title:" is supported. 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool EntryMatchWithQuery(const ResourceEntry& entry, 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& query) { 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringTokenizer tokenizer(query, " "); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tokenizer.set_quote_chars("\"'"); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (tokenizer.GetNext()) { 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string key, value; 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& token = tokenizer.token(); 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (token.find(':') == std::string::npos) { 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::TrimString(token, "\"'", &value); 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringTokenizer key_value(token, ":"); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key_value.set_quote_chars("\"'"); 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!key_value.GetNext()) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key = key_value.token(); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!key_value.GetNext()) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::TrimString(key_value.token(), "\"'", &value); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(peria): Deal with other attributes than title. 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!key.empty() && key != "title") 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Search query in the title. 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry.title().find(value) == std::string::npos) 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ScheduleUploadRangeCallback(const UploadRangeCallback& callback, 110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 start_position, 111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 end_position, 112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GDataErrorCode error, 113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<ResourceEntry> entry) { 114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::MessageLoop::current()->PostTask( 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FROM_HERE, 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(callback, 117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UploadRangeResponse(error, 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch start_position, 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch end_position), 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Passed(&entry))); 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void EntryActionCallbackAdapter( 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const EntryActionCallback& callback, 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) GDataErrorCode error, scoped_ptr<ResourceEntry> resource_entry) { 1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callback.Run(error); 1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 129d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)void ClearPropatiesForPermanentDelete(DictionaryValue* entry) { 130d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) scoped_ptr<DictionaryValue> new_entry(new DictionaryValue); 131d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) const char* kPreservedProperties[] = { 132d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) "docs$removed", "docs$changestamp", "gd$resourceId", "id", "updated" 133d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) }; 134d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 135d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) for (size_t i = 0; i < arraysize(kPreservedProperties); ++i) { 136d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) const char* key = kPreservedProperties[i]; 137d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) scoped_ptr<Value> value; 138d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (entry->Remove(key, &value)) 139d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) new_entry->Set(key, value.release()); 140d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) } 141d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 142d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) entry->Swap(new_entry.get()); 143d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)} 144d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstruct FakeDriveService::UploadSession { 148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string content_type; 149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 content_length; 150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string parent_resource_id; 151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string resource_id; 152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string etag; 153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string title; 154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 uploaded_size; 156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UploadSession() 158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : content_length(0), 159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uploaded_size(0) {} 160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UploadSession( 162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string content_type, 163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 content_length, 164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string parent_resource_id, 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string resource_id, 166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string etag, 167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string title) 168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : content_type(content_type), 169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch content_length(content_length), 170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch parent_resource_id(parent_resource_id), 171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch resource_id(resource_id), 172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch etag(etag), 173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch title(title), 174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uploaded_size(0) { 175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FakeDriveService::FakeDriveService() 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : largest_changestamp_(0), 1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) published_date_seq_(0), 181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch next_upload_sequence_number_(0), 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default_max_results_(0), 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_id_count_(0), 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_list_load_count_(0), 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) change_list_load_count_(0), 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) directory_load_count_(0), 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) about_resource_load_count_(0), 1882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch app_list_load_count_(0), 18958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) blocked_resource_list_load_count_(0), 19058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) offline_(false), 19158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) never_return_all_resource_list_(false) { 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FakeDriveService::~FakeDriveService() { 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FakeDriveService::LoadResourceListForWapi( 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& relative_path) { 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Value> raw_value = test_util::LoadJSONFile(relative_path); 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* as_dict = NULL; 2043240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch scoped_ptr<base::Value> feed; 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* feed_as_dict = NULL; 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Extract the "feed" from the raw value and take the ownership. 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note that Remove() transfers the ownership to |feed|. 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (raw_value->GetAsDictionary(&as_dict) && 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) as_dict->Remove("feed", &feed) && 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) feed->GetAsDictionary(&feed_as_dict)) { 2123240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch ignore_result(feed.release()); 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_list_value_.reset(feed_as_dict); 21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Go through entries and convert test$data from a string to a binary blob. 21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::ListValue* entries = NULL; 21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (feed_as_dict->GetList("entry", &entries)) { 21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::DictionaryValue* entry = NULL; 22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string content_data; 22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (entries->GetDictionary(i, &entry) && 22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entry->GetString("test$data", &content_data)) { 2233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch entry->Set("test$data", 2243240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch base::BinaryValue::CreateWithCopiedBuffer( 2253240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch content_data.c_str(), content_data.size())); 22690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return resource_list_value_; 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FakeDriveService::LoadAccountMetadataForWapi( 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& relative_path) { 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 237ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 238ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Load JSON data, which must be a dictionary. 239ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch scoped_ptr<base::Value> value = test_util::LoadJSONFile(relative_path); 240ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch CHECK_EQ(base::Value::TYPE_DICTIONARY, value->GetType()); 241ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch account_metadata_value_.reset( 242ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch static_cast<base::DictionaryValue*>(value.release())); 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Update the largest_changestamp_. 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AccountMetadata> account_metadata = 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AccountMetadata::CreateFrom(*account_metadata_value_); 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) largest_changestamp_ = account_metadata->largest_changestamp(); 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Add the largest changestamp to the existing entries. 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This will be used to generate change lists in GetResourceList(). 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (resource_list_value_) { 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* entries = NULL; 253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) { 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = NULL; 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entries->GetDictionary(i, &entry)) { 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->SetString("docs$changestamp.value", 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Int64ToString(largest_changestamp_)); 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return account_metadata_value_; 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FakeDriveService::LoadAppListForDriveApi( 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& relative_path) { 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app_info_value_ = test_util::LoadJSONFile(relative_path); 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return app_info_value_; 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 273ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 274ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid FakeDriveService::SetQuotaValue(int64 used, int64 total) { 275ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 276ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(account_metadata_value_); 277ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 278ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch account_metadata_value_->SetString("entry.gd$quotaBytesUsed.$t", 279ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Int64ToString16(used)); 280ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch account_metadata_value_->SetString("entry.gd$quotaBytesTotal.$t", 281ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Int64ToString16(total)); 282ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GURL FakeDriveService::GetFakeLinkUrl(const std::string& resource_id) { 285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return GURL("https://fake_server/" + net::EscapePath(resource_id)); 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 28868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void FakeDriveService::Initialize(const std::string& account_id) { 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FakeDriveService::AddObserver(DriveServiceObserver* observer) { 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FakeDriveService::RemoveObserver(DriveServiceObserver* observer) { 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool FakeDriveService::CanSendRequest() const { 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 305d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)ResourceIdCanonicalizer FakeDriveService::GetResourceIdCanonicalizer() const { 3068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return util::GetIdentityResourceIdCanonicalizer(); 30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FakeDriveService::HasAccessToken() const { 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FakeDriveService::RequestAccessToken(const AuthStatusCallback& callback) { 3157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(!callback.is_null()); 3177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch callback.Run(google_apis::HTTP_NOT_MODIFIED, "fake_access_token"); 3187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 3197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FakeDriveService::HasRefreshToken() const { 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FakeDriveService::ClearAccessToken() { 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FakeDriveService::ClearRefreshToken() { 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string FakeDriveService::GetRootResourceId() const { 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "fake_root"; 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetAllResourceList( 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetResourceListCallback& callback) { 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 34258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (never_return_all_resource_list_) { 34358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ++blocked_resource_list_load_count_; 34458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return CancelCallback(); 34558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 34658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetResourceListInternal(0, // start changestamp 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // empty search query 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // no directory resource id, 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, // start offset 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default_max_results_, 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &resource_list_load_count_, 353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetResourceListInDirectory( 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& directory_resource_id, 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetResourceListCallback& callback) { 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!directory_resource_id.empty()); 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetResourceListInternal(0, // start changestamp 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // empty search query 366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) directory_resource_id, 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, // start offset 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default_max_results_, 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &directory_load_count_, 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 3717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::Search( 3757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& search_query, 3767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const GetResourceListCallback& callback) { 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!search_query.empty()); 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetResourceListInternal(0, // start changestamp 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) search_query, 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // no directory resource id, 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, // start offset 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default_max_results_, 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NULL, 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 3887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::SearchByTitle( 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& title, 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& directory_resource_id, 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetResourceListCallback& callback) { 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!title.empty()); 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Note: the search implementation here doesn't support quotation unescape, 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // so don't escape here. 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetResourceListInternal(0, // start changestamp 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::StringPrintf("title:'%s'", title.c_str()), 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) directory_resource_id, 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, // start offset 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default_max_results_, 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NULL, 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetChangeList( 4127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int64 start_changestamp, 4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const GetResourceListCallback& callback) { 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetResourceListInternal(start_changestamp, 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // empty search query 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // no directory resource id, 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, // start offset 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default_max_results_, 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &change_list_load_count_, 423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 4247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 427424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)CancelCallback FakeDriveService::GetRemainingChangeList( 42858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const GURL& next_link, 429424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const GetResourceListCallback& callback) { 430424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 43158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(!next_link.is_empty()); 432424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(!callback.is_null()); 433424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 43458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return GetRemainingResourceList(next_link, callback); 435424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 436424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 437424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)CancelCallback FakeDriveService::GetRemainingFileList( 43858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const GURL& next_link, 439424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const GetResourceListCallback& callback) { 440424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 44158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(!next_link.is_empty()); 442424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(!callback.is_null()); 443424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 44458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return GetRemainingResourceList(next_link, callback); 445424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 446424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 4477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetResourceEntry( 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetResourceEntryCallback& callback) { 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 45590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&null))); 4607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry) { 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> resource_entry = 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResourceEntry::CreateFrom(*entry); 46790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_SUCCESS, base::Passed(&resource_entry))); 4707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 47490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, base::Passed(&null))); 4777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 480bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochCancelCallback FakeDriveService::GetShareUrl( 481bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const std::string& resource_id, 482bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const GURL& /* embed_origin */, 483bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const GetShareUrlCallback& callback) { 484bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 485bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DCHECK(!callback.is_null()); 486bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 487bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (offline_) { 488bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch scoped_ptr<ResourceEntry> null; 489bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::MessageLoop::current()->PostTask( 490bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch FROM_HERE, 491bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::Bind(callback, 492bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch GDATA_NO_CONNECTION, 493bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch GURL())); 494bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch return CancelCallback(); 495bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 496bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 497bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 498bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (entry) { 499bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Share urls are stored in the resource entry, and they do not rely on the 500bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // embedding origin. 501bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch scoped_ptr<ResourceEntry> resource_entry = 502bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch ResourceEntry::CreateFrom(*entry); 503bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const Link* share_url = resource_entry->GetLinkByType(Link::LINK_SHARE); 504bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (share_url) { 505bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::MessageLoop::current()->PostTask( 506bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch FROM_HERE, 507bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::Bind(callback, HTTP_SUCCESS, share_url->href())); 508bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } else { 509bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::MessageLoop::current()->PostTask( 510bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch FROM_HERE, 511bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::Bind(callback, HTTP_SUCCESS, GURL())); 512bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 513bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch return CancelCallback(); 514bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 515bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 516bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch scoped_ptr<ResourceEntry> null; 517bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::MessageLoop::current()->PostTask( 518bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch FROM_HERE, 519bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::Bind(callback, HTTP_NOT_FOUND, GURL())); 520bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch return CancelCallback(); 521bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 522bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 5237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetAboutResource( 524424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const AboutResourceCallback& callback) { 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AboutResource> null; 53090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, base::Passed(&null))); 5347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++about_resource_load_count_; 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AboutResource> about_resource( 539d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) util::ConvertAccountMetadataToAboutResource( 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *AccountMetadata::CreateFrom(*account_metadata_value_), 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRootResourceId())); 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Overwrite the change id. 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) about_resource->set_largest_change_id(largest_changestamp_); 54490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HTTP_SUCCESS, base::Passed(&about_resource))); 5487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 551424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)CancelCallback FakeDriveService::GetAppList(const AppListCallback& callback) { 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 55490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(app_info_value_); 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AppList> null; 55890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&null))); 5637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch ++app_list_load_count_; 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AppList> app_list(AppList::CreateFrom(*app_info_value_)); 56890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_SUCCESS, base::Passed(&app_list))); 5717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::DeleteResource( 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& etag, 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const EntryActionCallback& callback) { 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 58290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, GDATA_NO_CONNECTION)); 5847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* entries = NULL; 588d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) { 589d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 590d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) base::DictionaryValue* entry = NULL; 591d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) std::string current_resource_id; 592d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (entries->GetDictionary(i, &entry) && 593d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) entry->GetString("gd$resourceId.$t", ¤t_resource_id) && 594d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) resource_id == current_resource_id) { 595d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (entry->HasKey("docs$removed")) { 596d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) base::MessageLoop::current()->PostTask( 597d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND)); 598d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) return CancelCallback(); 599d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) } 600d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 601d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) std::string entry_etag; 602d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) entry->GetString("gd$etag", &entry_etag); 603d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (!etag.empty() && entry_etag != etag) { 604d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) base::MessageLoop::current()->PostTask( 605d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_PRECONDITION)); 606d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) return CancelCallback(); 607d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) } 608d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 609d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) entry->Set("docs$removed", new DictionaryValue); 610d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) AddNewChangestamp(entry); 611d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) ClearPropatiesForPermanentDelete(entry); 612d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) base::MessageLoop::current()->PostTask( 613d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_NO_CONTENT)); 614d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) return CancelCallback(); 615d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) } 616d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) } 617d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) } 618d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 619d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) base::MessageLoop::current()->PostTask( 620d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND)); 621d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) return CancelCallback(); 622d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)} 623d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 624d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)CancelCallback FakeDriveService::TrashResource( 625d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) const std::string& resource_id, 626d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) const EntryActionCallback& callback) { 627d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 628d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) DCHECK(!callback.is_null()); 629d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 630d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (offline_) { 631d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) base::MessageLoop::current()->PostTask( 632d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) FROM_HERE, base::Bind(callback, GDATA_NO_CONNECTION)); 633d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) return CancelCallback(); 634d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) } 635d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 636d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) base::ListValue* entries = NULL; 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Go through entries and remove the one that matches |resource_id|. 638868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) { 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = NULL; 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string current_resource_id; 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entries->GetDictionary(i, &entry) && 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("gd$resourceId.$t", ¤t_resource_id) && 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_id == current_resource_id) { 645eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 646d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (entry->HasKey("gd$deleted") || entry->HasKey("docs$removed")) { 647eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch error = HTTP_NOT_FOUND; 648eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 649eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry->Set("gd$deleted", new DictionaryValue); 650a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AddNewChangestamp(entry); 651eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch error = HTTP_SUCCESS; 652eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 65390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 654eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FROM_HERE, base::Bind(callback, error)); 6557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 66090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND)); 6627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::DownloadFile( 6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& local_cache_path, 667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& resource_id, 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DownloadActionCallback& download_action_callback, 669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetContentCallback& get_content_callback, 670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ProgressCallback& progress_callback) { 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!download_action_callback.is_null()); 6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 67590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(download_action_callback, 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath())); 6807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The field content.src is the URL to download the file. 684eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!entry) { 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(download_action_callback, HTTP_NOT_FOUND, base::FilePath())); 6897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Write "x"s of the file size specified in the entry. 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string file_size_string; 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("docs$size.$t", &file_size_string); 6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 file_size = 0; 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (base::StringToInt64(file_size_string, &file_size)) { 69790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::BinaryValue* content_binary_data; 69890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string content_data; 69990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (entry->GetBinary("test$data", &content_binary_data)) { 70090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content_data = std::string(content_binary_data->GetBuffer(), 70190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content_binary_data->GetSize()); 70290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 70390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_EQ(static_cast<size_t>(file_size), content_data.size()); 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!get_content_callback.is_null()) { 706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int64 kBlockSize = 5; 707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (int64 i = 0; i < file_size; i += kBlockSize) { 708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int64 size = std::min(kBlockSize, file_size - i); 709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<std::string> content_for_callback( 71090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new std::string(content_data.substr(i, size))); 711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(get_content_callback, HTTP_SUCCESS, 714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&content_for_callback))); 715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 71890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (test_util::WriteStringToFile(local_cache_path, content_data)) { 719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!progress_callback.is_null()) { 720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // See also the comment in ResumeUpload(). For testing that clients 721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // can handle the case progress_callback is called multiple times, 722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // here we invoke the callback twice. 723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(progress_callback, file_size / 2, file_size)); 726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 727c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(progress_callback, file_size, file_size)); 729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(download_action_callback, 7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HTTP_SUCCESS, 7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_cache_path)); 7357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Failed to write the content. 7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(download_action_callback, GDATA_FILE_ERROR, base::FilePath())); 7437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::CopyResource( 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 74890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& in_parent_resource_id, 7497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& new_title, 75068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const base::Time& last_modified, 7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetResourceEntryCallback& callback) { 7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 75790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, 7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&null))); 7627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 76590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& parent_resource_id = in_parent_resource_id.empty() ? 76690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetRootResourceId() : in_parent_resource_id; 76790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* entries = NULL; 7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Go through entries and copy the one that matches |resource_id|. 770868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) { 7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = NULL; 7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string current_resource_id; 7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entries->GetDictionary(i, &entry) && 7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("gd$resourceId.$t", ¤t_resource_id) && 77690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) resource_id == current_resource_id) { 77790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Make a copy and set the new resource ID and the new title. 77890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<DictionaryValue> copied_entry(entry->DeepCopy()); 77990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) copied_entry->SetString("gd$resourceId.$t", 78090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) resource_id + "_copied"); 7817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch copied_entry->SetString("title.$t", new_title); 78290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 78390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Reset parent directory. 78490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::ListValue* links = NULL; 7853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!copied_entry->GetList("link", &links)) { 78690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) links = new base::ListValue; 7873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) copied_entry->Set("link", links); 7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 78990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) links->Clear(); 79090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 79190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::DictionaryValue* link = new base::DictionaryValue; 79290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) link->SetString( 79390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "rel", "http://schemas.google.com/docs/2007#parent"); 79490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) link->SetString("href", GetFakeLinkUrl(parent_resource_id).spec()); 79590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) links->Append(link); 79690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 79768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!last_modified.is_null()) { 79868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) copied_entry->SetString( 79968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "updated.$t", 80068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) google_apis::util::FormatTimeAsString(last_modified)); 80168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 80268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 803a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AddNewChangestamp(copied_entry.get()); 804a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) UpdateETag(copied_entry.get()); 80590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 80690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Parse the new entry. 80790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<ResourceEntry> resource_entry = 80890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ResourceEntry::CreateFrom(*copied_entry); 80990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Add it to the resource list. 81090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entries->Append(copied_entry.release()); 81190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 81290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 81390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, 81490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(callback, 81590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) HTTP_SUCCESS, 81690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Passed(&resource_entry))); 8177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 82390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, base::Passed(&null))); 8267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 829f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)CancelCallback FakeDriveService::UpdateResource( 8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 8313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& parent_resource_id, 8327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& new_title, 83368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const base::Time& last_modified, 834f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const base::Time& last_viewed_by_me, 8353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const google_apis::GetResourceEntryCallback& callback) { 8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 84090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 8413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FROM_HERE, base::Bind(callback, GDATA_NO_CONNECTION, 8423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Passed(scoped_ptr<ResourceEntry>()))); 8437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry) { 8487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch entry->SetString("title.$t", new_title); 8493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 8503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Set parent if necessary. 8513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!parent_resource_id.empty()) { 8523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::ListValue* links = NULL; 8533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!entry->GetList("link", &links)) { 8543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) links = new base::ListValue; 8553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) entry->Set("link", links); 8563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 8573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 8583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Remove old parent(s). 8593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (size_t i = 0; i < links->GetSize(); ) { 8603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::DictionaryValue* link = NULL; 8613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string rel; 8623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string href; 8633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (links->GetDictionary(i, &link) && 8643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) link->GetString("rel", &rel) && 8653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) link->GetString("href", &href) && 8663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) rel == "http://schemas.google.com/docs/2007#parent") { 8673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) links->Remove(i, NULL); 8683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 8693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ++i; 8703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 8713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 8723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 8733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::DictionaryValue* link = new base::DictionaryValue; 8743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) link->SetString("rel", "http://schemas.google.com/docs/2007#parent"); 8753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) link->SetString( 8763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "href", GetFakeLinkUrl(parent_resource_id).spec()); 8773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) links->Append(link); 8783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 8793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 88068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!last_modified.is_null()) { 88168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) entry->SetString( 88268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "updated.$t", 88368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) google_apis::util::FormatTimeAsString(last_modified)); 88468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 88568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 886f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!last_viewed_by_me.is_null()) { 887f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) entry->SetString( 888f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "gd$lastViewed.$t", 889f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) google_apis::util::FormatTimeAsString(last_viewed_by_me)); 890f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 891f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 892a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AddNewChangestamp(entry); 893a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) UpdateETag(entry); 8943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 8953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Parse the new entry. 8963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<ResourceEntry> resource_entry = 8973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ResourceEntry::CreateFrom(*entry); 89890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 8993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FROM_HERE, 9003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(callback, HTTP_SUCCESS, base::Passed(&resource_entry))); 9017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 90490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FROM_HERE, 9063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, 9073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Passed(scoped_ptr<ResourceEntry>()))); 9087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)CancelCallback FakeDriveService::RenameResource( 9123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& resource_id, 9133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& new_title, 9143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const EntryActionCallback& callback) { 9153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 9163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(!callback.is_null()); 9173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 918f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return UpdateResource( 919f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) resource_id, std::string(), new_title, base::Time(), base::Time(), 9203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&EntryActionCallbackAdapter, callback)); 9213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 9223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 9237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::AddResourceToDirectory( 9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& parent_resource_id, 9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const EntryActionCallback& callback) { 9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 93190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, GDATA_NO_CONNECTION)); 9337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry) { 9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* links = NULL; 9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!entry->GetList("link", &links)) { 9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) links = new base::ListValue; 9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->Set("link", links); 9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // On the real Drive server, resources do not necessary shape a tree 9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // structure. That is, each resource can have multiple parent. 9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We mimic the behavior here; AddResourceToDirectoy just adds 9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // one more parent link, not overwriting old links. 9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* link = new base::DictionaryValue; 9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) link->SetString("rel", "http://schemas.google.com/docs/2007#parent"); 9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) link->SetString( 9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "href", GetFakeLinkUrl(parent_resource_id).spec()); 9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) links->Append(link); 9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 954a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AddNewChangestamp(entry); 95590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_SUCCESS)); 9577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 96090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND)); 9627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::RemoveResourceFromDirectory( 9662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& parent_resource_id, 9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const EntryActionCallback& callback) { 9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 97390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, GDATA_NO_CONNECTION)); 9757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry) { 9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* links = NULL; 9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry->GetList("link", &links)) { 9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL parent_content_url = GetFakeLinkUrl(parent_resource_id); 9832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < links->GetSize(); ++i) { 9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* link = NULL; 9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string rel; 9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string href; 9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (links->GetDictionary(i, &link) && 9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) link->GetString("rel", &rel) && 9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) link->GetString("href", &href) && 9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rel == "http://schemas.google.com/docs/2007#parent" && 9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL(href) == parent_content_url) { 9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) links->Remove(i, NULL); 993a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AddNewChangestamp(entry); 99490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 995a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_NO_CONTENT)); 9967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 100290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND)); 10047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::AddNewDirectory( 10082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& parent_resource_id, 10097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& directory_title, 10102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetResourceEntryCallback& callback) { 10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 10132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 10152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 101690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDATA_NO_CONNECTION, 10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&null))); 10217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1024c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char kContentType[] = "application/atom+xml;type=feed"; 1025c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::DictionaryValue* new_entry = AddNewEntry(kContentType, 102690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "", // content_data 1027c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parent_resource_id, 10287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch directory_title, 1029c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) false, // shared_with_me 1030c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "folder"); 1031c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!new_entry) { 1032c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 103390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1034c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1035c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, base::Passed(&null))); 10367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1039c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> parsed_entry(ResourceEntry::CreateFrom(*new_entry)); 104090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 1042c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_CREATED, base::Passed(&parsed_entry))); 10437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::InitiateUploadNewFile( 10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& content_type, 10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 content_length, 10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& parent_resource_id, 10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& title, 10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const InitiateUploadCallback& callback) { 10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 10542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 105690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, GDATA_NO_CONNECTION, GURL())); 10597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1062eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (parent_resource_id != GetRootResourceId() && 1063eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch !FindEntryByResourceId(parent_resource_id)) { 106490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 10662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, GURL())); 10677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1069eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1070eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL session_url = GetNewUploadSessionUrl(); 1071eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch upload_sessions_[session_url] = 1072eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UploadSession(content_type, content_length, 1073eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch parent_resource_id, 1074eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "", // resource_id 1075eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "", // etag 1076eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch title); 10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 107890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 1080eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(callback, HTTP_SUCCESS, session_url)); 10817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::InitiateUploadExistingFile( 10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& content_type, 10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 content_length, 10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& etag, 10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const InitiateUploadCallback& callback) { 10902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 10912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 109490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, GDATA_NO_CONNECTION, GURL())); 10977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 10982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DictionaryValue* entry = FindEntryByResourceId(resource_id); 11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!entry) { 110290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, GURL())); 11057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 11062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string entry_etag; 11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("gd$etag", &entry_etag); 1110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!etag.empty() && etag != entry_etag) { 111190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, HTTP_PRECONDITION, GURL())); 11147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL session_url = GetNewUploadSessionUrl(); 1118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch upload_sessions_[session_url] = 1119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UploadSession(content_type, content_length, 1120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "", // parent_resource_id 1121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch resource_id, 1122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry_etag, 1123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "" /* title */); 11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 112590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 1127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(callback, HTTP_SUCCESS, session_url)); 11287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetUploadStatus( 11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& upload_url, 11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 content_length, 11342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const UploadRangeCallback& callback) { 11352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 11362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 11377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 11382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 11392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::ResumeUpload( 11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& upload_url, 11422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 start_position, 11432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 end_position, 11442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 content_length, 11452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& content_type, 1146a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const base::FilePath& local_file_path, 1147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const UploadRangeCallback& callback, 1148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ProgressCallback& progress_callback) { 11492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 11502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 11512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GetResourceEntryCallback completion_callback 1153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch = base::Bind(&ScheduleUploadRangeCallback, 1154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback, start_position, end_position); 11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (offline_) { 1157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(GDATA_NO_CONNECTION, scoped_ptr<ResourceEntry>()); 11587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 11592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!upload_sessions_.count(upload_url)) { 1162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_NOT_FOUND, scoped_ptr<ResourceEntry>()); 11637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UploadSession* session = &upload_sessions_[upload_url]; 1167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Chunks are required to be sent in such a ways that they fill from the start 1169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // of the not-yet-uploaded part with no gaps nor overlaps. 1170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (session->uploaded_size != start_position) { 1171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_BAD_REQUEST, scoped_ptr<ResourceEntry>()); 11727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 1173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!progress_callback.is_null()) { 1176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // In the real GDataWapi/Drive DriveService, progress is reported in 1177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // nondeterministic timing. In this fake implementation, we choose to call 1178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // it twice per one ResumeUpload. This is for making sure that client code 1179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // works fine even if the callback is invoked more than once; it is the 1180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // crucial difference of the progress callback from others. 1181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Note that progress is notified in the relative offset in each chunk. 1182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int64 chunk_size = end_position - start_position; 118390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, base::Bind(progress_callback, chunk_size / 2, chunk_size)); 118590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, base::Bind(progress_callback, chunk_size, chunk_size)); 1187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 11892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (content_length != end_position) { 1190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->uploaded_size = end_position; 1191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_RESUME_INCOMPLETE, 1192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<ResourceEntry>()); 11937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 11942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string content_data; 119758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!base::ReadFileToString(local_file_path, &content_data)) { 1198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->uploaded_size = end_position; 1199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(GDATA_FILE_ERROR, scoped_ptr<ResourceEntry>()); 1200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return CancelCallback(); 1201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->uploaded_size = end_position; 1203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // |resource_id| is empty if the upload is for new file. 1205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (session->resource_id.empty()) { 1206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(!session->parent_resource_id.empty()); 1207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(!session->title.empty()); 1208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const DictionaryValue* new_entry = AddNewEntry( 1209eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->content_type, 1210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch content_data, 1211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->parent_resource_id, 1212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->title, 1213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch false, // shared_with_me 1214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "file"); 1215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!new_entry) { 1216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_NOT_FOUND, scoped_ptr<ResourceEntry>()); 1217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return CancelCallback(); 1218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 12192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_CREATED, 1221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ResourceEntry::CreateFrom(*new_entry)); 1222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return CancelCallback(); 1223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DictionaryValue* entry = FindEntryByResourceId(session->resource_id); 1226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!entry) { 1227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_NOT_FOUND, scoped_ptr<ResourceEntry>()); 1228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return CancelCallback(); 1229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 123090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1231eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string entry_etag; 1232eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry->GetString("gd$etag", &entry_etag); 1233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (entry_etag.empty() || session->etag != entry_etag) { 1234eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_PRECONDITION, scoped_ptr<ResourceEntry>()); 1235eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return CancelCallback(); 1236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 12372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry->SetString("docs$md5Checksum.$t", base::MD5String(content_data)); 1239eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry->Set("test$data", 1240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::BinaryValue::CreateWithCopiedBuffer( 1241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch content_data.data(), content_data.size())); 1242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry->SetString("docs$size.$t", base::Int64ToString(end_position)); 1243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AddNewChangestamp(entry); 1244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) UpdateETag(entry); 1245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch completion_callback.Run(HTTP_SUCCESS, ResourceEntry::CreateFrom(*entry)); 12477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 12492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::AuthorizeApp( 12517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& resource_id, 12527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& app_id, 12537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const AuthorizeAppCallback& callback) { 12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 12552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 12567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return CancelCallback(); 12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 12582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 125958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)CancelCallback FakeDriveService::GetResourceListInDirectoryByWapi( 126058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& directory_resource_id, 126158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const google_apis::GetResourceListCallback& callback) { 126258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return GetResourceListInDirectory( 126358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) directory_resource_id == util::kWapiRootDirectoryResourceId ? 126458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GetRootResourceId() : 126558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) directory_resource_id, 126658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) callback); 126758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 126858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 126958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)CancelCallback FakeDriveService::GetRemainingResourceList( 127058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const GURL& next_link, 127158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const google_apis::GetResourceListCallback& callback) { 127258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 127358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(!next_link.is_empty()); 127458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(!callback.is_null()); 127558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 127658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // "changestamp", "q", "parent" and "start-offset" are parameters to 127758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // implement "paging" of the result on FakeDriveService. 127858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The URL should be the one filled in GetResourceListInternal of the 127958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // previous method invocation, so it should start with "http://localhost/?". 128058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // See also GetResourceListInternal. 128158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK_EQ(next_link.host(), "localhost"); 128258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK_EQ(next_link.path(), "/"); 128358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 128458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int64 start_changestamp = 0; 128558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string search_query; 128658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string directory_resource_id; 128758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int start_offset = 0; 128858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int max_results = default_max_results_; 128958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::vector<std::pair<std::string, std::string> > parameters; 129058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (base::SplitStringIntoKeyValuePairs( 129158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) next_link.query(), '=', '&', ¶meters)) { 129258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (size_t i = 0; i < parameters.size(); ++i) { 129358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (parameters[i].first == "changestamp") { 129458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::StringToInt64(parameters[i].second, &start_changestamp); 129558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else if (parameters[i].first == "q") { 129658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) search_query = 129758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) net::UnescapeURLComponent(parameters[i].second, 129858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) net::UnescapeRule::URL_SPECIAL_CHARS); 129958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else if (parameters[i].first == "parent") { 130058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) directory_resource_id = 130158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) net::UnescapeURLComponent(parameters[i].second, 130258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) net::UnescapeRule::URL_SPECIAL_CHARS); 130358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else if (parameters[i].first == "start-offset") { 130458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::StringToInt(parameters[i].second, &start_offset); 130558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else if (parameters[i].first == "max-results") { 130658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::StringToInt(parameters[i].second, &max_results); 130758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 130858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 130958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 131058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 131158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GetResourceListInternal( 131258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) start_changestamp, search_query, directory_resource_id, 131358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) start_offset, max_results, NULL, callback); 131458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return CancelCallback(); 131558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 131658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void FakeDriveService::AddNewFile(const std::string& content_type, 131890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& content_data, 1319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& parent_resource_id, 1320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& title, 1321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool shared_with_me, 1322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetResourceEntryCallback& callback) { 1323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 1325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (offline_) { 1327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 132890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, 1331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GDATA_NO_CONNECTION, 1332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&null))); 1333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Prepare "kind" for hosted documents. This only supports Google Document. 1337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string entry_kind; 1338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (content_type == "application/vnd.google-apps.document") 1339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry_kind = "document"; 1340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 1341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry_kind = "file"; 1342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::DictionaryValue* new_entry = AddNewEntry(content_type, 134490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content_data, 1345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parent_resource_id, 1346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) title, 1347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shared_with_me, 1348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry_kind); 1349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!new_entry) { 1350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 135190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, base::Passed(&null))); 1354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> parsed_entry( 1358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceEntry::CreateFrom(*new_entry)); 135990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_CREATED, base::Passed(&parsed_entry))); 1362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void FakeDriveService::SetLastModifiedTime( 1365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& resource_id, 1366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Time& last_modified_time, 1367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetResourceEntryCallback& callback) { 1368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 1370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (offline_) { 1372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 137390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, 1376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GDATA_NO_CONNECTION, 1377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&null))); 1378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* entry = FindEntryByResourceId(resource_id); 1382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!entry) { 1383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> null; 138490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_NOT_FOUND, base::Passed(&null))); 1387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (last_modified_time.is_null()) { 1391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry->Remove("updated.$t", NULL); 1392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 139358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) entry->SetString( 139458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "updated.$t", 139558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) google_apis::util::FormatTimeAsString(last_modified_time)); 1396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> parsed_entry( 1399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceEntry::CreateFrom(*entry)); 140090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, HTTP_SUCCESS, base::Passed(&parsed_entry))); 1403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 14052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::DictionaryValue* FakeDriveService::FindEntryByResourceId( 14062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id) { 14072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 14082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* entries = NULL; 14102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Go through entries and return the one that matches |resource_id|. 1411868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) { 14122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 14132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = NULL; 14142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string current_resource_id; 14152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entries->GetDictionary(i, &entry) && 14162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("gd$resourceId.$t", ¤t_resource_id) && 14172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_id == current_resource_id) { 14182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return entry; 14192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 14202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 14212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 14222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 14242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 14252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::DictionaryValue* FakeDriveService::FindEntryByContentUrl( 14272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& content_url) { 14282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 14292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* entries = NULL; 14312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Go through entries and return the one that matches |content_url|. 1432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) { 14332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < entries->GetSize(); ++i) { 14342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* entry = NULL; 14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string current_content_url; 14362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entries->GetDictionary(i, &entry) && 14372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetString("content.src", ¤t_content_url) && 14382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_url == GURL(current_content_url)) { 14392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return entry; 14402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 14412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 14422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 14432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 14452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 14462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string FakeDriveService::GetNewResourceId() { 14482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 14492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++resource_id_count_; 14512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::StringPrintf("resource_id_%d", resource_id_count_); 14522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 14532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1454a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void FakeDriveService::UpdateETag(base::DictionaryValue* entry) { 1455a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) entry->SetString("gd$etag", 1456a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "etag_" + base::Int64ToString(largest_changestamp_)); 1457a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 1458a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1459a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void FakeDriveService::AddNewChangestamp(base::DictionaryValue* entry) { 14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++largest_changestamp_; 14612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->SetString("docs$changestamp.value", 14622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Int64ToString(largest_changestamp_)); 14632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 14642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::DictionaryValue* FakeDriveService::AddNewEntry( 1466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& content_type, 146790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& content_data, 1468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& parent_resource_id, 1469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& title, 1470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool shared_with_me, 1471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& entry_kind) { 1472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1474d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!parent_resource_id.empty() && 1475d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) parent_resource_id != GetRootResourceId() && 1476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !FindEntryByResourceId(parent_resource_id)) { 1477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return NULL; 1478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string resource_id = GetNewResourceId(); 1481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL upload_url = GURL("https://xxx/upload/" + resource_id); 1482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::DictionaryValue> new_entry(new base::DictionaryValue); 1484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Set the resource ID and the title 1485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->SetString("gd$resourceId.$t", resource_id); 1486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->SetString("title.$t", title); 1487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->SetString("docs$filename", title); 148890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Set the contents, size and MD5 for a file. 1489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (entry_kind == "file") { 149090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new_entry->Set("test$data", 149190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::BinaryValue::CreateWithCopiedBuffer( 149290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content_data.c_str(), content_data.size())); 149390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new_entry->SetString("docs$size.$t", 149490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Int64ToString(content_data.size())); 1495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->SetString("docs$md5Checksum.$t", 1496eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::MD5String(content_data)); 1497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add "category" which sets the resource type to |entry_kind|. 1500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue* categories = new base::ListValue; 1501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* category = new base::DictionaryValue; 1502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) category->SetString("scheme", "http://schemas.google.com/g/2005#kind"); 1503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) category->SetString("term", "http://schemas.google.com/docs/2007#" + 1504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry_kind); 1505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) categories->Append(category); 1506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->Set("category", categories); 1507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (shared_with_me) { 1508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* shared_with_me_label = new base::DictionaryValue; 1509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shared_with_me_label->SetString("label", "shared-with-me"); 1510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shared_with_me_label->SetString("scheme", 1511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://schemas.google.com/g/2005/labels"); 1512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shared_with_me_label->SetString( 1513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "term", "http://schemas.google.com/g/2005/labels#shared"); 1514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) categories->Append(shared_with_me_label); 1515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1517868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string escaped_resource_id = net::EscapePath(resource_id); 1518868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add "content" which sets the content URL. 1520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* content = new base::DictionaryValue; 1521868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) content->SetString("src", "https://xxx/content/" + escaped_resource_id); 1522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content->SetString("type", content_type); 1523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->Set("content", content); 1524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add "link" which sets the parent URL, the edit URL and the upload URL. 1526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue* links = new base::ListValue; 1527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* parent_link = new base::DictionaryValue; 1529d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (parent_resource_id.empty()) 1530d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) parent_link->SetString("href", GetFakeLinkUrl(GetRootResourceId()).spec()); 1531d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) else 1532d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) parent_link->SetString("href", GetFakeLinkUrl(parent_resource_id).spec()); 1533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parent_link->SetString("rel", 1534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://schemas.google.com/docs/2007#parent"); 1535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) links->Append(parent_link); 1536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* edit_link = new base::DictionaryValue; 1538868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) edit_link->SetString("href", "https://xxx/edit/" + escaped_resource_id); 1539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) edit_link->SetString("rel", "edit"); 1540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) links->Append(edit_link); 1541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* upload_link = new base::DictionaryValue; 1543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) upload_link->SetString("href", upload_url.spec()); 1544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) upload_link->SetString("rel", kUploadUrlRel); 1545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) links->Append(upload_link); 15462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 15472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const GURL share_url = net::AppendOrReplaceQueryParameter( 15482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch share_url_base_, "name", title); 15492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch base::DictionaryValue* share_link = new base::DictionaryValue; 15502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch upload_link->SetString("href", share_url.spec()); 15512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch upload_link->SetString("rel", kShareUrlRel); 15522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch links->Append(share_link); 1553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_entry->Set("link", links); 1554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1555a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AddNewChangestamp(new_entry.get()); 1556a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) UpdateETag(new_entry.get()); 1557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 15587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Time published_date = 15597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Time() + base::TimeDelta::FromMilliseconds(++published_date_seq_); 156058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) new_entry->SetString( 156158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "published.$t", 156258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) google_apis::util::FormatTimeAsString(published_date)); 15637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If there are no entries, prepare an empty entry to add. 1565868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!resource_list_value_->HasKey("entry")) 1566868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) resource_list_value_->Set("entry", new ListValue); 1567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* raw_new_entry = new_entry.release(); 1569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue* entries = NULL; 1570868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (resource_list_value_->GetList("entry", &entries)) 1571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entries->Append(raw_new_entry); 1572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return raw_new_entry; 1574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void FakeDriveService::GetResourceListInternal( 1577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 start_changestamp, 1578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& search_query, 1579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& directory_resource_id, 1580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int start_offset, 1581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int max_results, 1582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int* load_counter, 1583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetResourceListCallback& callback) { 1584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (offline_) { 158590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(callback, 1588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GDATA_NO_CONNECTION, 15897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Passed(scoped_ptr<ResourceList>()))); 1590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceList> resource_list = 1594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceList::CreateFrom(*resource_list_value_); 1595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 15967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // TODO(hashimoto): Drive API always provides largest changestamp. Remove this 15977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // if-statement after API switch. 15987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (start_changestamp > 0 && start_offset == 0) 15997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch resource_list->set_largest_changestamp(largest_changestamp_); 16007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Filter out entries per parameters like |directory_resource_id| and 1602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |search_query|. 1603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ScopedVector<ResourceEntry>* entries = resource_list->mutable_entries(); 1604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int num_entries_matched = 0; 1606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < entries->size();) { 1607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceEntry* entry = (*entries)[i]; 1608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool should_exclude = false; 1609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If |directory_resource_id| is set, exclude the entry if it's not in 1611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // the target directory. 1612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!directory_resource_id.empty()) { 1613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Get the parent resource ID of the entry. 1614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string parent_resource_id; 1615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const google_apis::Link* parent_link = 1616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry->GetLinkByType(Link::LINK_PARENT); 1617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (parent_link) { 1618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parent_resource_id = 1619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::UnescapeURLComponent(parent_link->href().ExtractFileName(), 1620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::UnescapeRule::URL_SPECIAL_CHARS); 1621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (directory_resource_id != parent_resource_id) 1623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_exclude = true; 1624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If |search_query| is set, exclude the entry if it does not contain the 1627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // search query in the title. 1628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!should_exclude && !search_query.empty() && 1629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !EntryMatchWithQuery(*entry, search_query)) { 1630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_exclude = true; 1631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If |start_changestamp| is set, exclude the entry if the 1634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // changestamp is older than |largest_changestamp|. 1635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // See https://developers.google.com/google-apps/documents-list/ 1636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // #retrieving_all_changes_since_a_given_changestamp 1637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (start_changestamp > 0 && entry->changestamp() < start_changestamp) 1638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_exclude = true; 1639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1640eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // If the caller requests other list than change list by specifying 1641eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // zero-|start_changestamp|, exclude deleted entry from the result. 1642eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!start_changestamp && entry->deleted()) 1643eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch should_exclude = true; 1644eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The entry matched the criteria for inclusion. 1646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!should_exclude) 1647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ++num_entries_matched; 1648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If |start_offset| is set, exclude the entry if the entry is before the 1650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // start index. <= instead of < as |num_entries_matched| was 1651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // already incremented. 1652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (start_offset > 0 && num_entries_matched <= start_offset) 1653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_exclude = true; 1654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (should_exclude) 1656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entries->erase(entries->begin() + i); 1657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 1658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ++i; 1659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If |max_results| is set, trim the entries if the number exceeded the max 1662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // results. 1663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (max_results > 0 && entries->size() > static_cast<size_t>(max_results)) { 1664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entries->erase(entries->begin() + max_results, entries->end()); 1665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Adds the next URL. 1666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Here, we embed information which is needed for continuing the 1667868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // GetResourceList request in the next invocation into url query 1668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // parameters. 1669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL next_url(base::StringPrintf( 1670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://localhost/?start-offset=%d&max-results=%d", 1671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) start_offset + max_results, 1672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) max_results)); 1673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (start_changestamp > 0) { 1674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url = net::AppendOrReplaceQueryParameter( 1675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url, "changestamp", 1676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Int64ToString(start_changestamp).c_str()); 1677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!search_query.empty()) { 1679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url = net::AppendOrReplaceQueryParameter( 1680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url, "q", search_query); 1681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!directory_resource_id.empty()) { 1683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url = net::AppendOrReplaceQueryParameter( 1684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_url, "parent", directory_resource_id); 1685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Link* link = new Link; 1688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) link->set_type(Link::LINK_NEXT); 1689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) link->set_href(next_url); 1690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) resource_list->mutable_links()->push_back(link); 1691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (load_counter) 1694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *load_counter += 1; 169590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 16977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(callback, HTTP_SUCCESS, base::Passed(&resource_list))); 1698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1700eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochGURL FakeDriveService::GetNewUploadSessionUrl() { 1701eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return GURL("https://upload_session_url/" + 1702eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Int64ToString(next_upload_sequence_number_++)); 1703eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 1704eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1705eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace drive 1706