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" 1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend_v1/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. 44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const char kErrorMessage[] = "%s (error code: %d)."; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kUnsupportedConflictResolutionPolicy[] = 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Policy %s is not supported."; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)sync_file_system::SyncFileSystemService* GetSyncFileSystemService( 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* profile) { 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sync_file_system::SyncFileSystemService* service = 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncFileSystemServiceFactory::GetForProfile(profile); 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(service); 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionSyncEventObserver* observer = 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionSyncEventObserverFactory::GetForProfile(profile); 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(observer); 56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) observer->InitializeForService(service); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return service; 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)std::string ErrorToString(SyncStatusCode code) { 61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return base::StringPrintf( 62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) kErrorMessage, 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sync_file_system::SyncStatusCodeToString(code), 64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static_cast<int>(code)); 65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncFileSystemDeleteFileSystemFunction::RunImpl() { 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string url; 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &url)); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<fileapi::FileSystemContext> file_system_context = 741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) BrowserContext::GetStoragePartition(GetProfile(), 751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) render_view_host()->GetSiteInstance()) 761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ->GetFileSystemContext(); 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fileapi::FileSystemURL file_system_url( 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_system_context->CrackURL(GURL(url))); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::IO, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bind(&fileapi::FileSystemContext::DeleteFileSystem, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_system_context, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source_url().GetOrigin(), 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_system_url.type(), 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bind(&SyncFileSystemDeleteFileSystemFunction::DidDeleteFileSystem, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this))); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncFileSystemDeleteFileSystemFunction::DidDeleteFileSystem( 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::PlatformFileError error) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Repost to switch from IO thread to UI thread for SendResponse(). 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::UI, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bind(&SyncFileSystemDeleteFileSystemFunction::DidDeleteFileSystem, this, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error)); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error != base::PLATFORM_FILE_OK) { 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) error_ = ErrorToString( 108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sync_file_system::PlatformFileErrorToSyncStatusCode(error)); 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetResult(new base::FundamentalValue(false)); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendResponse(false); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetResult(new base::FundamentalValue(true)); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendResponse(true); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncFileSystemRequestFileSystemFunction::RunImpl() { 11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // SyncFileSystem initialization is done in OpenFileSystem below, but we call 12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // GetSyncFileSystemService here too to initialize sync event observer for 12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // extensions API. 1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) GetSyncFileSystemService(GetProfile()); 12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializes sync context for this extension and continue to open 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a new file system. 12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) BrowserThread::PostTask( 12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) BrowserThread::IO, FROM_HERE, 12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Bind(&fileapi::FileSystemContext::OpenFileSystem, 12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GetFileSystemContext(), 13058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) source_url().GetOrigin(), 13158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fileapi::kFileSystemTypeSyncable, 13258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fileapi::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT, 13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Bind(&self::DidOpenFileSystem, this))); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fileapi::FileSystemContext* 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncFileSystemRequestFileSystemFunction::GetFileSystemContext() { 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(render_view_host()); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return BrowserContext::GetStoragePartition( 1411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) GetProfile(), render_view_host()->GetSiteInstance()) 1421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ->GetFileSystemContext(); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncFileSystemRequestFileSystemFunction::DidOpenFileSystem( 1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const GURL& root_url, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& file_system_name, 1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::PlatformFileError error) { 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Repost to switch from IO thread to UI thread for SendResponse(). 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask( 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::UI, FROM_HERE, 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Bind(&SyncFileSystemRequestFileSystemFunction::DidOpenFileSystem, 1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) this, root_url, file_system_name, error)); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error != base::PLATFORM_FILE_OK) { 161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) error_ = ErrorToString( 162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sync_file_system::PlatformFileErrorToSyncStatusCode(error)); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendResponse(false); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::DictionaryValue* dict = new base::DictionaryValue(); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetResult(dict); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("name", file_system_name); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("root", root_url.spec()); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendResponse(true); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SyncFileSystemGetFileStatusFunction::RunImpl() { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &url)); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<fileapi::FileSystemContext> file_system_context = 1791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) BrowserContext::GetStoragePartition(GetProfile(), 1801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) render_view_host()->GetSiteInstance()) 1811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ->GetFileSystemContext(); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fileapi::FileSystemURL file_system_url( 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_system_context->CrackURL(GURL(url))); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) GetSyncFileSystemService(GetProfile())->GetFileSyncStatus( 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_system_url, 1871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Bind(&SyncFileSystemGetFileStatusFunction::DidGetFileStatus, this)); 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemGetFileStatusFunction::DidGetFileStatus( 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SyncStatusCode sync_status_code, 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SyncFileStatus sync_file_status) { 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (sync_status_code != sync_file_system::SYNC_STATUS_OK) { 196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) error_ = ErrorToString(sync_status_code); 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendResponse(false); 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Convert from C++ to JavaScript enum. 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) results_ = api::sync_file_system::GetFileStatus::Results::Create( 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SyncFileStatusToExtensionEnum(sync_file_status)); 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendResponse(true); 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SyncFileSystemGetFileStatusesFunction::SyncFileSystemGetFileStatusesFunction() { 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SyncFileSystemGetFileStatusesFunction::~SyncFileSystemGetFileStatusesFunction( 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) {} 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SyncFileSystemGetFileStatusesFunction::RunImpl() { 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // All FileEntries converted into array of URL Strings in JS custom bindings. 215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ListValue* file_entry_urls = NULL; 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetList(0, &file_entry_urls)); 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<fileapi::FileSystemContext> file_system_context = 2191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) BrowserContext::GetStoragePartition(GetProfile(), 2201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) render_view_host()->GetSiteInstance()) 2211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ->GetFileSystemContext(); 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Map each file path->SyncFileStatus in the callback map. 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(calvinlo): Overload GetFileSyncStatus to take in URL array. 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_expected_results_ = file_entry_urls->GetSize(); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_results_received_ = 0; 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_sync_statuses_.clear(); 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sync_file_system::SyncFileSystemService* sync_file_system_service = 2291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) GetSyncFileSystemService(GetProfile()); 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < num_expected_results_; i++) { 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string url; 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_entry_urls->GetString(i, &url); 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fileapi::FileSystemURL file_system_url( 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_system_context->CrackURL(GURL(url))); 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sync_file_system_service->GetFileSyncStatus( 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_system_url, 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Bind(&SyncFileSystemGetFileStatusesFunction::DidGetFileStatus, 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, file_system_url)); 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemGetFileStatusesFunction::DidGetFileStatus( 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const fileapi::FileSystemURL& file_system_url, 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncStatusCode sync_status_code, 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncFileStatus sync_file_status) { 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_results_received_++; 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_LE(num_results_received_, num_expected_results_); 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_sync_statuses_[file_system_url] = 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::make_pair(sync_status_code, sync_file_status); 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Keep mapping file statuses until all of them have been received. 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(calvinlo): Get rid of this check when batch version of 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // GetFileSyncStatus(GURL urls[]); is added. 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (num_results_received_ < num_expected_results_) 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // All results received. Dump array of statuses into extension enum values. 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note that the enum types need to be set as strings manually as the 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // autogenerated Results::Create function thinks the enum values should be 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // returned as int values. 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* status_array = new base::ListValue(); 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (URLToStatusMap::iterator it = file_sync_statuses_.begin(); 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != file_sync_statuses_.end(); ++it) { 269eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::DictionaryValue* dict = new base::DictionaryValue(); 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) status_array->Append(dict); 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fileapi::FileSystemURL url = it->first; 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncStatusCode file_error = it->second.first; 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) api::sync_file_system::FileStatus file_status = 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SyncFileStatusToExtensionEnum(it->second.second); 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dict->Set("entry", CreateDictionaryValueForFileSystemEntry( 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) url, sync_file_system::SYNC_FILE_TYPE_FILE)); 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dict->SetString("status", ToString(file_status)); 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (file_error == sync_file_system::SYNC_STATUS_OK) 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 283a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) dict->SetString("error", ErrorToString(file_error)); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetResult(status_array); 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendResponse(true); 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SyncFileSystemGetUsageAndQuotaFunction::RunImpl() { 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string url; 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &url)); 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<fileapi::FileSystemContext> file_system_context = 2951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) BrowserContext::GetStoragePartition(GetProfile(), 2961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) render_view_host()->GetSiteInstance()) 2971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ->GetFileSystemContext(); 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fileapi::FileSystemURL file_system_url( 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_system_context->CrackURL(GURL(url))); 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<quota::QuotaManager> quota_manager = 3021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) BrowserContext::GetStoragePartition(GetProfile(), 3031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) render_view_host()->GetSiteInstance()) 3041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ->GetQuotaManager(); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::IO, 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Bind("a::QuotaManager::GetUsageAndQuotaForWebApps, 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quota_manager, 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source_url().GetOrigin(), 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fileapi::FileSystemTypeToQuotaStorageType(file_system_url.type()), 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bind(&SyncFileSystemGetUsageAndQuotaFunction::DidGetUsageAndQuota, 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this))); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncFileSystemGetUsageAndQuotaFunction::DidGetUsageAndQuota( 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quota::QuotaStatusCode status, int64 usage, int64 quota) { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Repost to switch from IO thread to UI thread for SendResponse(). 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::UI, 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bind(&SyncFileSystemGetUsageAndQuotaFunction::DidGetUsageAndQuota, this, 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status, usage, quota)); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status != quota::kQuotaStatusOk) { 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = QuotaStatusCodeToString(status); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendResponse(false); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) api::sync_file_system::StorageInfo info; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.usage_bytes = usage; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.quota_bytes = quota; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results_ = api::sync_file_system::GetUsageAndQuota::Results::Create(info); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendResponse(true); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SyncFileSystemSetConflictResolutionPolicyFunction::RunImpl() { 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string policy_string; 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &policy_string)); 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ConflictResolutionPolicy policy = ExtensionEnumToConflictResolutionPolicy( 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) api::sync_file_system::ParseConflictResolutionPolicy(policy_string)); 351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (policy == sync_file_system::CONFLICT_RESOLUTION_POLICY_UNKNOWN) { 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetError(base::StringPrintf(kUnsupportedConflictResolutionPolicy, 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) policy_string.c_str())); 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) sync_file_system::SyncFileSystemService* service = 3571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) GetSyncFileSystemService(GetProfile()); 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(service); 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncStatusCode status = service->SetConflictResolutionPolicy(policy); 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status != sync_file_system::SYNC_STATUS_OK) { 361a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SetError(ErrorToString(status)); 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SyncFileSystemGetConflictResolutionPolicyFunction::RunImpl() { 3681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) sync_file_system::SyncFileSystemService* service = 3691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) GetSyncFileSystemService(GetProfile()); 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(service); 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) api::sync_file_system::ConflictResolutionPolicy policy = 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConflictResolutionPolicyToExtensionEnum( 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) service->GetConflictResolutionPolicy()); 3743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetResult(new base::StringValue( 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) api::sync_file_system::ToString(policy))); 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 379424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool SyncFileSystemGetServiceStatusFunction::RunImpl() { 3801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) sync_file_system::SyncFileSystemService* service = 3811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) GetSyncFileSystemService(GetProfile()); 382424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) results_ = api::sync_file_system::GetServiceStatus::Results::Create( 383424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SyncServiceStateToExtensionEnum(service->GetSyncServiceState())); 384424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 385424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 386424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 388