summaryrefslogtreecommitdiffstats
path: root/chrome/browser/shell_integration.h
blob: 29265227ff27ce5a29e2f2e98b14beb0373626dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_SHELL_INTEGRATION_H_
#define CHROME_BROWSER_SHELL_INTEGRATION_H_

#include <string>

#include "base/basictypes.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string16.h"
#include "ui/gfx/image/image_family.h"
#include "url/gurl.h"

class CommandLine;

class ShellIntegration {
 public:
  // Sets Chrome as the default browser (only for the current user). Returns
  // false if this operation fails.
  static bool SetAsDefaultBrowser();

  // Initiates an OS shell flow which (if followed by the user) should set
  // Chrome as the default browser. Returns false if the flow cannot be
  // initialized, if it is not supported (introduced for Windows 8) or if the
  // user cancels the operation. This is a blocking call and requires a FILE
  // thread. If Chrome is already default browser, no interactive dialog will be
  // shown and this method returns true.
  static bool SetAsDefaultBrowserInteractive();

  // Sets Chrome as the default client application for the given protocol
  // (only for the current user). Returns false if this operation fails.
  static bool SetAsDefaultProtocolClient(const std::string& protocol);

  // Initiates an OS shell flow which (if followed by the user) should set
  // Chrome as the default handler for |protocol|. Returns false if the flow
  // cannot be initialized, if it is not supported (introduced for Windows 8)
  // or if the user cancels the operation. This is a blocking call and requires
  // a FILE thread. If Chrome is already default for |protocol|, no interactive
  // dialog will be shown and this method returns true.
  static bool SetAsDefaultProtocolClientInteractive(
      const std::string& protocol);

  // In Windows 8 a browser can be made default-in-metro only in an interactive
  // flow. We will distinguish between two types of permissions here to avoid
  // forcing the user into UI interaction when this should not be done.
  enum DefaultWebClientSetPermission {
    SET_DEFAULT_NOT_ALLOWED,
    SET_DEFAULT_UNATTENDED,
    SET_DEFAULT_INTERACTIVE,
  };

  // Returns requirements for making the running browser the user's default.
  static DefaultWebClientSetPermission CanSetAsDefaultBrowser();

  // Returns requirements for making the running browser the user's default
  // client application for specific protocols.
  static DefaultWebClientSetPermission CanSetAsDefaultProtocolClient();

  // Returns a string representing the application to be launched given the
  // protocol of the requested url. This string may be a name or a path, but
  // neither is guaranteed and it should only be used as a display string.
  // Returns an empty string on failure.
  static base::string16 GetApplicationNameForProtocol(const GURL& url);

  // On Linux, it may not be possible to determine or set the default browser
  // on some desktop environments or configurations. So, we use this enum and
  // not a plain bool.
  enum DefaultWebClientState {
    NOT_DEFAULT,
    IS_DEFAULT,
    UNKNOWN_DEFAULT,
    NUM_DEFAULT_STATES
  };

  // Attempt to determine if this instance of Chrome is the default browser and
  // return the appropriate state. (Defined as being the handler for HTTP/HTTPS
  // protocols; we don't want to report "no" here if the user has simply chosen
  // to open HTML files in a text editor and FTP links with an FTP client.)
  static DefaultWebClientState GetDefaultBrowser();

  // Returns true if Firefox is likely to be the default browser for the current
  // user. This method is very fast so it can be invoked in the UI thread.
  static bool IsFirefoxDefaultBrowser();

  // Attempt to determine if this instance of Chrome is the default client
  // application for the given protocol and return the appropriate state.
  static DefaultWebClientState
      IsDefaultProtocolClient(const std::string& protocol);

  struct ShortcutInfo {
    ShortcutInfo();
    ~ShortcutInfo();

    GURL url;
    // If |extension_id| is non-empty, this is short cut is to an extension-app
    // and the launch url will be detected at start-up. In this case, |url|
    // is still used to generate the app id (windows app id, not chrome app id).
    std::string extension_id;
    bool is_platform_app;
    base::string16 title;
    base::string16 description;
    base::FilePath extension_path;
    gfx::ImageFamily favicon;
    base::FilePath profile_path;
    std::string profile_name;
  };

  // This specifies a folder in the system applications menu (e.g the Start Menu
  // on Windows).
  //
  // These represent the applications menu root, the "Google Chrome" folder and
  // the "Chrome Apps" folder respectively.
  //
  // NB: On Linux, these locations may not be used by the window manager (e.g
  // Unity and Gnome Shell).
  enum ApplicationsMenuLocation {
    APP_MENU_LOCATION_NONE,
    APP_MENU_LOCATION_ROOT,
    APP_MENU_LOCATION_SUBDIR_CHROME,
    APP_MENU_LOCATION_SUBDIR_CHROMEAPPS,
  };

  // Info about which locations to create app shortcuts in.
  struct ShortcutLocations {
    ShortcutLocations();

    bool on_desktop;

    ApplicationsMenuLocation applications_menu_location;

    // For Windows, this refers to quick launch bar prior to Win7. In Win7,
    // this means "pin to taskbar". For Mac/Linux, this could be used for
    // Mac dock or the gnome/kde application launcher. However, those are not
    // implemented yet.
    bool in_quick_launch_bar;

#if defined(OS_POSIX)
    // For Linux, this refers to a shortcut which the system knows about (for
    // the purpose of identifying windows and giving them the correct
    // title/icon), but which does not show up in menus or search results.
    // Ignored if applications_menu_location is not APP_MENU_LOCATION_NONE.
    bool hidden;
#endif
  };

  // Data that needs to be passed between the app launcher stub and Chrome.
  struct AppModeInfo {
  };
  static void SetAppModeInfo(const AppModeInfo* info);
  static const AppModeInfo* AppModeInfo();

  // Is the current instance of Chrome running in App mode.
  bool IsRunningInAppMode();

  // Set up command line arguments for launching a URL or an app.
  // The new command line reuses the current process's user data directory (and
  // login profile, for ChromeOS).
  // If |extension_app_id| is non-empty, the arguments use kAppId=<id>.
  // Otherwise, kApp=<url> is used.
  static CommandLine CommandLineArgsForLauncher(
      const GURL& url,
      const std::string& extension_app_id,
      const base::FilePath& profile_path);

  // Append command line arguments for launching a new chrome.exe process
  // based on the current process.
  // The new command line reuses the current process's user data directory and
  // profile.
  static void AppendProfileArgs(const base::FilePath& profile_path,
                                CommandLine* command_line);

#if defined(OS_WIN)
  // Generates an application user model ID (AppUserModelId) for a given app
  // name and profile path. The returned app id is in the format of
  // "|app_name|[.<profile_id>]". "profile_id" is appended when user override
  // the default value.
  // Note: If the app has an installation specific suffix (e.g. on user-level
  // Chrome installs), |app_name| should already be suffixed, this method will
  // then further suffix it with the profile id as described above.
  static base::string16 GetAppModelIdForProfile(const base::string16& app_name,
                                          const base::FilePath& profile_path);

  // Generates an application user model ID (AppUserModelId) for Chromium by
  // calling GetAppModelIdForProfile() with ShellUtil::GetAppId() as app_name.
  static base::string16 GetChromiumModelIdForProfile(
      const base::FilePath& profile_path);

  // Get the AppUserModelId for the App List, for the profile in |profile_path|.
  static base::string16 GetAppListAppModelIdForProfile(
      const base::FilePath& profile_path);

  // Migrates existing chrome shortcuts by tagging them with correct app id.
  // see http://crbug.com/28104
  static void MigrateChromiumShortcuts();

  // Migrates all shortcuts in |path| which point to |chrome_exe| such that they
  // have the appropriate AppUserModelId. Also makes sure those shortcuts have
  // the dual_mode property set if such is requested by |check_dual_mode|.
  // Returns the number of shortcuts migrated.
  // This method should not be called prior to Windows 7.
  // This method is only public for the sake of tests and shouldn't be called
  // externally otherwise.
  static int MigrateShortcutsInPathInternal(const base::FilePath& chrome_exe,
                                            const base::FilePath& path,
                                            bool check_dual_mode);

  // Returns the path to the Start Menu shortcut for the given Chrome.
  static base::FilePath GetStartMenuShortcut(const base::FilePath& chrome_exe);
#endif  // defined(OS_WIN)

#if !defined(OS_WIN)
  // TODO(calamity): replace with
  // BrowserDistribution::GetStartMenuShortcutSubfolder() once
  // BrowserDistribution is cross-platform.
  // Gets the name of the Chrome Apps menu folder in which to place app
  // shortcuts. This is needed for Mac and Linux.
  static base::string16 GetAppShortcutsSubdirName();
#endif

  // The current default web client application UI state. This is used when
  // querying if Chrome is the default browser or the default handler
  // application for a url protocol, and communicates the state and result of
  // a request.
  enum DefaultWebClientUIState {
    STATE_PROCESSING,
    STATE_NOT_DEFAULT,
    STATE_IS_DEFAULT,
    STATE_UNKNOWN
  };

  class DefaultWebClientObserver {
   public:
    virtual ~DefaultWebClientObserver() {}
    // Updates the UI state to reflect the current default browser state.
    virtual void SetDefaultWebClientUIState(DefaultWebClientUIState state) = 0;
    // Called to notify the UI of the immediate result of invoking
    // SetAsDefault.
    virtual void OnSetAsDefaultConcluded(bool succeeded) {}
    // Observer classes that return true to OwnedByWorker are automatically
    // freed by the worker when they are no longer needed. False by default.
    virtual bool IsOwnedByWorker();
    // An observer can permit or decline set-as-default operation if it
    // requires triggering user interaction. By default not allowed.
    virtual bool IsInteractiveSetDefaultPermitted();
  };

  //  Helper objects that handle checking if Chrome is the default browser
  //  or application for a url protocol on Windows and Linux, and also setting
  //  it as the default. These operations are performed asynchronously on the
  //  file thread since registry access (on Windows) or the preference database
  //  (on Linux) are involved and this can be slow.
  class DefaultWebClientWorker
      : public base::RefCountedThreadSafe<DefaultWebClientWorker> {
   public:
    explicit DefaultWebClientWorker(DefaultWebClientObserver* observer);

    // Checks to see if Chrome is the default web client application. The result
    // will be passed back to the observer via the SetDefaultWebClientUIState
    // function. If there is no observer, this function does not do anything.
    void StartCheckIsDefault();

    // Sets Chrome as the default web client application. If there is an
    // observer, once the operation has completed the new default will be
    // queried and the current status reported via SetDefaultWebClientUIState.
    void StartSetAsDefault();

    // Called to notify the worker that the view is gone.
    void ObserverDestroyed();

   protected:
    friend class base::RefCountedThreadSafe<DefaultWebClientWorker>;

    virtual ~DefaultWebClientWorker() {}

   private:
    // Function that performs the check.
    virtual DefaultWebClientState CheckIsDefault() = 0;

    // Function that sets Chrome as the default web client. Returns false if
    // the operation fails or has been cancelled by the user.
    virtual bool SetAsDefault(bool interactive_permitted) = 0;

    // Function that handles performing the check on the file thread. This
    // function is posted as a task onto the file thread, where it performs
    // the check. When the check has finished the CompleteCheckIsDefault
    // function is posted to the UI thread, where the result is sent back to
    // the observer.
    void ExecuteCheckIsDefault();

    // Function that handles setting Chrome as the default web client on the
    // file thread. This function is posted as a task onto the file thread.
    // Once it is finished the CompleteSetAsDefault function is posted to the
    // UI thread which will check the status of Chrome as the default, and
    // send this to the observer.
    // |interactive_permitted| indicates if the routine is allowed to carry on
    // in context where user interaction is required (CanSetAsDefault*
    // returns SET_DEFAULT_INTERACTIVE).
    void ExecuteSetAsDefault(bool interactive_permitted);

    // Communicate results to the observer. This function is posted as a task
    // onto the UI thread by the ExecuteCheckIsDefault function running in the
    // file thread.
    void CompleteCheckIsDefault(DefaultWebClientState state);

    // When the action to set Chrome as the default has completed this function
    // is run. It is posted as a task back onto the UI thread by the
    // ExecuteSetAsDefault function running in the file thread. This function
    // will the start the check process, which, if an observer is present,
    // reports to it the new status.
    // |succeeded| is true if the actual call to a set-default function (from
    // ExecuteSetAsDefault) was successful.
    void CompleteSetAsDefault(bool succeeded);

    // Updates the UI in our associated view with the current default web
    // client state.
    void UpdateUI(DefaultWebClientState state);

    DefaultWebClientObserver* observer_;

    DISALLOW_COPY_AND_ASSIGN(DefaultWebClientWorker);
  };

  // Worker for checking and setting the default browser.
  class DefaultBrowserWorker : public DefaultWebClientWorker {
   public:
    explicit DefaultBrowserWorker(DefaultWebClientObserver* observer);

   private:
    virtual ~DefaultBrowserWorker() {}

    // Check if Chrome is the default browser.
    virtual DefaultWebClientState CheckIsDefault() OVERRIDE;

    // Set Chrome as the default browser.
    virtual bool SetAsDefault(bool interactive_permitted) OVERRIDE;

    DISALLOW_COPY_AND_ASSIGN(DefaultBrowserWorker);
  };

  // Worker for checking and setting the default client application
  // for a given protocol. A different worker instance is needed for each
  // protocol you are interested in, so to check or set the default for
  // multiple protocols you should use multiple worker objects.
  class DefaultProtocolClientWorker : public DefaultWebClientWorker {
   public:
    DefaultProtocolClientWorker(DefaultWebClientObserver* observer,
                                const std::string& protocol);

    const std::string& protocol() const { return protocol_; }

   protected:
    virtual ~DefaultProtocolClientWorker() {}

   private:
    // Check is Chrome is the default handler for this protocol.
    virtual DefaultWebClientState CheckIsDefault() OVERRIDE;

    // Set Chrome as the default handler for this protocol.
    virtual bool SetAsDefault(bool interactive_permitted) OVERRIDE;

    std::string protocol_;

    DISALLOW_COPY_AND_ASSIGN(DefaultProtocolClientWorker);
  };
};

#endif  // CHROME_BROWSER_SHELL_INTEGRATION_H_