1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file. 4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/chromeos/first_run/drive_first_run_controller.h" 6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ash/shell.h" 8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ash/system/tray/system_tray_delegate.h" 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/callback.h" 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/memory/weak_ptr.h" 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/message_loop/message_loop.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/metrics/histogram.h" 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/strings/utf_string_conversions.h" 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/background/background_contents_service.h" 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/background/background_contents_service_factory.h" 16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/chrome_notification_types.h" 1723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" 18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/tab_contents/background_contents.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/browser_navigator.h" 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/host_desktop.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/singleton_tabs.h" 246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/grit/generated_resources.h" 256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/grit/theme_resources.h" 266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/user_manager/user_manager.h" 27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/navigation_controller.h" 29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/notification_details.h" 30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/notification_observer.h" 31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/notification_registrar.h" 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/notification_source.h" 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/notification_types.h" 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/browser/render_frame_host.h" 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/site_instance.h" 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/web_contents.h" 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/web_contents_observer.h" 38a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "extensions/browser/extension_registry.h" 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h" 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 41a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "extensions/common/extension_set.h" 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/message_center/message_center.h" 45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/message_center/notification.h" 46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/message_center/notification_delegate.h" 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "url/gurl.h" 48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace chromeos { 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace { 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// The initial time to wait in seconds before enabling offline mode. 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)int kInitialDelaySeconds = 180; 55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Time to wait for Drive app background page to come up before giving up. 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)int kWebContentsTimeoutSeconds = 15; 58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Google Drive enable offline endpoint. 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kDriveOfflineEndpointUrl[] = 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "https://docs.google.com/offline/autoenable"; 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Google Drive app id. 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const char kDriveHostedAppId[] = "apdfllckaahabafndbhieahigkjlhalf"; 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Id of the notification shown when offline mode is enabled. 67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const char kDriveOfflineNotificationId[] = "chrome://drive/enable-offline"; 68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// The URL of the support page opened when the notification button is clicked. 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kDriveOfflineSupportUrl[] = 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "https://support.google.com/drive/answer/1628467"; 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// DriveOfflineNotificationDelegate 77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// NotificationDelegate for the notification that is displayed when Drive 79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// offline mode is enabled automatically. Clicking on the notification button 80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// will open the Drive settings page. 81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class DriveOfflineNotificationDelegate 82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : public message_center::NotificationDelegate { 83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public: 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) explicit DriveOfflineNotificationDelegate(Profile* profile) 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : profile_(profile) {} 86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // message_center::NotificationDelegate overrides: 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void Display() OVERRIDE {} 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void Error() OVERRIDE {} 90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void Close(bool by_user) OVERRIDE {} 91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void Click() OVERRIDE {} 92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void ButtonClick(int button_index) OVERRIDE; 93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) protected: 95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual ~DriveOfflineNotificationDelegate() {} 96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private: 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Profile* profile_; 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DriveOfflineNotificationDelegate); 101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void DriveOfflineNotificationDelegate::ButtonClick(int button_index) { 104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK_EQ(0, button_index); 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The support page will be localized based on the user's GAIA account. 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GURL url = GURL(kDriveOfflineSupportUrl); 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chrome::ScopedTabbedBrowserDisplayer displayer( 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile_, 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chrome::HOST_DESKTOP_TYPE_ASH); 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chrome::ShowSingletonTabOverwritingNTP( 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) displayer.browser(), 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chrome::GetSingletonTabNavigateParams(displayer.browser(), url)); 115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// DriveWebContentsManager 119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Manages web contents that initializes Google Drive offline mode. We create 121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// a background WebContents that loads a Drive endpoint to initialize offline 122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// mode. If successful, a background page will be opened to sync the user's 123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// files for offline use. 124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class DriveWebContentsManager : public content::WebContentsObserver, 125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public content::WebContentsDelegate, 126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public content::NotificationObserver { 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public: 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) typedef base::Callback< 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void(bool, DriveFirstRunController::UMAOutcome)> CompletionCallback; 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DriveWebContentsManager(Profile* profile, 132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& app_id, 133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& endpoint_url, 134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const CompletionCallback& completion_callback); 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual ~DriveWebContentsManager(); 136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Start loading the WebContents for the endpoint in the context of the Drive 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // hosted app that will initialize offline mode and open a background page. 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void StartLoad(); 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Stop loading the endpoint. The |completion_callback| will not be called. 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void StopLoad(); 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private: 145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Called when when offline initialization succeeds or fails and schedules 146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // |RunCompletionCallback|. 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void OnOfflineInit(bool success, 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DriveFirstRunController::UMAOutcome outcome); 149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Runs |completion_callback|. 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void RunCompletionCallback(bool success, 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DriveFirstRunController::UMAOutcome outcome); 153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // content::WebContentsObserver overrides: 155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void DidFailProvisionalLoad( 156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::RenderFrameHost* render_frame_host, 157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const GURL& validated_url, 158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int error_code, 159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::string16& error_description) OVERRIDE; 160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual void DidFailLoad(content::RenderFrameHost* render_frame_host, 162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const GURL& validated_url, 163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int error_code, 164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::string16& error_description) OVERRIDE; 165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // content::WebContentsDelegate overrides: 167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual bool ShouldCreateWebContents( 168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::WebContents* web_contents, 169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int route_id, 170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) WindowContainerType window_container_type, 171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& frame_name, 172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const GURL& target_url, 173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& partition_id, 174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::SessionStorageNamespace* session_storage_namespace) OVERRIDE; 175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // content::NotificationObserver overrides: 177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void Observe(int type, 178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const content::NotificationSource& source, 179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const content::NotificationDetails& details) OVERRIDE; 180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Profile* profile_; 182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string app_id_; 183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string endpoint_url_; 184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<content::WebContents> web_contents_; 185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::NotificationRegistrar registrar_; 186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool started_; 187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CompletionCallback completion_callback_; 188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::WeakPtrFactory<DriveWebContentsManager> weak_ptr_factory_; 189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DriveWebContentsManager); 191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}; 192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)DriveWebContentsManager::DriveWebContentsManager( 194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Profile* profile, 195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& app_id, 196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& endpoint_url, 197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const CompletionCallback& completion_callback) 198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : profile_(profile), 199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) app_id_(app_id), 200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) endpoint_url_(endpoint_url), 201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) started_(false), 202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) completion_callback_(completion_callback), 203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) weak_ptr_factory_(this) { 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!completion_callback_.is_null()); 205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_BACKGROUND_CONTENTS_OPENED, 206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::Source<Profile>(profile_)); 207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)DriveWebContentsManager::~DriveWebContentsManager() { 210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DriveWebContentsManager::StartLoad() { 213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) started_ = true; 214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const GURL url(endpoint_url_); 215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::WebContents::CreateParams create_params( 216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) profile_, content::SiteInstance::CreateForURL(profile_, url)); 217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) web_contents_.reset(content::WebContents::Create(create_params)); 219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) web_contents_->SetDelegate(this); 22023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) extensions::ChromeExtensionWebContentsObserver::CreateForWebContents( 221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) web_contents_.get()); 222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::NavigationController::LoadURLParams load_params(url); 2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci load_params.transition_type = ui::PAGE_TRANSITION_GENERATED; 225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) web_contents_->GetController().LoadURLWithParams(load_params); 226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::WebContentsObserver::Observe(web_contents_.get()); 228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DriveWebContentsManager::StopLoad() { 231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) started_ = false; 232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DriveWebContentsManager::OnOfflineInit( 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool success, 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DriveFirstRunController::UMAOutcome outcome) { 237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (started_) { 238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // We postpone notifying the controller as we may be in the middle 239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // of a call stack for some routine of the contained WebContents. 240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::MessageLoop::current()->PostTask( 241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FROM_HERE, 242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&DriveWebContentsManager::RunCompletionCallback, 243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) success, 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) outcome)); 246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) StopLoad(); 247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DriveWebContentsManager::RunCompletionCallback( 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool success, 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DriveFirstRunController::UMAOutcome outcome) { 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) completion_callback_.Run(success, outcome); 254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DriveWebContentsManager::DidFailProvisionalLoad( 257116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::RenderFrameHost* render_frame_host, 258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const GURL& validated_url, 259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int error_code, 260116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::string16& error_description) { 261116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!render_frame_host->GetParent()) { 262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) LOG(WARNING) << "Failed to load WebContents to enable offline mode."; 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnOfflineInit(false, 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DriveFirstRunController::OUTCOME_WEB_CONTENTS_LOAD_FAILED); 265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DriveWebContentsManager::DidFailLoad( 269116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::RenderFrameHost* render_frame_host, 270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const GURL& validated_url, 271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int error_code, 272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::string16& error_description) { 273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!render_frame_host->GetParent()) { 274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) LOG(WARNING) << "Failed to load WebContents to enable offline mode."; 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnOfflineInit(false, 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DriveFirstRunController::OUTCOME_WEB_CONTENTS_LOAD_FAILED); 277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool DriveWebContentsManager::ShouldCreateWebContents( 281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::WebContents* web_contents, 282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int route_id, 283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) WindowContainerType window_container_type, 284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& frame_name, 285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const GURL& target_url, 286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& partition_id, 287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::SessionStorageNamespace* session_storage_namespace) { 288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (window_container_type == WINDOW_CONTAINER_TYPE_NORMAL) 290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Check that the target URL is for the Drive app. 293a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const extensions::Extension* extension = 294a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch extensions::ExtensionRegistry::Get(profile_) 295a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ->enabled_extensions().GetAppByURL(target_url); 296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!extension || extension->id() != app_id_) 297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The background contents creation is normally done in Browser, but 300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // because we're using a detached WebContents, we need to do it ourselves. 301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BackgroundContentsService* background_contents_service = 302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BackgroundContentsServiceFactory::GetForProfile(profile_); 303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Prevent redirection if background contents already exists. 305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (background_contents_service->GetAppBackgroundContents( 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::UTF8ToUTF16(app_id_))) { 307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BackgroundContents* contents = background_contents_service 310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ->CreateBackgroundContents(content::SiteInstance::Create(profile_), 311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) route_id, 312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) profile_, 313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) frame_name, 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ASCIIToUTF16(app_id_), 315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) partition_id, 316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) session_storage_namespace); 317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) contents->web_contents()->GetController().LoadURL( 319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) target_url, 320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::Referrer(), 3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ui::PAGE_TRANSITION_LINK, 322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string()); 323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Return false as we already created the WebContents here. 325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DriveWebContentsManager::Observe( 329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int type, 330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const content::NotificationSource& source, 331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const content::NotificationDetails& details) { 332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (type == chrome::NOTIFICATION_BACKGROUND_CONTENTS_OPENED) { 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string app_id = base::UTF16ToUTF8( 334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::Details<BackgroundContentsOpenedDetails>(details) 335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ->application_id); 336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (app_id == app_id_) 3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnOfflineInit(true, DriveFirstRunController::OUTCOME_OFFLINE_ENABLED); 338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// DriveFirstRunController 343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DriveFirstRunController::DriveFirstRunController(Profile* profile) 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : profile_(profile), 346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) started_(false), 347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) initial_delay_secs_(kInitialDelaySeconds), 348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) web_contents_timeout_secs_(kWebContentsTimeoutSeconds), 349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) drive_offline_endpoint_url_(kDriveOfflineEndpointUrl), 350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) drive_hosted_app_id_(kDriveHostedAppId) { 351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)DriveFirstRunController::~DriveFirstRunController() { 354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DriveFirstRunController::EnableOfflineMode() { 357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!started_) { 358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) started_ = true; 359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) initial_delay_timer_.Start( 360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FROM_HERE, 361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::TimeDelta::FromSeconds(initial_delay_secs_), 362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) this, 363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &DriveFirstRunController::EnableOfflineMode); 364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!user_manager::UserManager::Get()->IsLoggedInAsRegularUser()) { 368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) LOG(ERROR) << "Attempting to enable offline access " 369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "but not logged in a regular user."; 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnOfflineInit(false, OUTCOME_WRONG_USER_TYPE); 371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionService* extension_service = 375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extensions::ExtensionSystem::Get(profile_)->extension_service(); 376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!extension_service->GetExtensionById(drive_hosted_app_id_, false)) { 377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) LOG(WARNING) << "Drive app is not installed."; 3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnOfflineInit(false, OUTCOME_APP_NOT_INSTALLED); 379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BackgroundContentsService* background_contents_service = 383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BackgroundContentsServiceFactory::GetForProfile(profile_); 384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (background_contents_service->GetAppBackgroundContents( 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::UTF8ToUTF16(drive_hosted_app_id_))) { 386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) LOG(WARNING) << "Background page for Drive app already exists"; 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnOfflineInit(false, OUTCOME_BACKGROUND_PAGE_EXISTS); 388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) web_contents_manager_.reset(new DriveWebContentsManager( 392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) profile_, 393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) drive_hosted_app_id_, 394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) drive_offline_endpoint_url_, 395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&DriveFirstRunController::OnOfflineInit, 396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Unretained(this)))); 397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) web_contents_manager_->StartLoad(); 398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) web_contents_timer_.Start( 399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FROM_HERE, 400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::TimeDelta::FromSeconds(web_contents_timeout_secs_), 401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) this, 402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &DriveFirstRunController::OnWebContentsTimedOut); 403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DriveFirstRunController::AddObserver(Observer* observer) { 406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) observer_list_.AddObserver(observer); 407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DriveFirstRunController::RemoveObserver(Observer* observer) { 410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) observer_list_.RemoveObserver(observer); 411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DriveFirstRunController::SetDelaysForTest(int initial_delay_secs, 414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int timeout_secs) { 415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!started_); 416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) initial_delay_secs_ = initial_delay_secs; 417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) web_contents_timeout_secs_ = timeout_secs; 418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DriveFirstRunController::SetAppInfoForTest( 421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& app_id, 422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& endpoint_url) { 423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!started_); 424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) drive_hosted_app_id_ = app_id; 425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) drive_offline_endpoint_url_ = endpoint_url; 426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DriveFirstRunController::OnWebContentsTimedOut() { 4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(WARNING) << "Timed out waiting for web contents."; 430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observer_list_, OnTimedOut()); 4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnOfflineInit(false, OUTCOME_WEB_CONTENTS_TIMED_OUT); 432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DriveFirstRunController::CleanUp() { 435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (web_contents_manager_) 436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) web_contents_manager_->StopLoad(); 437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) web_contents_timer_.Stop(); 438f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); 439f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DriveFirstRunController::OnOfflineInit(bool success, UMAOutcome outcome) { 442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 443a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (success) 444a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShowNotification(); 4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("DriveOffline.CrosAutoEnableOutcome", 4465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) outcome, OUTCOME_MAX); 447f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observer_list_, OnCompletion(success)); 448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CleanUp(); 449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 451a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void DriveFirstRunController::ShowNotification() { 452a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ExtensionService* service = 453a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) extensions::ExtensionSystem::Get(profile_)->extension_service(); 454a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(service); 455a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const extensions::Extension* extension = 456a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) service->GetExtensionById(drive_hosted_app_id_, false); 457a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(extension); 458a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 459a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) message_center::RichNotificationData data; 460a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) data.buttons.push_back(message_center::ButtonInfo( 461a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_DRIVE_OFFLINE_NOTIFICATION_BUTTON))); 462a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ui::ResourceBundle& resource_bundle = ui::ResourceBundle::GetSharedInstance(); 463a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<message_center::Notification> notification( 464a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) new message_center::Notification( 465a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) message_center::NOTIFICATION_TYPE_SIMPLE, 466a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) kDriveOfflineNotificationId, 467a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16(), // title 468a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_DRIVE_OFFLINE_NOTIFICATION_MESSAGE), 469a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) resource_bundle.GetImageNamed(IDR_NOTIFICATION_DRIVE), 470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::UTF8ToUTF16(extension->name()), 471a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) message_center::NotifierId(message_center::NotifierId::APPLICATION, 472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) kDriveHostedAppId), 473a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) data, 4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new DriveOfflineNotificationDelegate(profile_))); 475a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) notification->set_priority(message_center::LOW_PRIORITY); 476a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) message_center::MessageCenter::Get()->AddNotification(notification.Pass()); 477a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 478a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 479f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace chromeos 480