15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/sync_file_system/sync_file_system_api.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <utility>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/sync_file_system/extension_sync_event_observer.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/sync_file_system/extension_sync_event_observer_factory.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/extensions/api/sync_file_system/sync_file_system_api_helpers.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_service.h"
182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/sync_file_status.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync_file_system/sync_file_system_service.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/sync_file_system/sync_file_system_service_factory.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/api/sync_file_system.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_context.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/storage_partition.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_client.h"
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_context.h"
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_url.h"
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/quota/quota_manager.h"
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/fileapi/file_system_types.h"
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/fileapi/file_system_util.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserContext;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using sync_file_system::ConflictResolutionPolicy;
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using sync_file_system::SyncFileStatus;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using sync_file_system::SyncFileSystemServiceFactory;
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using sync_file_system::SyncStatusCode;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Error messages.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kFileError[] = "File error %d.";
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kQuotaError[] = "Quota error %d.";
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kUnsupportedConflictResolutionPolicy[] =
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "Policy %s is not supported.";
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)sync_file_system::SyncFileSystemService* GetSyncFileSystemService(
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Profile* profile) {
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sync_file_system::SyncFileSystemService* service =
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SyncFileSystemServiceFactory::GetForProfile(profile);
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(service);
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExtensionSyncEventObserver* observer =
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ExtensionSyncEventObserverFactory::GetForProfile(profile);
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(observer);
57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  observer->InitializeForService(service);
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return service;
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncFileSystemDeleteFileSystemFunction::RunImpl() {
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string url;
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &url));
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<fileapi::FileSystemContext> file_system_context =
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserContext::GetStoragePartition(
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          profile(),
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          render_view_host()->GetSiteInstance())->GetFileSystemContext();
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fileapi::FileSystemURL file_system_url(
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      file_system_context->CrackURL(GURL(url)));
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::IO,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Bind(&fileapi::FileSystemContext::DeleteFileSystem,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           file_system_context,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           source_url().GetOrigin(),
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           file_system_url.type(),
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           Bind(&SyncFileSystemDeleteFileSystemFunction::DidDeleteFileSystem,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                this)));
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncFileSystemDeleteFileSystemFunction::DidDeleteFileSystem(
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformFileError error) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Repost to switch from IO thread to UI thread for SendResponse().
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BrowserThread::UI,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Bind(&SyncFileSystemDeleteFileSystemFunction::DidDeleteFileSystem, this,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             error));
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (error != base::PLATFORM_FILE_OK) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_ = base::StringPrintf(kFileError, static_cast<int>(error));
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetResult(base::Value::CreateBooleanValue(false));
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SendResponse(false);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetResult(base::Value::CreateBooleanValue(true));
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(true);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncFileSystemRequestFileSystemFunction::RunImpl() {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initializes sync context for this extension and continue to open
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a new file system.
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetSyncFileSystemService(profile())->
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InitializeForApp(
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          GetFileSystemContext(),
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          source_url().GetOrigin(),
118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          base::Bind(&self::DidInitializeFileSystemContext, this));
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fileapi::FileSystemContext*
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncFileSystemRequestFileSystemFunction::GetFileSystemContext() {
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(render_view_host());
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return BrowserContext::GetStoragePartition(
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile(),
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      render_view_host()->GetSiteInstance())->GetFileSystemContext();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncFileSystemRequestFileSystemFunction::DidInitializeFileSystemContext(
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SyncStatusCode status) {
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (status != sync_file_system::SYNC_STATUS_OK) {
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    error_ = sync_file_system::SyncStatusCodeToString(status);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SendResponse(false);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!render_view_host()) {
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // The app seems to have been closed.
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserThread::PostTask(
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BrowserThread::IO, FROM_HERE,
145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      Bind(&fileapi::FileSystemContext::OpenFileSystem,
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           GetFileSystemContext(),
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           source_url().GetOrigin(),
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           fileapi::kFileSystemTypeSyncable,
14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)           fileapi::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           base::Bind(&self::DidOpenFileSystem, this)));
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncFileSystemRequestFileSystemFunction::DidOpenFileSystem(
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformFileError error,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& file_system_name,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& root_url) {
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Repost to switch from IO thread to UI thread for SendResponse().
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BrowserThread::PostTask(
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        BrowserThread::UI, FROM_HERE,
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        Bind(&SyncFileSystemRequestFileSystemFunction::DidOpenFileSystem,
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             this, error, file_system_name, root_url));
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (error != base::PLATFORM_FILE_OK) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_ = base::StringPrintf(kFileError, static_cast<int>(error));
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SendResponse(false);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::DictionaryValue* dict = new base::DictionaryValue();
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetResult(dict);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dict->SetString("name", file_system_name);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dict->SetString("root", root_url.spec());
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(true);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SyncFileSystemGetFileStatusFunction::RunImpl() {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &url));
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<fileapi::FileSystemContext> file_system_context =
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BrowserContext::GetStoragePartition(
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          profile(),
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          render_view_host()->GetSiteInstance())->GetFileSystemContext();
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fileapi::FileSystemURL file_system_url(
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      file_system_context->CrackURL(GURL(url)));
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SyncFileSystemServiceFactory::GetForProfile(profile())->GetFileSyncStatus(
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      file_system_url,
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Bind(&SyncFileSystemGetFileStatusFunction::DidGetFileStatus,
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           this));
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemGetFileStatusFunction::DidGetFileStatus(
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const SyncStatusCode sync_status_code,
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const SyncFileStatus sync_file_status) {
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (sync_status_code != sync_file_system::SYNC_STATUS_OK) {
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    error_ = sync_file_system::SyncStatusCodeToString(sync_status_code);
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SendResponse(false);
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Convert from C++ to JavaScript enum.
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  results_ = api::sync_file_system::GetFileStatus::Results::Create(
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SyncFileStatusToExtensionEnum(sync_file_status));
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SendResponse(true);
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SyncFileSystemGetFileStatusesFunction::SyncFileSystemGetFileStatusesFunction() {
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SyncFileSystemGetFileStatusesFunction::~SyncFileSystemGetFileStatusesFunction(
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ) {}
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SyncFileSystemGetFileStatusesFunction::RunImpl() {
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // All FileEntries converted into array of URL Strings in JS custom bindings.
223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::ListValue* file_entry_urls = NULL;
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(args_->GetList(0, &file_entry_urls));
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<fileapi::FileSystemContext> file_system_context =
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BrowserContext::GetStoragePartition(
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          profile(),
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          render_view_host()->GetSiteInstance())->GetFileSystemContext();
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Map each file path->SyncFileStatus in the callback map.
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(calvinlo): Overload GetFileSyncStatus to take in URL array.
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  num_expected_results_ = file_entry_urls->GetSize();
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  num_results_received_ = 0;
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_sync_statuses_.clear();
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sync_file_system::SyncFileSystemService* sync_file_system_service =
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SyncFileSystemServiceFactory::GetForProfile(profile());
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (unsigned int i = 0; i < num_expected_results_; i++) {
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string url;
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    file_entry_urls->GetString(i, &url);
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fileapi::FileSystemURL file_system_url(
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        file_system_context->CrackURL(GURL(url)));
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_file_system_service->GetFileSyncStatus(
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        file_system_url,
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        Bind(&SyncFileSystemGetFileStatusesFunction::DidGetFileStatus,
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             this, file_system_url));
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemGetFileStatusesFunction::DidGetFileStatus(
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const fileapi::FileSystemURL& file_system_url,
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SyncStatusCode sync_status_code,
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SyncFileStatus sync_file_status) {
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  num_results_received_++;
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_LE(num_results_received_, num_expected_results_);
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_sync_statuses_[file_system_url] =
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::make_pair(sync_status_code, sync_file_status);
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Keep mapping file statuses until all of them have been received.
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(calvinlo): Get rid of this check when batch version of
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // GetFileSyncStatus(GURL urls[]); is added.
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (num_results_received_ < num_expected_results_)
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // All results received. Dump array of statuses into extension enum values.
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Note that the enum types need to be set as strings manually as the
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // autogenerated Results::Create function thinks the enum values should be
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // returned as int values.
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ListValue* status_array = new base::ListValue();
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (URLToStatusMap::iterator it = file_sync_statuses_.begin();
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != file_sync_statuses_.end(); ++it) {
277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::DictionaryValue* dict = new base::DictionaryValue();
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    status_array->Append(dict);
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fileapi::FileSystemURL url = it->first;
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SyncStatusCode file_error = it->second.first;
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    api::sync_file_system::FileStatus file_status =
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        SyncFileStatusToExtensionEnum(it->second.second);
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    dict->Set("entry", CreateDictionaryValueForFileSystemEntry(
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        url, sync_file_system::SYNC_FILE_TYPE_FILE));
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetString("status", ToString(file_status));
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (file_error == sync_file_system::SYNC_STATUS_OK)
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetString("error",
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    sync_file_system::SyncStatusCodeToString(file_error));
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResult(status_array);
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SendResponse(true);
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SyncFileSystemGetUsageAndQuotaFunction::RunImpl() {
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string url;
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &url));
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<fileapi::FileSystemContext> file_system_context =
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BrowserContext::GetStoragePartition(
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          profile(),
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          render_view_host()->GetSiteInstance())->GetFileSystemContext();
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fileapi::FileSystemURL file_system_url(
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      file_system_context->CrackURL(GURL(url)));
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<quota::QuotaManager> quota_manager =
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserContext::GetStoragePartition(
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          profile(),
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          render_view_host()->GetSiteInstance())->GetQuotaManager();
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::IO,
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      Bind(&quota::QuotaManager::GetUsageAndQuotaForWebApps,
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           quota_manager,
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           source_url().GetOrigin(),
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           fileapi::FileSystemTypeToQuotaStorageType(file_system_url.type()),
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           Bind(&SyncFileSystemGetUsageAndQuotaFunction::DidGetUsageAndQuota,
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                this)));
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncFileSystemGetUsageAndQuotaFunction::DidGetUsageAndQuota(
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      quota::QuotaStatusCode status, int64 usage, int64 quota) {
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Repost to switch from IO thread to UI thread for SendResponse().
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BrowserThread::UI,
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Bind(&SyncFileSystemGetUsageAndQuotaFunction::DidGetUsageAndQuota, this,
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             status, usage, quota));
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != quota::kQuotaStatusOk) {
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_ = QuotaStatusCodeToString(status);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SendResponse(false);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  api::sync_file_system::StorageInfo info;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.usage_bytes = usage;
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.quota_bytes = quota;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  results_ = api::sync_file_system::GetUsageAndQuota::Results::Create(info);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(true);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SyncFileSystemSetConflictResolutionPolicyFunction::RunImpl() {
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string policy_string;
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &policy_string));
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ConflictResolutionPolicy policy = ExtensionEnumToConflictResolutionPolicy(
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      api::sync_file_system::ParseConflictResolutionPolicy(policy_string));
360eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (policy == sync_file_system::CONFLICT_RESOLUTION_POLICY_UNKNOWN) {
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetError(base::StringPrintf(kUnsupportedConflictResolutionPolicy,
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                policy_string.c_str()));
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sync_file_system::SyncFileSystemService* service = GetSyncFileSystemService(
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      profile());
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(service);
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SyncStatusCode status = service->SetConflictResolutionPolicy(policy);
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (status != sync_file_system::SYNC_STATUS_OK) {
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetError(sync_file_system::SyncStatusCodeToString(status));
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SyncFileSystemGetConflictResolutionPolicyFunction::RunImpl() {
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sync_file_system::SyncFileSystemService* service = GetSyncFileSystemService(
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      profile());
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(service);
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  api::sync_file_system::ConflictResolutionPolicy policy =
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ConflictResolutionPolicyToExtensionEnum(
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          service->GetConflictResolutionPolicy());
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResult(Value::CreateStringValue(
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          api::sync_file_system::ToString(policy)));
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
389