1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/apps/drive/drive_service_bridge.h"
6
7#include <string>
8
9#include "base/logging.h"
10#include "chrome/browser/drive/drive_api_service.h"
11#include "chrome/browser/drive/drive_app_registry.h"
12#include "chrome/browser/drive/drive_notification_manager.h"
13#include "chrome/browser/drive/drive_notification_manager_factory.h"
14#include "chrome/browser/drive/drive_notification_observer.h"
15#include "chrome/browser/profiles/profile.h"
16#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
17#include "chrome/browser/signin/signin_manager_factory.h"
18#include "components/signin/core/browser/profile_oauth2_token_service.h"
19#include "components/signin/core/browser/signin_manager.h"
20#include "content/public/browser/browser_thread.h"
21
22namespace {
23
24// Hosts DriveAPIService and DriveAppRegistry.
25// TODO(xiyuan): Optimize to leverage chromeos::DriveIntegrationService.
26class DriveServiceBridgeImpl : public DriveServiceBridge,
27                               public drive::DriveServiceObserver,
28                               public drive::DriveNotificationObserver {
29 public:
30  explicit DriveServiceBridgeImpl(Profile* profile);
31  virtual ~DriveServiceBridgeImpl();
32
33  void Initialize();
34
35  // DriveServiceBridge:
36  virtual drive::DriveAppRegistry* GetAppRegistry() OVERRIDE;
37
38  // drive::DriveServiceObserver:
39  virtual void OnReadyToSendRequests() OVERRIDE;
40
41  // drive::DriveNotificationObserver:
42  virtual void OnNotificationReceived() OVERRIDE;
43  virtual void OnPushNotificationEnabled(bool enabled) OVERRIDE;
44
45 private:
46  Profile* profile_;
47  scoped_ptr<drive::DriveServiceInterface> drive_service_;
48  scoped_ptr<drive::DriveAppRegistry> drive_app_registry_;
49
50  DISALLOW_COPY_AND_ASSIGN(DriveServiceBridgeImpl);
51};
52
53DriveServiceBridgeImpl::DriveServiceBridgeImpl(Profile* profile)
54    : profile_(profile) {
55  DCHECK(profile_);
56}
57
58DriveServiceBridgeImpl::~DriveServiceBridgeImpl() {
59  drive::DriveNotificationManager* drive_notification_manager =
60      drive::DriveNotificationManagerFactory::FindForBrowserContext(profile_);
61  if (drive_notification_manager)
62    drive_notification_manager->RemoveObserver(this);
63
64  drive_service_->RemoveObserver(this);
65
66  drive_app_registry_.reset();
67  drive_service_.reset();
68}
69
70void DriveServiceBridgeImpl::Initialize() {
71  scoped_refptr<base::SequencedWorkerPool> worker_pool(
72      content::BrowserThread::GetBlockingPool());
73  scoped_refptr<base::SequencedTaskRunner> drive_task_runner(
74      worker_pool->GetSequencedTaskRunnerWithShutdownBehavior(
75          worker_pool->GetSequenceToken(),
76          base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
77
78  ProfileOAuth2TokenService* token_service =
79      ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
80  drive_service_.reset(new drive::DriveAPIService(
81      token_service,
82      profile_->GetRequestContext(),
83      drive_task_runner.get(),
84      GURL(google_apis::DriveApiUrlGenerator::kBaseUrlForProduction),
85      GURL(google_apis::DriveApiUrlGenerator::kBaseDownloadUrlForProduction),
86      GURL(google_apis::GDataWapiUrlGenerator::kBaseUrlForProduction),
87      std::string() /* custom_user_agent */));
88  SigninManagerBase* signin_manager =
89      SigninManagerFactory::GetForProfile(profile_);
90  drive_service_->Initialize(signin_manager->GetAuthenticatedAccountId());
91  drive_service_->AddObserver(this);
92
93  drive::DriveNotificationManager* drive_notification_manager =
94      drive::DriveNotificationManagerFactory::GetForBrowserContext(profile_);
95  if (drive_notification_manager)
96    drive_notification_manager->AddObserver(this);
97
98  drive_app_registry_.reset(new drive::DriveAppRegistry(drive_service_.get()));
99  if (drive_service_->CanSendRequest())
100    drive_app_registry_->Update();
101}
102
103drive::DriveAppRegistry* DriveServiceBridgeImpl::GetAppRegistry() {
104  return drive_app_registry_.get();
105}
106
107void DriveServiceBridgeImpl::OnReadyToSendRequests() {
108  drive_app_registry_->Update();
109}
110
111void DriveServiceBridgeImpl::OnNotificationReceived() {
112  if (drive_service_->CanSendRequest())
113    drive_app_registry_->Update();
114}
115
116void DriveServiceBridgeImpl::OnPushNotificationEnabled(bool enabled) {
117  if (enabled && drive_service_->CanSendRequest())
118    drive_app_registry_->Update();
119}
120
121}  // namespace
122
123// static
124scoped_ptr<DriveServiceBridge> DriveServiceBridge::Create(Profile* profile) {
125  scoped_ptr<DriveServiceBridgeImpl> bridge(
126      new DriveServiceBridgeImpl(profile));
127  bridge->Initialize();
128  return bridge.PassAs<DriveServiceBridge>();
129}
130
131// static
132void DriveServiceBridge::AppendDependsOnFactories(
133    std::set<BrowserContextKeyedServiceFactory*>* factories) {
134  DCHECK(factories);
135  factories->insert(ProfileOAuth2TokenServiceFactory::GetInstance());
136  factories->insert(SigninManagerFactory::GetInstance());
137  factories->insert(drive::DriveNotificationManagerFactory::GetInstance());
138}
139