1 // Copyright 2020 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_UI_APP_LIST_SEARCH_OS_SETTINGS_PROVIDER_H_
6 #define CHROME_BROWSER_UI_APP_LIST_SEARCH_OS_SETTINGS_PROVIDER_H_
7 
8 #include <string>
9 #include <vector>
10 
11 #include "base/macros.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/time/time.h"
14 #include "chrome/browser/ui/app_list/search/chrome_search_result.h"
15 #include "chrome/browser/ui/app_list/search/search_provider.h"
16 #include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom.h"
17 #include "components/services/app_service/public/cpp/app_registry_cache.h"
18 #include "components/services/app_service/public/mojom/types.mojom.h"
19 #include "mojo/public/cpp/bindings/receiver.h"
20 #include "mojo/public/cpp/bindings/remote.h"
21 
22 class Profile;
23 
24 namespace apps {
25 class AppServiceProxy;
26 }  // namespace apps
27 
28 namespace chromeos {
29 namespace settings {
30 class Hierarchy;
31 class OsSettingsManager;
32 class SearchHandler;
33 }
34 }  // namespace chromeos
35 
36 namespace gfx {
37 class ImageSkia;
38 }
39 
40 namespace app_list {
41 
42 // Search results for OS settings.
43 class OsSettingsResult : public ChromeSearchResult {
44  public:
45   OsSettingsResult(Profile* profile,
46                    const chromeos::settings::mojom::SearchResultPtr& result,
47                    float relevance_score,
48                    const gfx::ImageSkia& icon);
49   ~OsSettingsResult() override;
50 
51   OsSettingsResult(const OsSettingsResult&) = delete;
52   OsSettingsResult& operator=(const OsSettingsResult&) = delete;
53 
54   // ChromeSearchResult:
55   void Open(int event_flags) override;
56 
57  private:
58   Profile* profile_;
59   const std::string url_path_;
60 };
61 
62 // Provider results for OS settings based on a search query. No results are
63 // provided for zero-state.
64 class OsSettingsProvider
65     : public SearchProvider,
66       public apps::AppRegistryCache::Observer,
67       public chromeos::settings::mojom::SearchResultsObserver {
68  public:
69   explicit OsSettingsProvider(Profile* profile);
70   ~OsSettingsProvider() override;
71 
72   OsSettingsProvider(const OsSettingsProvider&) = delete;
73   OsSettingsProvider& operator=(const OsSettingsProvider&) = delete;
74 
75   // SearchProvider:
76   void Start(const base::string16& query) override;
77   void ViewClosing() override;
78   ash::AppListSearchResultType ResultType() override;
79 
80   // apps::AppRegistryCache::Observer:
81   void OnAppUpdate(const apps::AppUpdate& update) override;
82   void OnAppRegistryCacheWillBeDestroyed(
83       apps::AppRegistryCache* cache) override;
84 
85   // mojom::SearchResultsObserver:
86   void OnSearchResultAvailabilityChanged() override;
87 
88  private:
89   void OnSearchReturned(
90       const base::string16& query,
91       const base::TimeTicks& start_time,
92       std::vector<chromeos::settings::mojom::SearchResultPtr> results);
93 
94   // Given a vector of results from the SearchHandler, filters them down to a
95   // display-ready vector. It:
96   // - returns at most |kMaxShownResults| results
97   // - removes results with duplicate IDs
98   // - removes results with relevance score below |min_score_|.
99   // - removes results matching alternate text unless they meet extra
100   //   requirements.
101   //
102   // The SearchHandler's vector is ranked high-to-low with this logic:
103   // - compares SearchResultDefaultRank,
104   // - if equal, compares relevance scores
105   // - if equal, compares SearchResultType, favoring sections over subpages over
106   //   settings
107   // - if equal, picks arbitrarily
108   //
109   // So simply iterating down the vector while being careful about duplicates
110   // and checking for alternate matches is enough.
111   std::vector<chromeos::settings::mojom::SearchResultPtr> FilterResults(
112       const base::string16& query,
113       const std::vector<chromeos::settings::mojom::SearchResultPtr>& results,
114       const chromeos::settings::Hierarchy* hierarchy);
115 
116   void OnLoadIcon(apps::mojom::IconValuePtr icon_value);
117 
118   // Scoring and filtering parameters controlled from Finch.
119   bool accept_alternate_matches_ = false;
120   size_t min_query_length_ = 4u;
121   size_t min_query_length_for_alternates_ = 4u;
122   float min_score_ = 0.4f;
123   float min_score_for_alternates_ = 0.4f;
124 
125   Profile* const profile_;
126   chromeos::settings::OsSettingsManager* const settings_manager_;
127   chromeos::settings::SearchHandler* search_handler_;
128   const chromeos::settings::Hierarchy* hierarchy_;
129   apps::AppServiceProxy* app_service_proxy_;
130   gfx::ImageSkia icon_;
131 
132   // Whether the app service has signalled the settings app as ready.
133   bool settings_app_ready_ = false;
134 
135   // Last query. It is reset when view is closed.
136   base::string16 last_query_;
137   mojo::Receiver<chromeos::settings::mojom::SearchResultsObserver>
138       search_results_observer_receiver_{this};
139 
140   base::WeakPtrFactory<OsSettingsProvider> weak_factory_{this};
141 };
142 
143 }  // namespace app_list
144 
145 #endif  // CHROME_BROWSER_UI_APP_LIST_SEARCH_OS_SETTINGS_PROVIDER_H_
146