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_AUTOCOMPLETE_EXTENSION_APP_PROVIDER_H_
6#define CHROME_BROWSER_AUTOCOMPLETE_EXTENSION_APP_PROVIDER_H_
7
8#include <vector>
9
10#include "base/basictypes.h"
11#include "base/compiler_specific.h"
12#include "base/gtest_prod_util.h"
13#include "chrome/browser/autocomplete/autocomplete_input.h"
14#include "chrome/browser/autocomplete/autocomplete_match.h"
15#include "chrome/browser/autocomplete/autocomplete_provider.h"
16#include "content/public/browser/notification_observer.h"
17#include "content/public/browser/notification_registrar.h"
18#include "ui/base/window_open_disposition.h"
19
20// This provider is responsible for keeping track of which Extension Apps are
21// installed and their URLs.  An instance of it gets created and managed by
22// AutocompleteController.
23class ExtensionAppProvider : public AutocompleteProvider,
24                             public content::NotificationObserver {
25 public:
26  ExtensionAppProvider(AutocompleteProviderListener* listener,
27                       Profile* profile);
28
29  // AutocompleteProvider:
30  virtual void Start(const AutocompleteInput& input,
31                     bool minimal_changes) OVERRIDE;
32
33  // Launch an Extension App from |match| details provided by the Omnibox. If
34  // the application wants to launch as a window or panel, |disposition| is
35  // ignored; otherwise it's used to determine in which tab we'll launch the
36  // application.
37  static void LaunchAppFromOmnibox(const AutocompleteMatch& match,
38                                   Profile* profile,
39                                   WindowOpenDisposition disposition);
40
41 private:
42  friend class ExtensionAppProviderTest;
43  FRIEND_TEST_ALL_PREFIXES(ExtensionAppProviderTest, CreateMatchSanitize);
44
45  // ExtensionApp stores the minimal metadata that we need to match against
46  // eligible apps.
47  struct ExtensionApp {
48    // App's name.
49    string16 name;
50    // App's launch URL (for platform apps, which don't have a launch URL, this
51    // just points to the app's origin).
52    string16 launch_url;
53    // If false, then the launch_url will not be considered for matching,
54    // not shown next to the match, and not displayed as the editable text if
55    // the user selects the match with the arrow keys.
56    bool should_match_against_launch_url;
57  };
58  typedef std::vector<ExtensionApp> ExtensionApps;
59
60  virtual ~ExtensionAppProvider();
61
62  void AddExtensionAppForTesting(const ExtensionApp& extension_app);
63
64  // Construct a match for the specified parameters.
65  AutocompleteMatch CreateAutocompleteMatch(const AutocompleteInput& input,
66                                            const ExtensionApp& app,
67                                            size_t name_match_index,
68                                            size_t url_match_index);
69
70  // Fetch the current app list and cache it locally.
71  void RefreshAppList();
72
73  // Calculate the relevance of the match.
74  int CalculateRelevance(AutocompleteInput::Type type,
75                         int input_length,
76                         int target_length,
77                         const GURL& url);
78
79  // content::NotificationObserver implementation:
80  virtual void Observe(int type,
81                       const content::NotificationSource& source,
82                       const content::NotificationDetails& details) OVERRIDE;
83
84  content::NotificationRegistrar registrar_;
85
86  // Our cache of ExtensionApp objects (name + url) representing the extension
87  // apps we know/care about.
88  ExtensionApps extension_apps_;
89
90  DISALLOW_COPY_AND_ASSIGN(ExtensionAppProvider);
91};
92
93#endif  // CHROME_BROWSER_AUTOCOMPLETE_EXTENSION_APP_PROVIDER_H_
94