Home | History | Annotate | Download | only in browser
      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