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