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_SHELL_INTEGRATION_H_ 6 #define CHROME_BROWSER_SHELL_INTEGRATION_H_ 7 8 #include <string> 9 10 #include "base/basictypes.h" 11 #include "base/files/file_path.h" 12 #include "base/memory/ref_counted.h" 13 #include "base/strings/string16.h" 14 #include "ui/gfx/image/image_family.h" 15 #include "url/gurl.h" 16 17 class CommandLine; 18 19 class ShellIntegration { 20 public: 21 // Sets Chrome as the default browser (only for the current user). Returns 22 // false if this operation fails. 23 static bool SetAsDefaultBrowser(); 24 25 // Initiates an OS shell flow which (if followed by the user) should set 26 // Chrome as the default browser. Returns false if the flow cannot be 27 // initialized, if it is not supported (introduced for Windows 8) or if the 28 // user cancels the operation. This is a blocking call and requires a FILE 29 // thread. If Chrome is already default browser, no interactive dialog will be 30 // shown and this method returns true. 31 static bool SetAsDefaultBrowserInteractive(); 32 33 // Sets Chrome as the default client application for the given protocol 34 // (only for the current user). Returns false if this operation fails. 35 static bool SetAsDefaultProtocolClient(const std::string& protocol); 36 37 // Initiates an OS shell flow which (if followed by the user) should set 38 // Chrome as the default handler for |protocol|. Returns false if the flow 39 // cannot be initialized, if it is not supported (introduced for Windows 8) 40 // or if the user cancels the operation. This is a blocking call and requires 41 // a FILE thread. If Chrome is already default for |protocol|, no interactive 42 // dialog will be shown and this method returns true. 43 static bool SetAsDefaultProtocolClientInteractive( 44 const std::string& protocol); 45 46 // In Windows 8 a browser can be made default-in-metro only in an interactive 47 // flow. We will distinguish between two types of permissions here to avoid 48 // forcing the user into UI interaction when this should not be done. 49 enum DefaultWebClientSetPermission { 50 SET_DEFAULT_NOT_ALLOWED, 51 SET_DEFAULT_UNATTENDED, 52 SET_DEFAULT_INTERACTIVE, 53 }; 54 55 // Returns requirements for making the running browser the user's default. 56 static DefaultWebClientSetPermission CanSetAsDefaultBrowser(); 57 58 // Returns requirements for making the running browser the user's default 59 // client application for specific protocols. 60 static DefaultWebClientSetPermission CanSetAsDefaultProtocolClient(); 61 62 // Returns the path of the application to be launched given the protocol 63 // of the requested url. Returns an empty string on failure. 64 static std::string GetApplicationForProtocol(const GURL& url); 65 66 // On Linux, it may not be possible to determine or set the default browser 67 // on some desktop environments or configurations. So, we use this enum and 68 // not a plain bool. 69 enum DefaultWebClientState { 70 NOT_DEFAULT, 71 IS_DEFAULT, 72 UNKNOWN_DEFAULT, 73 NUM_DEFAULT_STATES 74 }; 75 76 // Attempt to determine if this instance of Chrome is the default browser and 77 // return the appropriate state. (Defined as being the handler for HTTP/HTTPS 78 // protocols; we don't want to report "no" here if the user has simply chosen 79 // to open HTML files in a text editor and FTP links with an FTP client.) 80 static DefaultWebClientState GetDefaultBrowser(); 81 82 // Returns true if Firefox is likely to be the default browser for the current 83 // user. This method is very fast so it can be invoked in the UI thread. 84 static bool IsFirefoxDefaultBrowser(); 85 86 // Attempt to determine if this instance of Chrome is the default client 87 // application for the given protocol and return the appropriate state. 88 static DefaultWebClientState 89 IsDefaultProtocolClient(const std::string& protocol); 90 91 struct ShortcutInfo { 92 ShortcutInfo(); 93 ~ShortcutInfo(); 94 95 GURL url; 96 // If |extension_id| is non-empty, this is short cut is to an extension-app 97 // and the launch url will be detected at start-up. In this case, |url| 98 // is still used to generate the app id (windows app id, not chrome app id). 99 std::string extension_id; 100 bool is_platform_app; 101 string16 title; 102 string16 description; 103 base::FilePath extension_path; 104 gfx::ImageFamily favicon; 105 base::FilePath profile_path; 106 std::string profile_name; 107 }; 108 109 // Info about which locations to create app shortcuts in. 110 struct ShortcutLocations { 111 ShortcutLocations(); 112 113 bool on_desktop; 114 bool in_applications_menu; 115 string16 applications_menu_subdir; 116 117 // For Windows, this refers to quick launch bar prior to Win7. In Win7, 118 // this means "pin to taskbar". For Mac/Linux, this could be used for 119 // Mac dock or the gnome/kde application launcher. However, those are not 120 // implemented yet. 121 bool in_quick_launch_bar; 122 123 // For Linux, this refers to a shortcut which the system knows about (for 124 // the purpose of identifying windows and giving them the correct 125 // title/icon), but which does not show up in menus or search results. 126 // Ignored if in_applications_menu == true. 127 bool hidden; 128 }; 129 130 // Data that needs to be passed between the app launcher stub and Chrome. 131 struct AppModeInfo { 132 }; 133 static void SetAppModeInfo(const AppModeInfo* info); 134 static const AppModeInfo* AppModeInfo(); 135 136 // Is the current instance of Chrome running in App mode. 137 bool IsRunningInAppMode(); 138 139 // Set up command line arguments for launching a URL or an app. 140 // The new command line reuses the current process's user data directory (and 141 // login profile, for ChromeOS). 142 // If |extension_app_id| is non-empty, the arguments use kAppId=<id>. 143 // Otherwise, kApp=<url> is used. 144 static CommandLine CommandLineArgsForLauncher( 145 const GURL& url, 146 const std::string& extension_app_id, 147 const base::FilePath& profile_path); 148 149 #if defined(OS_WIN) 150 // Generates an application user model ID (AppUserModelId) for a given app 151 // name and profile path. The returned app id is in the format of 152 // "|app_name|[.<profile_id>]". "profile_id" is appended when user override 153 // the default value. 154 // Note: If the app has an installation specific suffix (e.g. on user-level 155 // Chrome installs), |app_name| should already be suffixed, this method will 156 // then further suffix it with the profile id as described above. 157 static string16 GetAppModelIdForProfile(const string16& app_name, 158 const base::FilePath& profile_path); 159 160 // Generates an application user model ID (AppUserModelId) for Chromium by 161 // calling GetAppModelIdForProfile() with ShellUtil::GetAppId() as app_name. 162 static string16 GetChromiumModelIdForProfile( 163 const base::FilePath& profile_path); 164 165 // Get the AppUserModelId for the App List, for the profile in |profile_path|. 166 static string16 GetAppListAppModelIdForProfile( 167 const base::FilePath& profile_path); 168 169 // Returns the location (path and index) of the Chromium icon, (e.g., 170 // "C:\path\to\chrome.exe,0"). This is used to specify the icon to use 171 // for the taskbar group on Win 7. 172 static string16 GetChromiumIconLocation(); 173 174 // Migrates existing chrome shortcuts by tagging them with correct app id. 175 // see http://crbug.com/28104 176 static void MigrateChromiumShortcuts(); 177 178 // Migrates all shortcuts in |path| which point to |chrome_exe| such that they 179 // have the appropriate AppUserModelId. Also makes sure those shortcuts have 180 // the dual_mode property set if such is requested by |check_dual_mode|. 181 // Returns the number of shortcuts migrated. 182 // This method should not be called prior to Windows 7. 183 // This method is only public for the sake of tests and shouldn't be called 184 // externally otherwise. 185 static int MigrateShortcutsInPathInternal(const base::FilePath& chrome_exe, 186 const base::FilePath& path, 187 bool check_dual_mode); 188 189 // Returns the path to the Start Menu shortcut for the given Chrome. 190 static base::FilePath GetStartMenuShortcut(const base::FilePath& chrome_exe); 191 #endif // defined(OS_WIN) 192 193 // The current default web client application UI state. This is used when 194 // querying if Chrome is the default browser or the default handler 195 // application for a url protocol, and communicates the state and result of 196 // a request. 197 enum DefaultWebClientUIState { 198 STATE_PROCESSING, 199 STATE_NOT_DEFAULT, 200 STATE_IS_DEFAULT, 201 STATE_UNKNOWN 202 }; 203 204 class DefaultWebClientObserver { 205 public: 206 virtual ~DefaultWebClientObserver() {} 207 // Updates the UI state to reflect the current default browser state. 208 virtual void SetDefaultWebClientUIState(DefaultWebClientUIState state) = 0; 209 // Called to notify the UI of the immediate result of invoking 210 // SetAsDefault. 211 virtual void OnSetAsDefaultConcluded(bool succeeded) {} 212 // Observer classes that return true to OwnedByWorker are automatically 213 // freed by the worker when they are no longer needed. False by default. 214 virtual bool IsOwnedByWorker(); 215 // An observer can permit or decline set-as-default operation if it 216 // requires triggering user interaction. By default not allowed. 217 virtual bool IsInteractiveSetDefaultPermitted(); 218 }; 219 220 // Helper objects that handle checking if Chrome is the default browser 221 // or application for a url protocol on Windows and Linux, and also setting 222 // it as the default. These operations are performed asynchronously on the 223 // file thread since registry access (on Windows) or the preference database 224 // (on Linux) are involved and this can be slow. 225 class DefaultWebClientWorker 226 : public base::RefCountedThreadSafe<DefaultWebClientWorker> { 227 public: 228 explicit DefaultWebClientWorker(DefaultWebClientObserver* observer); 229 230 // Checks to see if Chrome is the default web client application. The result 231 // will be passed back to the observer via the SetDefaultWebClientUIState 232 // function. If there is no observer, this function does not do anything. 233 void StartCheckIsDefault(); 234 235 // Sets Chrome as the default web client application. If there is an 236 // observer, once the operation has completed the new default will be 237 // queried and the current status reported via SetDefaultWebClientUIState. 238 void StartSetAsDefault(); 239 240 // Called to notify the worker that the view is gone. 241 void ObserverDestroyed(); 242 243 protected: 244 friend class base::RefCountedThreadSafe<DefaultWebClientWorker>; 245 246 virtual ~DefaultWebClientWorker() {} 247 248 private: 249 // Function that performs the check. 250 virtual DefaultWebClientState CheckIsDefault() = 0; 251 252 // Function that sets Chrome as the default web client. Returns false if 253 // the operation fails or has been cancelled by the user. 254 virtual bool SetAsDefault(bool interactive_permitted) = 0; 255 256 // Function that handles performing the check on the file thread. This 257 // function is posted as a task onto the file thread, where it performs 258 // the check. When the check has finished the CompleteCheckIsDefault 259 // function is posted to the UI thread, where the result is sent back to 260 // the observer. 261 void ExecuteCheckIsDefault(); 262 263 // Function that handles setting Chrome as the default web client on the 264 // file thread. This function is posted as a task onto the file thread. 265 // Once it is finished the CompleteSetAsDefault function is posted to the 266 // UI thread which will check the status of Chrome as the default, and 267 // send this to the observer. 268 // |interactive_permitted| indicates if the routine is allowed to carry on 269 // in context where user interaction is required (CanSetAsDefault* 270 // returns SET_DEFAULT_INTERACTIVE). 271 void ExecuteSetAsDefault(bool interactive_permitted); 272 273 // Communicate results to the observer. This function is posted as a task 274 // onto the UI thread by the ExecuteCheckIsDefault function running in the 275 // file thread. 276 void CompleteCheckIsDefault(DefaultWebClientState state); 277 278 // When the action to set Chrome as the default has completed this function 279 // is run. It is posted as a task back onto the UI thread by the 280 // ExecuteSetAsDefault function running in the file thread. This function 281 // will the start the check process, which, if an observer is present, 282 // reports to it the new status. 283 // |succeeded| is true if the actual call to a set-default function (from 284 // ExecuteSetAsDefault) was successful. 285 void CompleteSetAsDefault(bool succeeded); 286 287 // Updates the UI in our associated view with the current default web 288 // client state. 289 void UpdateUI(DefaultWebClientState state); 290 291 DefaultWebClientObserver* observer_; 292 293 DISALLOW_COPY_AND_ASSIGN(DefaultWebClientWorker); 294 }; 295 296 // Worker for checking and setting the default browser. 297 class DefaultBrowserWorker : public DefaultWebClientWorker { 298 public: 299 explicit DefaultBrowserWorker(DefaultWebClientObserver* observer); 300 301 private: 302 virtual ~DefaultBrowserWorker() {} 303 304 // Check if Chrome is the default browser. 305 virtual DefaultWebClientState CheckIsDefault() OVERRIDE; 306 307 // Set Chrome as the default browser. 308 virtual bool SetAsDefault(bool interactive_permitted) OVERRIDE; 309 310 DISALLOW_COPY_AND_ASSIGN(DefaultBrowserWorker); 311 }; 312 313 // Worker for checking and setting the default client application 314 // for a given protocol. A different worker instance is needed for each 315 // protocol you are interested in, so to check or set the default for 316 // multiple protocols you should use multiple worker objects. 317 class DefaultProtocolClientWorker : public DefaultWebClientWorker { 318 public: 319 DefaultProtocolClientWorker(DefaultWebClientObserver* observer, 320 const std::string& protocol); 321 322 const std::string& protocol() const { return protocol_; } 323 324 protected: 325 virtual ~DefaultProtocolClientWorker() {} 326 327 private: 328 // Check is Chrome is the default handler for this protocol. 329 virtual DefaultWebClientState CheckIsDefault() OVERRIDE; 330 331 // Set Chrome as the default handler for this protocol. 332 virtual bool SetAsDefault(bool interactive_permitted) OVERRIDE; 333 334 std::string protocol_; 335 336 DISALLOW_COPY_AND_ASSIGN(DefaultProtocolClientWorker); 337 }; 338 }; 339 340 #endif // CHROME_BROWSER_SHELL_INTEGRATION_H_ 341