1 // Copyright (c) 2012 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 #ifndef CHROME_BROWSER_BACKGROUND_BACKGROUND_CONTENTS_SERVICE_H_ 6 #define CHROME_BROWSER_BACKGROUND_BACKGROUND_CONTENTS_SERVICE_H_ 7 8 #include <map> 9 #include <string> 10 #include <vector> 11 12 #include "base/gtest_prod_util.h" 13 #include "base/memory/ref_counted.h" 14 #include "chrome/browser/tab_contents/background_contents.h" 15 #include "components/browser_context_keyed_service/browser_context_keyed_service.h" 16 #include "content/public/browser/notification_observer.h" 17 #include "content/public/browser/notification_registrar.h" 18 #include "content/public/common/window_container_type.h" 19 #include "ui/base/window_open_disposition.h" 20 #include "url/gurl.h" 21 22 class CommandLine; 23 class PrefService; 24 class Profile; 25 26 namespace base { 27 class DictionaryValue; 28 } 29 30 namespace content { 31 class SessionStorageNamespace; 32 } 33 34 namespace extensions { 35 class Extension; 36 } 37 38 namespace gfx { 39 class Rect; 40 } 41 42 struct BackgroundContentsOpenedDetails; 43 44 // BackgroundContentsService is owned by the profile, and is responsible for 45 // managing the lifetime of BackgroundContents (tracking the set of background 46 // urls, loading them at startup, and keeping the browser process alive as long 47 // as there are BackgroundContents loaded). 48 // 49 // It is also responsible for tracking the association between 50 // BackgroundContents and their parent app, and shutting them down when the 51 // parent app is unloaded. 52 class BackgroundContentsService : private content::NotificationObserver, 53 public BackgroundContents::Delegate, 54 public BrowserContextKeyedService { 55 public: 56 BackgroundContentsService(Profile* profile, const CommandLine* command_line); 57 virtual ~BackgroundContentsService(); 58 59 // Allows tests to reduce the time between a force-installed app/extension 60 // crashing and when we reload it. 61 static void SetRestartDelayForForceInstalledAppsAndExtensionsForTesting( 62 int restart_delay_in_ms); 63 64 // Returns the BackgroundContents associated with the passed application id, 65 // or NULL if none. 66 BackgroundContents* GetAppBackgroundContents(const base::string16& appid); 67 68 // Returns true if there's a registered BackgroundContents for this app. It 69 // is possible for this routine to return true when GetAppBackgroundContents() 70 // returns false, if the BackgroundContents closed due to the render process 71 // crashing. 72 bool HasRegisteredBackgroundContents(const base::string16& appid); 73 74 // Returns all currently opened BackgroundContents (used by the task manager). 75 std::vector<BackgroundContents*> GetBackgroundContents() const; 76 77 // BackgroundContents::Delegate implementation. 78 virtual void AddWebContents(content::WebContents* new_contents, 79 WindowOpenDisposition disposition, 80 const gfx::Rect& initial_pos, 81 bool user_gesture, 82 bool* was_blocked) OVERRIDE; 83 84 // Gets the parent application id for the passed BackgroundContents. Returns 85 // an empty string if no parent application found (e.g. passed 86 // BackgroundContents has already shut down). 87 const base::string16& GetParentApplicationId(BackgroundContents* contents) const; 88 89 // Creates a new BackgroundContents using the passed |site| and 90 // the |route_id| and begins tracking the object internally so it can be 91 // shutdown if the parent application is uninstalled. 92 // A BACKGROUND_CONTENTS_OPENED notification will be generated with the passed 93 // |frame_name| and |application_id| values, using the passed |profile| as the 94 // Source.. 95 BackgroundContents* CreateBackgroundContents( 96 content::SiteInstance* site, 97 int route_id, 98 Profile* profile, 99 const base::string16& frame_name, 100 const base::string16& application_id, 101 const std::string& partition_id, 102 content::SessionStorageNamespace* session_storage_namespace); 103 104 // Load the manifest-specified background page for the specified hosted app. 105 // If the manifest doesn't specify one, then load the BackgroundContents 106 // registered in the pref. This is typically used to reload a crashed 107 // background page. 108 void LoadBackgroundContentsForExtension(Profile* profile, 109 const std::string& extension_id); 110 111 private: 112 friend class BackgroundContentsServiceTest; 113 friend class MockBackgroundContents; 114 friend class TaskManagerNoShowBrowserTest; 115 116 FRIEND_TEST_ALL_PREFIXES(BackgroundContentsServiceTest, 117 BackgroundContentsCreateDestroy); 118 FRIEND_TEST_ALL_PREFIXES(BackgroundContentsServiceTest, 119 TestApplicationIDLinkage); 120 FRIEND_TEST_ALL_PREFIXES(TaskManagerNoShowBrowserTest, 121 NoticeBGContentsChanges); 122 FRIEND_TEST_ALL_PREFIXES(TaskManagerNoShowBrowserTest, 123 KillBGContents); 124 125 // Registers for various notifications. 126 void StartObserving(Profile* profile); 127 128 // content::NotificationObserver implementation. 129 virtual void Observe(int type, 130 const content::NotificationSource& source, 131 const content::NotificationDetails& details) OVERRIDE; 132 133 // Restarts a force-installed app/extension after a crash. 134 void RestartForceInstalledExtensionOnCrash( 135 const extensions::Extension* extension, 136 Profile* profile); 137 138 // Loads all registered BackgroundContents at startup. 139 void LoadBackgroundContentsFromPrefs(Profile* profile); 140 141 // Load a BackgroundContent; the settings are read from the provided 142 // dictionary. 143 void LoadBackgroundContentsFromDictionary( 144 Profile* profile, 145 const std::string& extension_id, 146 const base::DictionaryValue* contents); 147 148 // Load the manifest-specified BackgroundContents for all apps for the 149 // profile. 150 void LoadBackgroundContentsFromManifests(Profile* profile); 151 152 // Creates a single BackgroundContents associated with the specified |appid|, 153 // creates an associated RenderView with the name specified by |frame_name|, 154 // and navigates to the passed |url|. 155 void LoadBackgroundContents(Profile* profile, 156 const GURL& url, 157 const base::string16& frame_name, 158 const base::string16& appid); 159 160 // Invoked when a new BackgroundContents is opened. 161 void BackgroundContentsOpened(BackgroundContentsOpenedDetails* details); 162 163 // Invoked when a BackgroundContents object is destroyed. 164 void BackgroundContentsShutdown(BackgroundContents* contents); 165 166 // Registers the |contents->GetURL()| to be run at startup. Only happens for 167 // the first navigation after window.open() (future calls to 168 // RegisterBackgroundContents() for the same BackgroundContents will do 169 // nothing). 170 void RegisterBackgroundContents(BackgroundContents* contents); 171 172 // Stops loading the passed BackgroundContents on startup. 173 void UnregisterBackgroundContents(BackgroundContents* contents); 174 175 // Unregisters and deletes the BackgroundContents associated with the 176 // passed extension. 177 void ShutdownAssociatedBackgroundContents(const base::string16& appid); 178 179 // Returns true if this BackgroundContents is in the contents_list_. 180 bool IsTracked(BackgroundContents* contents) const; 181 182 // Sends out a notification when our association of background contents with 183 // apps may have changed (used by BackgroundApplicationListModel to update the 184 // set of background apps as new background contents are opened/closed). 185 void SendChangeNotification(Profile* profile); 186 187 // Delay (in ms) before restarting a force-installed extension that crashed. 188 static int restart_delay_in_ms_; 189 190 // PrefService used to store list of background pages (or NULL if this is 191 // running under an incognito profile). 192 PrefService* prefs_; 193 content::NotificationRegistrar registrar_; 194 195 // Information we track about each BackgroundContents. 196 struct BackgroundContentsInfo { 197 // The BackgroundContents whose information we are tracking. 198 BackgroundContents* contents; 199 // The name of the top level frame for this BackgroundContents. 200 base::string16 frame_name; 201 }; 202 203 // Map associating currently loaded BackgroundContents with their parent 204 // applications. 205 // Key: application id 206 // Value: BackgroundContentsInfo for the BC associated with that application 207 typedef std::map<base::string16, BackgroundContentsInfo> 208 BackgroundContentsMap; 209 BackgroundContentsMap contents_map_; 210 211 DISALLOW_COPY_AND_ASSIGN(BackgroundContentsService); 212 }; 213 214 #endif // CHROME_BROWSER_BACKGROUND_BACKGROUND_CONTENTS_SERVICE_H_ 215