root/chrome/browser/extensions/api/sync_file_system/extension_sync_event_observer.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. GetFactoryInstance
  2. sync_service_
  3. InitializeForService
  4. Shutdown
  5. GetExtensionId
  6. OnSyncStateUpdated
  7. OnFileSynced
  8. BroadcastOrDispatchEvent
  9. DeclareFactoryDependencies

// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/api/sync_file_system/extension_sync_event_observer.h"

#include "base/lazy_instance.h"
#include "chrome/browser/extensions/api/sync_file_system/sync_file_system_api_helpers.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/sync_file_system/sync_event_observer.h"
#include "chrome/browser/sync_file_system/sync_file_system_service.h"
#include "chrome/browser/sync_file_system/sync_file_system_service_factory.h"
#include "chrome/browser/sync_file_system/syncable_file_system_util.h"
#include "chrome/common/extensions/api/sync_file_system.h"
#include "content/public/browser/browser_context.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/extension_system_provider.h"
#include "extensions/browser/extensions_browser_client.h"
#include "webkit/browser/fileapi/file_system_url.h"
#include "webkit/common/fileapi/file_system_util.h"

using sync_file_system::SyncEventObserver;

namespace extensions {

static base::LazyInstance<
    BrowserContextKeyedAPIFactory<ExtensionSyncEventObserver> > g_factory =
    LAZY_INSTANCE_INITIALIZER;

// static
BrowserContextKeyedAPIFactory<ExtensionSyncEventObserver>*
ExtensionSyncEventObserver::GetFactoryInstance() {
  return g_factory.Pointer();
}

ExtensionSyncEventObserver::ExtensionSyncEventObserver(
    content::BrowserContext* context)
    : browser_context_(context), sync_service_(NULL) {}

void ExtensionSyncEventObserver::InitializeForService(
    sync_file_system::SyncFileSystemService* sync_service) {
  DCHECK(sync_service);
  if (sync_service_ != NULL) {
    DCHECK_EQ(sync_service_, sync_service);
    return;
  }
  sync_service_ = sync_service;
  sync_service_->AddSyncEventObserver(this);
}

ExtensionSyncEventObserver::~ExtensionSyncEventObserver() {}

void ExtensionSyncEventObserver::Shutdown() {
  if (sync_service_ != NULL)
    sync_service_->RemoveSyncEventObserver(this);
}

std::string ExtensionSyncEventObserver::GetExtensionId(
    const GURL& app_origin) {
  const Extension* app = ExtensionSystem::Get(browser_context_)
                             ->extension_service()
                             ->GetInstalledApp(app_origin);
  if (!app) {
    // The app is uninstalled or disabled.
    return std::string();
  }
  return app->id();
}

void ExtensionSyncEventObserver::OnSyncStateUpdated(
    const GURL& app_origin,
    sync_file_system::SyncServiceState state,
    const std::string& description) {
  // Convert state and description into SyncState Object.
  api::sync_file_system::ServiceInfo service_info;
  service_info.state = SyncServiceStateToExtensionEnum(state);
  service_info.description = description;
  scoped_ptr<base::ListValue> params(
      api::sync_file_system::OnServiceStatusChanged::Create(service_info));

  BroadcastOrDispatchEvent(
      app_origin,
      api::sync_file_system::OnServiceStatusChanged::kEventName,
      params.Pass());
}

void ExtensionSyncEventObserver::OnFileSynced(
    const fileapi::FileSystemURL& url,
    sync_file_system::SyncFileStatus status,
    sync_file_system::SyncAction action,
    sync_file_system::SyncDirection direction) {
  scoped_ptr<base::ListValue> params(new base::ListValue());

  // For now we always assume events come only for files (not directories).
  params->Append(CreateDictionaryValueForFileSystemEntry(
      url, sync_file_system::SYNC_FILE_TYPE_FILE));

  // Status, SyncAction and any optional notes to go here.
  api::sync_file_system::FileStatus status_enum =
      SyncFileStatusToExtensionEnum(status);
  api::sync_file_system::SyncAction action_enum =
      SyncActionToExtensionEnum(action);
  api::sync_file_system::SyncDirection direction_enum =
      SyncDirectionToExtensionEnum(direction);
  params->AppendString(api::sync_file_system::ToString(status_enum));
  params->AppendString(api::sync_file_system::ToString(action_enum));
  params->AppendString(api::sync_file_system::ToString(direction_enum));

  BroadcastOrDispatchEvent(
      url.origin(),
      api::sync_file_system::OnFileStatusChanged::kEventName,
      params.Pass());
}

void ExtensionSyncEventObserver::BroadcastOrDispatchEvent(
    const GURL& app_origin,
    const std::string& event_name,
    scoped_ptr<base::ListValue> values) {
  // Check to see whether the event should be broadcasted to all listening
  // extensions or sent to a specific extension ID.
  bool broadcast_mode = app_origin.is_empty();
  EventRouter* event_router =
      ExtensionSystem::Get(browser_context_)->event_router();
  DCHECK(event_router);

  scoped_ptr<Event> event(new Event(event_name, values.Pass()));
  event->restrict_to_browser_context = browser_context_;

  // No app_origin, broadcast to all listening extensions for this event name.
  if (broadcast_mode) {
    event_router->BroadcastEvent(event.Pass());
    return;
  }

  // Dispatch to single extension ID.
  const std::string extension_id = GetExtensionId(app_origin);
  if (extension_id.empty())
    return;
  event_router->DispatchEventToExtension(extension_id, event.Pass());
}

template <>
void BrowserContextKeyedAPIFactory<
    ExtensionSyncEventObserver>::DeclareFactoryDependencies() {
  DependsOn(sync_file_system::SyncFileSystemServiceFactory::GetInstance());
  DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory());
}

}  // namespace extensions

/* [<][>][^][v][top][bottom][index][help] */