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