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)
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "base/json/json_string_value_serializer.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/md5.h"
139ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_tokenizer.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/values.h"
2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/drive/drive_api_util.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/drive_api_parser.h"
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/test_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::AppList;
32424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::AppListCallback;
337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing google_apis::AuthStatusCallback;
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::AuthorizeAppCallback;
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::CancelCallback;
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using google_apis::ChangeList;
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using google_apis::ChangeListCallback;
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using google_apis::ChangeResource;
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::DownloadActionCallback;
40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::EntryActionCallback;
4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)using google_apis::FileList;
4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)using google_apis::FileListCallback;
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using google_apis::FileResource;
4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)using google_apis::FileResourceCallback;
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_FILE_ERROR;
46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_NO_CONNECTION;
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_OTHER_ERROR;
48424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::GDataErrorCode;
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetContentCallback;
50bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochusing google_apis::GetShareUrlCallback;
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_BAD_REQUEST;
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_CREATED;
536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)using google_apis::HTTP_FORBIDDEN;
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_NOT_FOUND;
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using google_apis::HTTP_NO_CONTENT;
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_PRECONDITION;
57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_RESUME_INCOMPLETE;
58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_SUCCESS;
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::InitiateUploadCallback;
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using google_apis::ParentReference;
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ProgressCallback;
62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::UploadRangeResponse;
6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)using google_apis::drive::UploadRangeCallback;
64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace test_util = google_apis::test_util;
65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace drive {
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Returns true if the entry matches with the search query.
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Supports queries consist of following format.
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Phrases quoted by double/single quotes
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - AND search for multiple words/phrases segmented by space
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Limited attribute search.  Only "title:" is supported.
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool EntryMatchWithQuery(const ChangeResource& entry,
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         const std::string& query) {
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::StringTokenizer tokenizer(query, " ");
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tokenizer.set_quote_chars("\"'");
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (tokenizer.GetNext()) {
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string key, value;
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& token = tokenizer.token();
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (token.find(':') == std::string::npos) {
82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::TrimString(token, "\"'", &value);
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::StringTokenizer key_value(token, ":");
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      key_value.set_quote_chars("\"'");
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!key_value.GetNext())
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return false;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      key = key_value.token();
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!key_value.GetNext())
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return false;
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::TrimString(key_value.token(), "\"'", &value);
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(peria): Deal with other attributes than title.
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!key.empty() && key != "title")
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Search query in the title.
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!entry.file() ||
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        entry.file()->title().find(value) == std::string::npos)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ScheduleUploadRangeCallback(const UploadRangeCallback& callback,
106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                 int64 start_position,
107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                 int64 end_position,
108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                 GDataErrorCode error,
10946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                 scoped_ptr<FileResource> entry) {
110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::MessageLoop::current()->PostTask(
111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(callback,
113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 UploadRangeResponse(error,
114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                     start_position,
115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                     end_position),
116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 base::Passed(&entry)));
117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void FileListCallbackAdapter(const FileListCallback& callback,
12046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                             GDataErrorCode error,
12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                             scoped_ptr<ChangeList> change_list) {
12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<FileList> file_list;
12303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!change_list) {
12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    callback.Run(error, file_list.Pass());
12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return;
12603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
12703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
12803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  file_list.reset(new FileList);
12903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  file_list->set_next_link(change_list->next_link());
13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  for (size_t i = 0; i < change_list->items().size(); ++i) {
13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const ChangeResource& entry = *change_list->items()[i];
13203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (entry.file())
13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      file_list->mutable_items()->push_back(new FileResource(*entry.file()));
13446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
13546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  callback.Run(error, file_list.Pass());
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool UserHasWriteAccess(google_apis::drive::PermissionRole user_permission) {
1396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  switch (user_permission) {
1406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    case google_apis::drive::PERMISSION_ROLE_OWNER:
1416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    case google_apis::drive::PERMISSION_ROLE_WRITER:
1426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      return true;
1436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    case google_apis::drive::PERMISSION_ROLE_READER:
1446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    case google_apis::drive::PERMISSION_ROLE_COMMENTER:
1456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      break;
1466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return false;
1486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
1496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct FakeDriveService::EntryInfo {
1536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EntryInfo() : user_permission(google_apis::drive::PERMISSION_ROLE_OWNER) {}
1546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  google_apis::ChangeResource change_resource;
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GURL share_url;
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string content_data;
1586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Behaves in the same way as "userPermission" described in
1606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // https://developers.google.com/drive/v2/reference/files
1616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  google_apis::drive::PermissionRole user_permission;
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstruct FakeDriveService::UploadSession {
165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string content_type;
166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int64 content_length;
167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string parent_resource_id;
168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string resource_id;
169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string etag;
170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string title;
171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int64 uploaded_size;
173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  UploadSession()
175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      : content_length(0),
176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        uploaded_size(0) {}
177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  UploadSession(
179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      std::string content_type,
180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      int64 content_length,
181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      std::string parent_resource_id,
182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      std::string resource_id,
183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      std::string etag,
184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      std::string title)
185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    : content_type(content_type),
186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      content_length(content_length),
187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      parent_resource_id(parent_resource_id),
188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      resource_id(resource_id),
189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      etag(etag),
190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      title(title),
191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      uploaded_size(0) {
192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch};
194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FakeDriveService::FakeDriveService()
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : about_resource_(new AboutResource),
1977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      published_date_seq_(0),
198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      next_upload_sequence_number_(0),
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      default_max_results_(0),
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      resource_id_count_(0),
20146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      file_list_load_count_(0),
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      change_list_load_count_(0),
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      directory_load_count_(0),
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      about_resource_load_count_(0),
2052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      app_list_load_count_(0),
20646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      blocked_file_list_load_count_(0),
20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      offline_(false),
20846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      never_return_all_file_list_(false),
20903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      share_url_base_("https://share_url/"),
21003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      weak_ptr_factory_(this) {
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
212c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
213c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  about_resource_->set_largest_change_id(654321);
214c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  about_resource_->set_quota_bytes_total(9876543210);
215c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  about_resource_->set_quota_bytes_used(6789012345);
216c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  about_resource_->set_root_folder_id(GetRootResourceId());
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FakeDriveService::~FakeDriveService() {
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  STLDeleteValues(&entries_);
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FakeDriveService::LoadAppListForDriveApi(
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& relative_path) {
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Load JSON data, which must be a dictionary.
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<base::Value> value = test_util::LoadJSONFile(relative_path);
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK_EQ(base::Value::TYPE_DICTIONARY, value->GetType());
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  app_info_value_.reset(
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      static_cast<base::DictionaryValue*>(value.release()));
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return app_info_value_;
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
235ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void FakeDriveService::AddApp(const std::string& app_id,
2376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                              const std::string& app_name,
2386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                              const std::string& product_id,
2396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                              const std::string& create_url) {
2406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (app_json_template_.empty()) {
2416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    base::FilePath path =
2426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        test_util::GetTestFilePath("drive/applist_app_template.json");
2436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    CHECK(base::ReadFileToString(path, &app_json_template_));
2446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
2456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  std::string app_json = app_json_template_;
2476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ReplaceSubstringsAfterOffset(&app_json, 0, "$AppId", app_id);
2486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ReplaceSubstringsAfterOffset(&app_json, 0, "$AppName", app_name);
2496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ReplaceSubstringsAfterOffset(&app_json, 0, "$ProductId", product_id);
2506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ReplaceSubstringsAfterOffset(&app_json, 0, "$CreateUrl", create_url);
2516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  JSONStringValueSerializer json(app_json);
2536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  std::string error_message;
2546d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_ptr<base::Value> value(json.Deserialize(NULL, &error_message));
2556d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  CHECK_EQ(base::Value::TYPE_DICTIONARY, value->GetType());
2566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  base::ListValue* item_list;
2586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  CHECK(app_info_value_->GetListWithoutPathExpansion("items", &item_list));
2596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  item_list->Append(value.release());
2606d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
2616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2626d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void FakeDriveService::RemoveAppByProductId(const std::string& product_id) {
2636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  base::ListValue* item_list;
2646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  CHECK(app_info_value_->GetListWithoutPathExpansion("items", &item_list));
2656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  for (size_t i = 0; i < item_list->GetSize(); ++i) {
2666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    base::DictionaryValue* item;
2676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    CHECK(item_list->GetDictionary(i, &item));
2686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const char kKeyProductId[] = "productId";
2696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    std::string item_product_id;
2706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    if (item->GetStringWithoutPathExpansion(kKeyProductId, &item_product_id) &&
2716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        product_id == item_product_id) {
2726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      item_list->Remove(i, NULL);
2736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      return;
2746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    }
2756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
2766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
2776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)bool FakeDriveService::HasApp(const std::string& app_id) const {
2796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  base::ListValue* item_list;
2806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  CHECK(app_info_value_->GetListWithoutPathExpansion("items", &item_list));
2816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  for (size_t i = 0; i < item_list->GetSize(); ++i) {
2826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    base::DictionaryValue* item;
2836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    CHECK(item_list->GetDictionary(i, &item));
2846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const char kKeyId[] = "id";
2856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    std::string item_id;
2866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    if (item->GetStringWithoutPathExpansion(kKeyId, &item_id) &&
2876d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        item_id == app_id) {
2886d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      return true;
2896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    }
2906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
2916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  return false;
2936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
2946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
295ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid FakeDriveService::SetQuotaValue(int64 used, int64 total) {
296ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
297ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  about_resource_->set_quota_bytes_used(used);
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  about_resource_->set_quota_bytes_total(total);
300ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GURL FakeDriveService::GetFakeLinkUrl(const std::string& resource_id) {
303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return GURL("https://fake_server/" + net::EscapePath(resource_id));
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void FakeDriveService::Initialize(const std::string& account_id) {
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FakeDriveService::AddObserver(DriveServiceObserver* observer) {
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FakeDriveService::RemoveObserver(DriveServiceObserver* observer) {
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool FakeDriveService::CanSendRequest() const {
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FakeDriveService::HasAccessToken() const {
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FakeDriveService::RequestAccessToken(const AuthStatusCallback& callback) {
3297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(!callback.is_null());
3317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  callback.Run(google_apis::HTTP_NOT_MODIFIED, "fake_access_token");
3327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
3337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FakeDriveService::HasRefreshToken() const {
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FakeDriveService::ClearAccessToken() {
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FakeDriveService::ClearRefreshToken() {
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string FakeDriveService::GetRootResourceId() const {
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return "fake_root";
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)CancelCallback FakeDriveService::GetAllFileList(
35246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const FileListCallback& callback) {
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!callback.is_null());
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
35646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (never_return_all_file_list_) {
35746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ++blocked_file_list_load_count_;
35858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return CancelCallback();
35958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
36058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
36146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GetChangeListInternal(0,  // start changestamp
36246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        std::string(),  // empty search query
36346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        std::string(),  // no directory resource id,
36446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        0,  // start offset
36546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        default_max_results_,
36646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        &file_list_load_count_,
36746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        base::Bind(&FileListCallbackAdapter, callback));
3687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return CancelCallback();
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
37146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)CancelCallback FakeDriveService::GetFileListInDirectory(
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& directory_resource_id,
37346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const FileListCallback& callback) {
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!directory_resource_id.empty());
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GetChangeListInternal(0,  // start changestamp
37946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        std::string(),  // empty search query
38046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        directory_resource_id,
38146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        0,  // start offset
38246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        default_max_results_,
38346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        &directory_load_count_,
38446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        base::Bind(&FileListCallbackAdapter, callback));
3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return CancelCallback();
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::Search(
3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& search_query,
39046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const FileListCallback& callback) {
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!search_query.empty());
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!callback.is_null());
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
39546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GetChangeListInternal(0,  // start changestamp
39646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        search_query,
39746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        std::string(),  // no directory resource id,
39846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        0,  // start offset
39946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        default_max_results_,
40046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        NULL,
40146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        base::Bind(&FileListCallbackAdapter, callback));
4027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return CancelCallback();
403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::SearchByTitle(
406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& title,
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& directory_resource_id,
40846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const FileListCallback& callback) {
409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!title.empty());
411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!callback.is_null());
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Note: the search implementation here doesn't support quotation unescape,
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // so don't escape here.
41546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GetChangeListInternal(0,  // start changestamp
41646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        base::StringPrintf("title:'%s'", title.c_str()),
41746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        directory_resource_id,
41846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        0,  // start offset
41946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        default_max_results_,
42046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        NULL,
42146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        base::Bind(&FileListCallbackAdapter, callback));
4227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return CancelCallback();
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetChangeList(
4267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    int64 start_changestamp,
427cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ChangeListCallback& callback) {
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!callback.is_null());
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
43146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GetChangeListInternal(start_changestamp,
43246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        std::string(),  // empty search query
43346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        std::string(),  // no directory resource id,
43446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        0,  // start offset
43546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        default_max_results_,
43646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        &change_list_load_count_,
43746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        callback);
4387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return CancelCallback();
439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
441424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)CancelCallback FakeDriveService::GetRemainingChangeList(
44258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const GURL& next_link,
443cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ChangeListCallback& callback) {
444424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
44558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(!next_link.is_empty());
446424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!callback.is_null());
447424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
4484ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  // "changestamp", "q", "parent" and "start-offset" are parameters to
4494ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  // implement "paging" of the result on FakeDriveService.
45046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // The URL should be the one filled in GetChangeListInternal of the
4514ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  // previous method invocation, so it should start with "http://localhost/?".
45246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // See also GetChangeListInternal.
4534ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  DCHECK_EQ(next_link.host(), "localhost");
4544ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  DCHECK_EQ(next_link.path(), "/");
4554ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch
4564ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  int64 start_changestamp = 0;
4574ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  std::string search_query;
4584ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  std::string directory_resource_id;
4594ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  int start_offset = 0;
4604ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  int max_results = default_max_results_;
4611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::StringPairs parameters;
4624ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  if (base::SplitStringIntoKeyValuePairs(
4634ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch          next_link.query(), '=', '&', &parameters)) {
4644ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch    for (size_t i = 0; i < parameters.size(); ++i) {
4654ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch      if (parameters[i].first == "changestamp") {
4664ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch        base::StringToInt64(parameters[i].second, &start_changestamp);
4674ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch      } else if (parameters[i].first == "q") {
4684ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch        search_query =
4694ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch            net::UnescapeURLComponent(parameters[i].second,
4704ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch                                      net::UnescapeRule::URL_SPECIAL_CHARS);
4714ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch      } else if (parameters[i].first == "parent") {
4724ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch        directory_resource_id =
4734ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch            net::UnescapeURLComponent(parameters[i].second,
4744ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch                                      net::UnescapeRule::URL_SPECIAL_CHARS);
4754ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch      } else if (parameters[i].first == "start-offset") {
4764ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch        base::StringToInt(parameters[i].second, &start_offset);
4774ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch      } else if (parameters[i].first == "max-results") {
4784ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch        base::StringToInt(parameters[i].second, &max_results);
4794ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch      }
4804ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch    }
4814ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  }
4824ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch
48346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GetChangeListInternal(start_changestamp, search_query, directory_resource_id,
48446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        start_offset, max_results, NULL, callback);
4854ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  return CancelCallback();
486424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
487424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
488424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)CancelCallback FakeDriveService::GetRemainingFileList(
48958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const GURL& next_link,
49046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const FileListCallback& callback) {
491424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
49258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(!next_link.is_empty());
493424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!callback.is_null());
494424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
495cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return GetRemainingChangeList(
49646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      next_link, base::Bind(&FileListCallbackAdapter, callback));
497424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
498424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
49946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)CancelCallback FakeDriveService::GetFileResource(
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
50146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const FileResourceCallback& callback) {
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (offline_) {
50690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE,
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(callback,
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   GDATA_NO_CONNECTION,
51046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   base::Passed(scoped_ptr<FileResource>())));
5117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EntryInfo* entry = FindEntryByResourceId(resource_id);
51546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (entry && entry->change_resource.file()) {
51690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE,
51846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        base::Bind(callback, HTTP_SUCCESS, base::Passed(make_scoped_ptr(
51946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            new FileResource(*entry->change_resource.file())))));
5207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
52546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(callback, HTTP_NOT_FOUND,
52646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Passed(scoped_ptr<FileResource>())));
5277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return CancelCallback();
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
530bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochCancelCallback FakeDriveService::GetShareUrl(
531bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    const std::string& resource_id,
532bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    const GURL& /* embed_origin */,
533bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    const GetShareUrlCallback& callback) {
534bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
535bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  DCHECK(!callback.is_null());
536bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
537bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  if (offline_) {
538bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    base::MessageLoop::current()->PostTask(
539bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch        FROM_HERE,
540bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch        base::Bind(callback,
541bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch                   GDATA_NO_CONNECTION,
542bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch                   GURL()));
543bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    return CancelCallback();
544bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  }
545bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EntryInfo* entry = FindEntryByResourceId(resource_id);
547bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  if (entry) {
5485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::MessageLoop::current()->PostTask(
5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        FROM_HERE,
5505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(callback, HTTP_SUCCESS, entry->share_url));
551bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    return CancelCallback();
552bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  }
553bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
554bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  base::MessageLoop::current()->PostTask(
555bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      FROM_HERE,
556bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      base::Bind(callback, HTTP_NOT_FOUND, GURL()));
557bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  return CancelCallback();
558bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}
559bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
5607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetAboutResource(
561424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const AboutResourceCallback& callback) {
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (offline_) {
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<AboutResource> null;
56790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE,
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(callback,
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   GDATA_NO_CONNECTION, base::Passed(&null)));
5717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ++about_resource_load_count_;
5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<AboutResource> about_resource(new AboutResource(*about_resource_));
57690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(callback,
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 HTTP_SUCCESS, base::Passed(&about_resource)));
5807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return CancelCallback();
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
583424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)CancelCallback FakeDriveService::GetAppList(const AppListCallback& callback) {
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
58690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(app_info_value_);
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (offline_) {
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<AppList> null;
59090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE,
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(callback,
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   GDATA_NO_CONNECTION,
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   base::Passed(&null)));
5957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ++app_list_load_count_;
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<AppList> app_list(AppList::CreateFrom(*app_info_value_));
60090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(callback, HTTP_SUCCESS, base::Passed(&app_list)));
6037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return CancelCallback();
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::DeleteResource(
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& etag,
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const EntryActionCallback& callback) {
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (offline_) {
61490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE, base::Bind(callback, GDATA_NO_CONNECTION));
6167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EntryInfo* entry = FindEntryByResourceId(resource_id);
62003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!entry) {
62103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    base::MessageLoop::current()->PostTask(
62203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND));
62303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return CancelCallback();
62403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
62603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ChangeResource* change = &entry->change_resource;
62703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const FileResource* file = change->file();
62803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (change->is_deleted()) {
62903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    base::MessageLoop::current()->PostTask(
63003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND));
63103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return CancelCallback();
63203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
63403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!etag.empty() && etag != file->etag()) {
63503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    base::MessageLoop::current()->PostTask(
63603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        FROM_HERE, base::Bind(callback, HTTP_PRECONDITION));
63703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return CancelCallback();
63803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
6396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
64003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (entry->user_permission != google_apis::drive::PERMISSION_ROLE_OWNER) {
6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::MessageLoop::current()->PostTask(
64203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        FROM_HERE, base::Bind(callback, HTTP_FORBIDDEN));
6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return CancelCallback();
6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
64603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  change->set_deleted(true);
64703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  AddNewChangestamp(change);
64803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  change->set_file(scoped_ptr<FileResource>());
6495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoop::current()->PostTask(
65003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      FROM_HERE, base::Bind(callback, HTTP_NO_CONTENT));
65103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  base::MessageLoop::current()->PostTask(
65203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      FROM_HERE,
65303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Bind(&FakeDriveService::NotifyObservers,
65403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
6555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return CancelCallback();
6565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CancelCallback FakeDriveService::TrashResource(
6595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& resource_id,
6605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const EntryActionCallback& callback) {
6615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
6625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!callback.is_null());
6635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (offline_) {
6655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::MessageLoop::current()->PostTask(
6665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        FROM_HERE, base::Bind(callback, GDATA_NO_CONNECTION));
6675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return CancelCallback();
6685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
6695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EntryInfo* entry = FindEntryByResourceId(resource_id);
67103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!entry) {
6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::MessageLoop::current()->PostTask(
67303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND));
6745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return CancelCallback();
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
67703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ChangeResource* change = &entry->change_resource;
67803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  FileResource* file = change->mutable_file();
67903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (change->is_deleted() || file->labels().is_trashed()) {
68003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    base::MessageLoop::current()->PostTask(
68103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND));
68203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return CancelCallback();
68303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
68403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
68503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (entry->user_permission != google_apis::drive::PERMISSION_ROLE_OWNER) {
68603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    base::MessageLoop::current()->PostTask(
68703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        FROM_HERE, base::Bind(callback, HTTP_FORBIDDEN));
68803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return CancelCallback();
68903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
69003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
69103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  file->mutable_labels()->set_trashed(true);
69203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  AddNewChangestamp(change);
69390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
69403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      FROM_HERE, base::Bind(callback, HTTP_SUCCESS));
69503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  base::MessageLoop::current()->PostTask(
69603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      FROM_HERE,
69703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Bind(&FakeDriveService::NotifyObservers,
69803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
6997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return CancelCallback();
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::DownloadFile(
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& local_cache_path,
704eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::string& resource_id,
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DownloadActionCallback& download_action_callback,
706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GetContentCallback& get_content_callback,
707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ProgressCallback& progress_callback) {
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!download_action_callback.is_null());
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (offline_) {
71290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE,
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(download_action_callback,
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   GDATA_NO_CONNECTION,
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   base::FilePath()));
7177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EntryInfo* entry = FindEntryByResourceId(resource_id);
7215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!entry || entry->change_resource.file()->IsHostedDocument()) {
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::MessageLoopProxy::current()->PostTask(
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE,
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(download_action_callback, HTTP_NOT_FOUND, base::FilePath()));
7257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const FileResource* file = entry->change_resource.file();
7295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const std::string& content_data = entry->content_data;
7305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 file_size = file->file_size();
7315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(static_cast<size_t>(file_size), content_data.size());
7325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!get_content_callback.is_null()) {
7345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const int64 kBlockSize = 5;
7355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (int64 i = 0; i < file_size; i += kBlockSize) {
7365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const int64 size = std::min(kBlockSize, file_size - i);
7375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      scoped_ptr<std::string> content_for_callback(
7385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          new std::string(content_data.substr(i, size)));
7395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::MessageLoopProxy::current()->PostTask(
7405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          FROM_HERE,
7415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::Bind(get_content_callback, HTTP_SUCCESS,
7425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     base::Passed(&content_for_callback)));
743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
7445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
74603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!test_util::WriteStringToFile(local_cache_path, content_data)) {
74703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // Failed to write the content.
7485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::MessageLoopProxy::current()->PostTask(
7495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        FROM_HERE,
7505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(download_action_callback,
75103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   GDATA_FILE_ERROR, base::FilePath()));
7525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return CancelCallback();
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
75503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!progress_callback.is_null()) {
75603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // See also the comment in ResumeUpload(). For testing that clients
75703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // can handle the case progress_callback is called multiple times,
75803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // here we invoke the callback twice.
75903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    base::MessageLoopProxy::current()->PostTask(
76003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        FROM_HERE,
76103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        base::Bind(progress_callback, file_size / 2, file_size));
76203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    base::MessageLoopProxy::current()->PostTask(
76303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        FROM_HERE,
76403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        base::Bind(progress_callback, file_size, file_size));
76503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::MessageLoopProxy::current()->PostTask(
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
76803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Bind(download_action_callback,
76903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 HTTP_SUCCESS,
77003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 local_cache_path));
7717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return CancelCallback();
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::CopyResource(
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
77690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& in_parent_resource_id,
7777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& new_title,
77868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const base::Time& last_modified,
77946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const FileResourceCallback& callback) {
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (offline_) {
78490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE,
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(callback,
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   GDATA_NO_CONNECTION,
78846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   base::Passed(scoped_ptr<FileResource>())));
7897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
79290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const std::string& parent_resource_id = in_parent_resource_id.empty() ?
79390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GetRootResourceId() : in_parent_resource_id;
79490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EntryInfo* entry = FindEntryByResourceId(resource_id);
79603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!entry) {
7975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::MessageLoop::current()->PostTask(
7985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        FROM_HERE,
79903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        base::Bind(callback, HTTP_NOT_FOUND,
80003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   base::Passed(scoped_ptr<FileResource>())));
8015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return CancelCallback();
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
80403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Make a copy and set the new resource ID and the new title.
80503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<EntryInfo> copied_entry(new EntryInfo);
80603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  copied_entry->content_data = entry->content_data;
80703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  copied_entry->share_url = entry->share_url;
80803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  copied_entry->change_resource.set_file(
80903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      make_scoped_ptr(new FileResource(*entry->change_resource.file())));
81003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
81103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ChangeResource* new_change = &copied_entry->change_resource;
81203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  FileResource* new_file = new_change->mutable_file();
81303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const std::string new_resource_id = GetNewResourceId();
81403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  new_change->set_file_id(new_resource_id);
81503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  new_file->set_file_id(new_resource_id);
81603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  new_file->set_title(new_title);
81703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
81803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ParentReference parent;
81903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  parent.set_file_id(parent_resource_id);
82003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  parent.set_parent_link(GetFakeLinkUrl(parent_resource_id));
82103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::vector<ParentReference> parents;
82203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  parents.push_back(parent);
82303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  *new_file->mutable_parents() = parents;
82403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
82503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!last_modified.is_null())
82603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    new_file->set_modified_date(last_modified);
82703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
82803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  AddNewChangestamp(new_change);
82903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  UpdateETag(new_file);
83003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
83103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Add the new entry to the map.
83203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  entries_[new_resource_id] = copied_entry.release();
83303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
83490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
83603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Bind(callback,
83703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 HTTP_SUCCESS,
83803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 base::Passed(make_scoped_ptr(new FileResource(*new_file)))));
83903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  base::MessageLoop::current()->PostTask(
84003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      FROM_HERE,
84103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Bind(&FakeDriveService::NotifyObservers,
84203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
8437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return CancelCallback();
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
846f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)CancelCallback FakeDriveService::UpdateResource(
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
8483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const std::string& parent_resource_id,
8497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& new_title,
85068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const base::Time& last_modified,
851f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::Time& last_viewed_by_me,
85246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const google_apis::FileResourceCallback& callback) {
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (offline_) {
85790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
8583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        FROM_HERE, base::Bind(callback, GDATA_NO_CONNECTION,
85946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                              base::Passed(scoped_ptr<FileResource>())));
8607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EntryInfo* entry = FindEntryByResourceId(resource_id);
86403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!entry) {
86503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    base::MessageLoop::current()->PostTask(
86603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        FROM_HERE,
86703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        base::Bind(callback, HTTP_NOT_FOUND,
86803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   base::Passed(scoped_ptr<FileResource>())));
86903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return CancelCallback();
87003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
8716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
87203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!UserHasWriteAccess(entry->user_permission)) {
87303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    base::MessageLoop::current()->PostTask(
87403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        FROM_HERE,
87503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        base::Bind(callback, HTTP_FORBIDDEN,
87603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   base::Passed(scoped_ptr<FileResource>())));
87703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return CancelCallback();
87803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
8790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
88003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ChangeResource* change = &entry->change_resource;
88103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  FileResource* file = change->mutable_file();
8823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
88303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!new_title.empty())
88403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    file->set_title(new_title);
885effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
88603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Set parent if necessary.
88703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!parent_resource_id.empty()) {
88803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    ParentReference parent;
88903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    parent.set_file_id(parent_resource_id);
89003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    parent.set_parent_link(GetFakeLinkUrl(parent_resource_id));
8913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
89203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    std::vector<ParentReference> parents;
89303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    parents.push_back(parent);
89403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    *file->mutable_parents() = parents;
89503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
89668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
89703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!last_modified.is_null())
89803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    file->set_modified_date(last_modified);
899f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
90003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!last_viewed_by_me.is_null())
90103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    file->set_last_viewed_by_me_date(last_viewed_by_me);
9023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
90303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  AddNewChangestamp(change);
90403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  UpdateETag(file);
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
90690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
9073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      FROM_HERE,
90803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Bind(callback, HTTP_SUCCESS,
90903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 base::Passed(make_scoped_ptr(new FileResource(*file)))));
91003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  base::MessageLoop::current()->PostTask(
91103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      FROM_HERE,
91203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Bind(&FakeDriveService::NotifyObservers,
91303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
9147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return CancelCallback();
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::AddResourceToDirectory(
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& parent_resource_id,
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const EntryActionCallback& callback) {
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (offline_) {
92590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE, base::Bind(callback, GDATA_NO_CONNECTION));
9277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EntryInfo* entry = FindEntryByResourceId(resource_id);
93103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!entry) {
93290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
93303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND));
9347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
93703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ChangeResource* change = &entry->change_resource;
93803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // On the real Drive server, resources do not necessary shape a tree
93903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // structure. That is, each resource can have multiple parent.
94003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // We mimic the behavior here; AddResourceToDirectoy just adds
94103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // one more parent, not overwriting old ones.
94203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ParentReference parent;
94303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  parent.set_file_id(parent_resource_id);
94403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  parent.set_parent_link(GetFakeLinkUrl(parent_resource_id));
94503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  change->mutable_file()->mutable_parents()->push_back(parent);
94603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
94703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  AddNewChangestamp(change);
94890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
94903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      FROM_HERE, base::Bind(callback, HTTP_SUCCESS));
95003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  base::MessageLoop::current()->PostTask(
95103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      FROM_HERE,
95203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Bind(&FakeDriveService::NotifyObservers,
95303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
9547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return CancelCallback();
9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::RemoveResourceFromDirectory(
9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& parent_resource_id,
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const EntryActionCallback& callback) {
9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (offline_) {
96590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
9662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE, base::Bind(callback, GDATA_NO_CONNECTION));
9677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EntryInfo* entry = FindEntryByResourceId(resource_id);
97103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!entry) {
97203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    base::MessageLoop::current()->PostTask(
97303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND));
97403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return CancelCallback();
97503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
97603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
97703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ChangeResource* change = &entry->change_resource;
97803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  FileResource* file = change->mutable_file();
97903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::vector<ParentReference>* parents = file->mutable_parents();
98003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  for (size_t i = 0; i < parents->size(); ++i) {
98103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if ((*parents)[i].file_id() == parent_resource_id) {
98203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      parents->erase(parents->begin() + i);
98303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      AddNewChangestamp(change);
98403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::MessageLoop::current()->PostTask(
98503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          FROM_HERE, base::Bind(callback, HTTP_NO_CONTENT));
98603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::MessageLoop::current()->PostTask(
98703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          FROM_HERE,
98803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          base::Bind(&FakeDriveService::NotifyObservers,
98903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                     weak_ptr_factory_.GetWeakPtr()));
99003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return CancelCallback();
9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
99490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND));
9967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return CancelCallback();
9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::AddNewDirectory(
10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& parent_resource_id,
10017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& directory_title,
10025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const AddNewDirectoryOptions& options,
100346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const FileResourceCallback& callback) {
10040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return AddNewDirectoryWithResourceId(
10050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      "",
10060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      parent_resource_id.empty() ? GetRootResourceId() : parent_resource_id,
10070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      directory_title,
10080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      options,
10090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      callback);
10102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::InitiateUploadNewFile(
10132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& content_type,
10142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 content_length,
10152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& parent_resource_id,
10162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& title,
10175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const InitiateUploadNewFileOptions& options,
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const InitiateUploadCallback& callback) {
10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (offline_) {
102390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE,
10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(callback, GDATA_NO_CONNECTION, GURL()));
10267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1029eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (parent_resource_id != GetRootResourceId() &&
10305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      !entries_.count(parent_resource_id)) {
103190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE,
10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(callback, HTTP_NOT_FOUND, GURL()));
10347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1036eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1037eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  GURL session_url = GetNewUploadSessionUrl();
1038eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  upload_sessions_[session_url] =
1039eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      UploadSession(content_type, content_length,
1040eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                    parent_resource_id,
1041eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                    "",  // resource_id
1042eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                    "",  // etag
1043eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                    title);
10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
104590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
1047eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(callback, HTTP_SUCCESS, session_url));
10487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return CancelCallback();
10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::InitiateUploadExistingFile(
10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& content_type,
10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 content_length,
10542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
10555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const InitiateUploadExistingFileOptions& options,
10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const InitiateUploadCallback& callback) {
10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (offline_) {
106190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE,
10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(callback, GDATA_NO_CONNECTION, GURL()));
10647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EntryInfo* entry = FindEntryByResourceId(resource_id);
10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!entry) {
106990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE,
10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(callback, HTTP_NOT_FOUND, GURL()));
10727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!UserHasWriteAccess(entry->user_permission)) {
10766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    base::MessageLoop::current()->PostTask(
10776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        FROM_HERE,
10786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        base::Bind(callback, HTTP_FORBIDDEN, GURL()));
10796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return CancelCallback();
10806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
10816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
10825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FileResource* file = entry->change_resource.mutable_file();
10835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!options.etag.empty() && options.etag != file->etag()) {
108490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE,
10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(callback, HTTP_PRECONDITION, GURL()));
10877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(hashimoto): Update |file|'s metadata with |options|.
10902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1091eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  GURL session_url = GetNewUploadSessionUrl();
1092eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  upload_sessions_[session_url] =
1093eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      UploadSession(content_type, content_length,
1094eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                    "",  // parent_resource_id
1095eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                    resource_id,
10965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    file->etag(),
1097eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                    "" /* title */);
10982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
109990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
1101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(callback, HTTP_SUCCESS, session_url));
11027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return CancelCallback();
11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::GetUploadStatus(
11062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& upload_url,
11072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 content_length,
11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const UploadRangeCallback& callback) {
11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
11117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return CancelCallback();
11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::ResumeUpload(
11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const GURL& upload_url,
11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int64 start_position,
11172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int64 end_position,
11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int64 content_length,
11192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& content_type,
1120a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      const base::FilePath& local_file_path,
1121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const UploadRangeCallback& callback,
1122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const ProgressCallback& progress_callback) {
11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
11252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
112646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  FileResourceCallback completion_callback
1127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      = base::Bind(&ScheduleUploadRangeCallback,
1128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                   callback, start_position, end_position);
11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (offline_) {
113146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    completion_callback.Run(GDATA_NO_CONNECTION, scoped_ptr<FileResource>());
11327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!upload_sessions_.count(upload_url)) {
113646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    completion_callback.Run(HTTP_NOT_FOUND, scoped_ptr<FileResource>());
11377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
11382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  UploadSession* session = &upload_sessions_[upload_url];
1141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Chunks are required to be sent in such a ways that they fill from the start
1143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // of the not-yet-uploaded part with no gaps nor overlaps.
1144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (session->uploaded_size != start_position) {
114546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    completion_callback.Run(HTTP_BAD_REQUEST, scoped_ptr<FileResource>());
11467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
1147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!progress_callback.is_null()) {
1150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // In the real GDataWapi/Drive DriveService, progress is reported in
1151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // nondeterministic timing. In this fake implementation, we choose to call
1152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // it twice per one ResumeUpload. This is for making sure that client code
1153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // works fine even if the callback is invoked more than once; it is the
1154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // crucial difference of the progress callback from others.
1155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Note that progress is notified in the relative offset in each chunk.
1156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const int64 chunk_size = end_position - start_position;
115790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
1158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        FROM_HERE, base::Bind(progress_callback, chunk_size / 2, chunk_size));
115990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
1160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        FROM_HERE, base::Bind(progress_callback, chunk_size, chunk_size));
1161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (content_length != end_position) {
1164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    session->uploaded_size = end_position;
116546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    completion_callback.Run(HTTP_RESUME_INCOMPLETE, scoped_ptr<FileResource>());
11667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
11672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string content_data;
117058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!base::ReadFileToString(local_file_path, &content_data)) {
1171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    session->uploaded_size = end_position;
117246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    completion_callback.Run(GDATA_FILE_ERROR, scoped_ptr<FileResource>());
1173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return CancelCallback();
1174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
1175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session->uploaded_size = end_position;
1176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // |resource_id| is empty if the upload is for new file.
1178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (session->resource_id.empty()) {
1179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    DCHECK(!session->parent_resource_id.empty());
1180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    DCHECK(!session->title.empty());
11815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const EntryInfo* new_entry = AddNewEntry(
1182effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        "",  // auto generate resource id.
1183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        session->content_type,
1184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        content_data,
1185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        session->parent_resource_id,
1186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        session->title,
11875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        false);  // shared_with_me
1188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (!new_entry) {
118946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      completion_callback.Run(HTTP_NOT_FOUND, scoped_ptr<FileResource>());
1190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return CancelCallback();
1191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
119346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    completion_callback.Run(HTTP_CREATED, make_scoped_ptr(
119446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        new FileResource(*new_entry->change_resource.file())));
119503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    base::MessageLoop::current()->PostTask(
119603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        FROM_HERE,
119703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        base::Bind(&FakeDriveService::NotifyObservers,
119803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
1199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return CancelCallback();
1200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
1201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EntryInfo* entry = FindEntryByResourceId(session->resource_id);
1203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!entry) {
120446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    completion_callback.Run(HTTP_NOT_FOUND, scoped_ptr<FileResource>());
1205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return CancelCallback();
1206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
120790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
12085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ChangeResource* change = &entry->change_resource;
12095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FileResource* file = change->mutable_file();
12105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (file->etag().empty() || session->etag != file->etag()) {
121146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    completion_callback.Run(HTTP_PRECONDITION, scoped_ptr<FileResource>());
1212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return CancelCallback();
1213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  file->set_md5_checksum(base::MD5String(content_data));
12165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  entry->content_data = content_data;
12175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  file->set_file_size(end_position);
12185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AddNewChangestamp(change);
12195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UpdateETag(file);
1220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
122146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  completion_callback.Run(HTTP_SUCCESS, make_scoped_ptr(
122246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      new FileResource(*file)));
122303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  base::MessageLoop::current()->PostTask(
122403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      FROM_HERE,
122503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Bind(&FakeDriveService::NotifyObservers,
122603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
12277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return CancelCallback();
12282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback FakeDriveService::AuthorizeApp(
12317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& resource_id,
12327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& app_id,
12337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const AuthorizeAppCallback& callback) {
12342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
1236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (entries_.count(resource_id) == 0) {
1238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    callback.Run(google_apis::HTTP_NOT_FOUND, GURL());
1239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return CancelCallback();
1240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
1241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  callback.Run(HTTP_SUCCESS,
1243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch               GURL(base::StringPrintf(open_url_format_.c_str(),
1244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                       resource_id.c_str(),
1245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                       app_id.c_str())));
12467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return CancelCallback();
12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CancelCallback FakeDriveService::UninstallApp(
12505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& app_id,
12515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const google_apis::EntryActionCallback& callback) {
12525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
12535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!callback.is_null());
12545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (offline_) {
125603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    base::MessageLoop::current()->PostTask(
125703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        FROM_HERE,
125803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        base::Bind(callback, google_apis::GDATA_NO_CONNECTION));
125903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return CancelCallback();
126003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
126103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
126203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Find app_id from app_info_value_ and delete.
126303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  base::ListValue* items = NULL;
126403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!app_info_value_->GetList("items", &items)) {
126503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    base::MessageLoop::current()->PostTask(
126603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        FROM_HERE,
126703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        base::Bind(callback, google_apis::HTTP_NOT_FOUND));
126803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return CancelCallback();
126903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
127003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
127103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  for (size_t i = 0; i < items->GetSize(); ++i) {
127203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    base::DictionaryValue* item = NULL;
127303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    std::string id;
127403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (items->GetDictionary(i, &item) && item->GetString("id", &id) &&
127503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        id == app_id) {
127603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::MessageLoop::current()->PostTask(
127703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          FROM_HERE,
127803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          base::Bind(callback,
127903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                     items->Remove(i, NULL) ? google_apis::HTTP_NO_CONTENT
128003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                            : google_apis::HTTP_NOT_FOUND));
128103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return CancelCallback();
12825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
12835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
12845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
128503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  base::MessageLoop::current()->PostTask(
128603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      FROM_HERE,
128703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Bind(callback, google_apis::HTTP_NOT_FOUND));
12885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return CancelCallback();
12895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
12905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void FakeDriveService::AddNewFile(const std::string& content_type,
129290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  const std::string& content_data,
1293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  const std::string& parent_resource_id,
1294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  const std::string& title,
1295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  bool shared_with_me,
129646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  const FileResourceCallback& callback) {
1297effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  AddNewFileWithResourceId("", content_type, content_data, parent_resource_id,
1298effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                           title, shared_with_me, callback);
1299effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
1300effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1301effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid FakeDriveService::AddNewFileWithResourceId(
1302effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const std::string& resource_id,
1303effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const std::string& content_type,
1304effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const std::string& content_data,
1305effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const std::string& parent_resource_id,
1306effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const std::string& title,
1307effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    bool shared_with_me,
130846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const FileResourceCallback& callback) {
1309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!callback.is_null());
1311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (offline_) {
131390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
1314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        FROM_HERE,
1315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(callback,
1316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   GDATA_NO_CONNECTION,
131746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   base::Passed(scoped_ptr<FileResource>())));
1318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
1319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1321effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const EntryInfo* new_entry = AddNewEntry(resource_id,
1322effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                           content_type,
13235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           content_data,
13245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           parent_resource_id,
13255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           title,
13265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           shared_with_me);
1327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!new_entry) {
132890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
1329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        FROM_HERE,
133046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        base::Bind(callback, HTTP_NOT_FOUND,
133146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   base::Passed(scoped_ptr<FileResource>())));
1332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
1333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
133590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
1336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FROM_HERE,
133746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(callback, HTTP_CREATED,
133846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Passed(make_scoped_ptr(
133946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                     new FileResource(*new_entry->change_resource.file())))));
134003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  base::MessageLoop::current()->PostTask(
134103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      FROM_HERE,
134203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Bind(&FakeDriveService::NotifyObservers,
134303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
1344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
13460529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochCancelCallback FakeDriveService::AddNewDirectoryWithResourceId(
13470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const std::string& resource_id,
13480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const std::string& parent_resource_id,
13490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const std::string& directory_title,
13500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const AddNewDirectoryOptions& options,
135146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const FileResourceCallback& callback) {
13520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
13530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(!callback.is_null());
13540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
13550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (offline_) {
13560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    base::MessageLoop::current()->PostTask(
13570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        FROM_HERE,
13580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        base::Bind(callback,
13590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                   GDATA_NO_CONNECTION,
136046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   base::Passed(scoped_ptr<FileResource>())));
13610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return CancelCallback();
13620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
13630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
13640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const EntryInfo* new_entry = AddNewEntry(resource_id,
13650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                           util::kDriveFolderMimeType,
13660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                           "",  // content_data
13670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                           parent_resource_id,
13680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                           directory_title,
13690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                           false);  // shared_with_me
13700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!new_entry) {
13710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    base::MessageLoop::current()->PostTask(
13720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        FROM_HERE,
137346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        base::Bind(callback, HTTP_NOT_FOUND,
137446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   base::Passed(scoped_ptr<FileResource>())));
13750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return CancelCallback();
13760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
13770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
13780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::MessageLoop::current()->PostTask(
13790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      FROM_HERE,
138046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(callback, HTTP_CREATED,
138146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Passed(make_scoped_ptr(
138246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                     new FileResource(*new_entry->change_resource.file())))));
138303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  base::MessageLoop::current()->PostTask(
138403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      FROM_HERE,
138503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Bind(&FakeDriveService::NotifyObservers,
138603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
13870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return CancelCallback();
13880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
13890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void FakeDriveService::SetLastModifiedTime(
1391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& resource_id,
1392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::Time& last_modified_time,
139346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const FileResourceCallback& callback) {
1394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!callback.is_null());
1396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (offline_) {
139890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
1399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        FROM_HERE,
1400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(callback,
1401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   GDATA_NO_CONNECTION,
140246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   base::Passed(scoped_ptr<FileResource>())));
1403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
1404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
14065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EntryInfo* entry = FindEntryByResourceId(resource_id);
1407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!entry) {
140890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
1409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        FROM_HERE,
141046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        base::Bind(callback, HTTP_NOT_FOUND,
141146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   base::Passed(scoped_ptr<FileResource>())));
1412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
1413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
14155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ChangeResource* change = &entry->change_resource;
14165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FileResource* file = change->mutable_file();
14175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  file->set_modified_date(last_modified_time);
1418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
141990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
1420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FROM_HERE,
142146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(callback, HTTP_SUCCESS,
142246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Passed(make_scoped_ptr(new FileResource(*file)))));
1423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
14256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)google_apis::GDataErrorCode FakeDriveService::SetUserPermission(
14266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const std::string& resource_id,
14276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    google_apis::drive::PermissionRole user_permission) {
14286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
14296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
14306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EntryInfo* entry = FindEntryByResourceId(resource_id);
14316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!entry)
14326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return HTTP_NOT_FOUND;
14336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
14346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry->user_permission = user_permission;
14356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return HTTP_SUCCESS;
14366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
14376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
143803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void FakeDriveService::AddChangeObserver(ChangeObserver* change_observer) {
143903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  change_observers_.AddObserver(change_observer);
144003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
144103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
144203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void FakeDriveService::RemoveChangeObserver(ChangeObserver* change_observer) {
144303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  change_observers_.RemoveObserver(change_observer);
144403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
144503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
14465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)FakeDriveService::EntryInfo* FakeDriveService::FindEntryByResourceId(
14472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id) {
14482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
14492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EntryInfoMap::iterator it = entries_.find(resource_id);
14515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Deleted entries don't have FileResource.
14525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return it != entries_.end() && it->second->change_resource.file() ?
14535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      it->second : NULL;
14542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string FakeDriveService::GetNewResourceId() {
14572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
14582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ++resource_id_count_;
14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::StringPrintf("resource_id_%d", resource_id_count_);
14612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void FakeDriveService::UpdateETag(google_apis::FileResource* file) {
14645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  file->set_etag(
14655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "etag_" + base::Int64ToString(about_resource_->largest_change_id()));
1466a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
1467a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
14685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void FakeDriveService::AddNewChangestamp(google_apis::ChangeResource* change) {
14695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  about_resource_->set_largest_change_id(
14705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      about_resource_->largest_change_id() + 1);
14715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  change->set_change_id(about_resource_->largest_change_id());
14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const FakeDriveService::EntryInfo* FakeDriveService::AddNewEntry(
1475effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const std::string& given_resource_id,
1476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& content_type,
147790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& content_data,
1478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& parent_resource_id,
1479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& title,
14805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool shared_with_me) {
1481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1483d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!parent_resource_id.empty() &&
1484d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      parent_resource_id != GetRootResourceId() &&
14855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      !entries_.count(parent_resource_id)) {
1486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return NULL;
1487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1489effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const std::string resource_id =
1490effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      given_resource_id.empty() ? GetNewResourceId() : given_resource_id;
1491effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (entries_.count(resource_id))
1492effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return NULL;
1493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GURL upload_url = GURL("https://xxx/upload/" + resource_id);
1494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
14955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<EntryInfo> new_entry(new EntryInfo);
14965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ChangeResource* new_change = &new_entry->change_resource;
14975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FileResource* new_file = new FileResource;
14985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  new_change->set_file(make_scoped_ptr(new_file));
14995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Set the resource ID and the title
15015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  new_change->set_file_id(resource_id);
15025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  new_file->set_file_id(resource_id);
15035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  new_file->set_title(title);
150490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Set the contents, size and MD5 for a file.
15055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (content_type != util::kDriveFolderMimeType &&
15065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      !util::IsKnownHostedDocumentMimeType(content_type)) {
15075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    new_entry->content_data = content_data;
15085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    new_file->set_file_size(content_data.size());
15095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    new_file->set_md5_checksum(base::MD5String(content_data));
1510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (shared_with_me) {
15135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Set current time to mark the file as shared_with_me.
15145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    new_file->set_shared_with_me_date(base::Time::Now());
1515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1517868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string escaped_resource_id = net::EscapePath(resource_id);
1518868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1519a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Set mime type.
15205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  new_file->set_mime_type(content_type);
1521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
15225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Set alternate link if needed.
15235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (content_type == util::kGoogleDocumentMimeType)
15245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    new_file->set_alternate_link(GURL("https://document_alternate_link"));
15255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
15265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Set parents.
15270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!parent_resource_id.empty()) {
15280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ParentReference parent;
1529effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    parent.set_file_id(parent_resource_id);
15300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    parent.set_parent_link(GetFakeLinkUrl(parent.file_id()));
15310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    std::vector<ParentReference> parents;
15320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    parents.push_back(parent);
15330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    *new_file->mutable_parents() = parents;
15340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
15355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
15365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  new_entry->share_url = net::AppendOrReplaceQueryParameter(
15372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      share_url_base_, "name", title);
1538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
15395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AddNewChangestamp(new_change);
15405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UpdateETag(new_file);
1541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
15427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::Time published_date =
15437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Time() + base::TimeDelta::FromMilliseconds(++published_date_seq_);
15445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  new_file->set_created_date(published_date);
1545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
15465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EntryInfo* raw_new_entry = new_entry.release();
15475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  entries_[resource_id] = raw_new_entry;
1548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return raw_new_entry;
1549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
155146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void FakeDriveService::GetChangeListInternal(
1552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int64 start_changestamp,
1553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& search_query,
1554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& directory_resource_id,
1555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int start_offset,
1556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int max_results,
1557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int* load_counter,
1558cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ChangeListCallback& callback) {
1559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (offline_) {
156090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
1561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        FROM_HERE,
1562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(callback,
1563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   GDATA_NO_CONNECTION,
1564cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   base::Passed(scoped_ptr<ChangeList>())));
1565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
1566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Filter out entries per parameters like |directory_resource_id| and
1569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // |search_query|.
1570cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ScopedVector<ChangeResource> entries;
1571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int num_entries_matched = 0;
15725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (EntryInfoMap::iterator it = entries_.begin(); it != entries_.end();
15735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       ++it) {
1574cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ChangeResource& entry = it->second->change_resource;
1575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool should_exclude = false;
1576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // If |directory_resource_id| is set, exclude the entry if it's not in
1578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // the target directory.
1579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!directory_resource_id.empty()) {
1580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Get the parent resource ID of the entry.
1581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      std::string parent_resource_id;
1582cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (entry.file() && !entry.file()->parents().empty())
1583cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        parent_resource_id = entry.file()->parents()[0].file_id();
1584cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (directory_resource_id != parent_resource_id)
1586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        should_exclude = true;
1587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
1588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // If |search_query| is set, exclude the entry if it does not contain the
1590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // search query in the title.
1591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!should_exclude && !search_query.empty() &&
1592cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        !EntryMatchWithQuery(entry, search_query)) {
1593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      should_exclude = true;
1594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
1595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // If |start_changestamp| is set, exclude the entry if the
1597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // changestamp is older than |largest_changestamp|.
1598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // See https://developers.google.com/google-apps/documents-list/
1599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // #retrieving_all_changes_since_a_given_changestamp
1600cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (start_changestamp > 0 && entry.change_id() < start_changestamp)
1601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      should_exclude = true;
1602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1603eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // If the caller requests other list than change list by specifying
1604eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // zero-|start_changestamp|, exclude deleted entry from the result.
1605cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const bool deleted = entry.is_deleted() ||
1606cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        (entry.file() && entry.file()->labels().is_trashed());
1607cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!start_changestamp && deleted)
1608eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      should_exclude = true;
1609eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // The entry matched the criteria for inclusion.
1611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!should_exclude)
1612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ++num_entries_matched;
1613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // If |start_offset| is set, exclude the entry if the entry is before the
1615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // start index. <= instead of < as |num_entries_matched| was
1616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // already incremented.
1617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (start_offset > 0 && num_entries_matched <= start_offset)
1618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      should_exclude = true;
1619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1620cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!should_exclude) {
1621cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      scoped_ptr<ChangeResource> entry_copied(new ChangeResource);
1622cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      entry_copied->set_change_id(entry.change_id());
1623cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      entry_copied->set_file_id(entry.file_id());
1624cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      entry_copied->set_deleted(entry.is_deleted());
1625cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (entry.file()) {
1626cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        entry_copied->set_file(
1627cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            make_scoped_ptr(new FileResource(*entry.file())));
1628cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
1629cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      entry_copied->set_modification_date(entry.modification_date());
1630cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      entries.push_back(entry_copied.release());
1631cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
16325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
16335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1634cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<ChangeList> change_list(new ChangeList);
16355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (start_changestamp > 0 && start_offset == 0) {
1636cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    change_list->set_largest_change_id(about_resource_->largest_change_id());
1637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // If |max_results| is set, trim the entries if the number exceeded the max
1640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // results.
16415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (max_results > 0 && entries.size() > static_cast<size_t>(max_results)) {
16425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    entries.erase(entries.begin() + max_results, entries.end());
1643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Adds the next URL.
1644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Here, we embed information which is needed for continuing the
164546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // GetChangeList request in the next invocation into url query
1646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // parameters.
1647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GURL next_url(base::StringPrintf(
1648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        "http://localhost/?start-offset=%d&max-results=%d",
1649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        start_offset + max_results,
1650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        max_results));
1651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (start_changestamp > 0) {
1652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      next_url = net::AppendOrReplaceQueryParameter(
1653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          next_url, "changestamp",
1654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          base::Int64ToString(start_changestamp).c_str());
1655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
1656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!search_query.empty()) {
1657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      next_url = net::AppendOrReplaceQueryParameter(
1658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          next_url, "q", search_query);
1659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
1660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!directory_resource_id.empty()) {
1661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      next_url = net::AppendOrReplaceQueryParameter(
1662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          next_url, "parent", directory_resource_id);
1663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
1664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1665cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    change_list->set_next_link(next_url);
1666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1667cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *change_list->mutable_items() = entries.Pass();
1668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (load_counter)
1670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *load_counter += 1;
167190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
1672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FROM_HERE,
1673cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(callback, HTTP_SUCCESS, base::Passed(&change_list)));
1674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1676eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochGURL FakeDriveService::GetNewUploadSessionUrl() {
1677eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return GURL("https://upload_session_url/" +
1678eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              base::Int64ToString(next_upload_sequence_number_++));
1679eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
1680eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1681a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)google_apis::CancelCallback FakeDriveService::AddPermission(
1682a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& resource_id,
1683a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& email,
1684a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    google_apis::drive::PermissionRole role,
1685a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const google_apis::EntryActionCallback& callback) {
1686a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1687a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!callback.is_null());
1688a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1689a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NOTREACHED();
1690a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return CancelCallback();
1691a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1692a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
169303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void FakeDriveService::NotifyObservers() {
169403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  FOR_EACH_OBSERVER(ChangeObserver, change_observers_, OnNewChangeAvailable());
169503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
169603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1697eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace drive
1698