File: app_list_client_impl.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (294 lines) | stat: -rw-r--r-- 12,081 bytes parent folder | download | duplicates (3)
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
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_ASH_APP_LIST_APP_LIST_CLIENT_IMPL_H_
#define CHROME_BROWSER_ASH_APP_LIST_APP_LIST_CLIENT_IMPL_H_

#include <stdint.h>

#include <map>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "ash/app_list/apps_collections_controller.h"
#include "ash/public/cpp/app_list/app_list_client.h"
#include "ash/public/cpp/app_list/app_list_metrics.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ref.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "base/time/time.h"
#include "chrome/browser/ash/app_list/app_list_controller_delegate.h"
#include "chromeos/ash/services/assistant/public/cpp/assistant_browser_delegate.h"
#include "components/feature_engagement/public/tracker.h"
#include "components/search_engines/template_url_service.h"
#include "components/search_engines/template_url_service_observer.h"
#include "components/session_manager/core/session_manager_observer.h"
#include "components/user_manager/user_manager.h"
#include "ui/base/models/image_model.h"
#include "ui/display/types/display_constants.h"
#include "ui/gfx/image/image.h"

namespace app_list {
class AppListSurveyHandler;
class SearchController;
}  // namespace app_list

class AppListClientWithProfileTest;
class AppListNotifier;
class AppListModelUpdater;
class AppSyncUIStateWatcher;
class Profile;

class AppListClientImpl
    : public ash::AppListClient,
      public AppListControllerDelegate,
      public user_manager::UserManager::Observer,
      public user_manager::UserManager::UserSessionStateObserver,
      public session_manager::SessionManagerObserver,
      public TemplateURLServiceObserver {
 public:
  // Indicates the launcher usage state during the session started by a new user
  // (i.e. the session completing the OOBE flow) but before any account
  // switching. These are used in histograms, do not remove/renumber entries. If
  // you're adding to this enum with the intention that it will be logged,
  // update the AppListUsageStateByNewUsers enum listing in
  // tools/metrics/histograms/enums.xml.
  enum class AppListUsageStateByNewUsers {
    // Launcher is used during the session started by a new user.
    kUsed = 0,

    // Launcher is not used before destruction. The destruction can be triggered
    // in the following scenarios: logging out all account, shutting down the
    // device and system crashes.
    kNotUsedBeforeDestruction = 1,

    // Launcher is not used before switching accounts.
    kNotUsedBeforeSwitchingAccounts = 2,

    kMaxValue = kNotUsedBeforeSwitchingAccounts,
  };

  // `user_manage` must be non-null and must outlive `this`.
  explicit AppListClientImpl(user_manager::UserManager* user_manager);
  AppListClientImpl(const AppListClientImpl&) = delete;
  AppListClientImpl& operator=(const AppListClientImpl&) = delete;
  ~AppListClientImpl() override;

  static AppListClientImpl* GetInstance();

  // ash::AppListClient:
  void OnAppListControllerDestroyed() override;
  std::vector<ash::AppListSearchControlCategory> GetToggleableCategories()
      const override;
  void StartZeroStateSearch(base::OnceClosure on_done,
                            base::TimeDelta timeout) override;
  void StartSearch(const std::u16string& trimmed_query) override;
  void OpenSearchResult(int profile_id,
                        const std::string& result_id,
                        int event_flags,
                        ash::AppListLaunchedFrom launched_from,
                        ash::AppListLaunchType launch_type,
                        int suggestion_index,
                        bool launch_as_default) override;
  void InvokeSearchResultAction(const std::string& result_id,
                                ash::SearchResultActionType action) override;
  void ActivateItem(int profile_id,
                    const std::string& id,
                    int event_flags,
                    ash::AppListLaunchedFrom launched_from,
                    bool is_above_the_fold) override;
  void GetContextMenuModel(int profile_id,
                           const std::string& id,
                           ash::AppListItemContext item_context,
                           GetContextMenuModelCallback callback) override;
  void OnAppListVisibilityWillChange(bool visible) override;
  void OnAppListVisibilityChanged(bool visible) override;
  void OnSearchResultVisibilityChanged(const std::string& id,
                                       bool visible) override;
  void OnQuickSettingsChanged(
      const std::string& setting_name,
      const std::map<std::string, int>& values) override;
  ash::AppListNotifier* GetNotifier() override;
  void RecalculateWouldTriggerLauncherSearchIph() override;
  std::unique_ptr<ash::ScopedIphSession> CreateLauncherSearchIphSession()
      override;
  void LoadIcon(int profile_id, const std::string& app_id) override;
  ash::AppListSortOrder GetPermanentSortingOrder() const override;
  std::optional<bool> IsNewUser(const AccountId& account_id) const override;
  void RecordAppsDefaultVisibility(
      const std::vector<std::string>& apps_above_the_fold,
      const std::vector<std::string>& apps_below_the_fold,
      bool is_apps_collections_page) override;
  bool HasReordered() override;
  gfx::Image GetGeminiIcon() override;

  // user_manager::UserManager::Observer:
  void OnUserProfileCreated(const user_manager::User& user) override;

  // user_manager::UserManager::UserSessionStateObserver:
  void ActiveUserChanged(user_manager::User* active_user) override;

  // AppListControllerDelegate overrides:
  void DismissView() override;
  aura::Window* GetAppListWindow() override;
  int64_t GetAppListDisplayId() override;
  bool IsAppPinned(const std::string& app_id) override;
  bool IsAppOpen(const std::string& app_id) const override;
  void PinApp(const std::string& app_id) override;
  void UnpinApp(const std::string& app_id) override;
  Pinnable GetPinnable(const std::string& app_id) override;
  void CreateNewWindow(bool incognito,
                       bool should_trigger_session_restore) override;
  void OpenURL(Profile* profile,
               const GURL& url,
               ui::PageTransition transition,
               WindowOpenDisposition disposition) override;

  // Associates this client with the current active user, called when this
  // client is accessed or active user is changed.
  void UpdateProfile();

  void ShowAppList(ash::AppListShowSource source);

  bool app_list_target_visibility() const {
    return app_list_target_visibility_;
  }
  bool app_list_visible() const { return app_list_visible_; }

  // Returns a pointer to control the app list views in ash.
  ash::AppListController* GetAppListController() const;

  AppListControllerDelegate* GetControllerDelegate();
  Profile* GetCurrentAppListProfile() const;

  app_list::SearchController* search_controller();

  void SetSearchControllerForTest(
      std::unique_ptr<app_list::SearchController> test_controller);

  AppListModelUpdater* GetModelUpdaterForTest();

  // Initializes as if a new user logged in for testing.
  void InitializeAsIfNewUserLoginForTest();

  // Recalculate the default position of apps with a modified order.
  void MaybeRecalculateAppsGridDefaultOrder();

 private:
  friend class AppListSurveyTriggerTest;
  FRIEND_TEST_ALL_PREFIXES(AppListClientWithProfileTest, CheckDataRace);

  struct StateForNewUser {
    // Indicates whether showing the app list has been recorded.
    bool showing_recorded = false;
    bool shown_in_tablet_mode = false;

    // Indicates whether any launcher action has been recorded.
    bool action_recorded = false;

    // Whether the user entered a query into the search box.
    bool started_search = false;
    // Whether the result that the user launched during their first search
    // attempt got recorder.
    bool first_search_result_recorded = false;
  };

  // session_manager::SessionManagerObserver:
  void OnSessionStateChanged() override;

  // Overridden from TemplateURLServiceObserver:
  void OnTemplateURLServiceChanged() override;

  // Configures the AppList for the given |profile|.
  void SetProfile(Profile* profile);

  // Updates the speech webview and start page for the current |profile_|.
  void SetUpSearchUI();

  // Records the metrics related to showing the app list.
  void RecordViewShown(bool is_apps_collection_shown);

  // Records the browser window status + the opened search result type when
  // the result is opened from the search box.
  void RecordOpenedResultFromSearchBox(ash::SearchResultType result_type);

  // Maybe records the launcher action. Launcher actions include activating an
  // app and opening a search result from either a suggestion chip or the search
  // box. `launched_from` indicates where the launcher action comes from.
  void MaybeRecordLauncherAction(ash::AppListLaunchedFrom launched_from);

  // Maybe record an activated item's visibility. An app item visibility refers
  // to above or below the fold of the launcher (i.e. is it is visible without
  // scrolling or switching the page).
  void MaybeRecordActivatedItemVisibility(
      const std::string& id,
      ash::AppListLaunchedFrom launched_from,
      bool is_app_above_the_fold);

  const raw_ref<user_manager::UserManager> user_manager_;

  // Unowned pointer to the associated profile. May change if SetProfile is
  // called.
  raw_ptr<Profile> profile_ = nullptr;

  // Unowned pointer to the model updater owned by AppListSyncableService. Will
  // change if |profile_| changes.
  raw_ptr<AppListModelUpdater> current_model_updater_ = nullptr;

  // Store the mappings between profiles and AppListModelUpdater instances.
  // In multi-profile mode, mojo callings from the Ash process to access the app
  // list items should be dealt with the correct AppListModelUpdater instance.
  // Otherwise data race may happen, like the issue 939755
  // (https://crbug.com/939755).
  // TODO: Replace the mojo interface functions provided by AppListClient with
  // callbacks.
  std::map<int, raw_ptr<AppListModelUpdater, CtnExperimental>>
      profile_model_mappings_;

  std::unique_ptr<app_list::SearchController> search_controller_;
  std::unique_ptr<AppSyncUIStateWatcher> app_sync_ui_state_watcher_;

  base::ScopedObservation<TemplateURLService, TemplateURLServiceObserver>
      template_url_service_observation_{this};

  raw_ptr<ash::AppListController> app_list_controller_ = nullptr;

  std::unique_ptr<ash::AppListNotifier> app_list_notifier_;

  // Records the app list state for the session started by a new user. It
  // gets reset when:
  // (1) the active user changes, or
  // (2) the user signs out all accounts. `AppListClientImpl` is destructed in
  // this scenario.
  std::optional<StateForNewUser> state_for_new_user_;

  // Indicates when the session of a new user becomes active. If there is no new
  // users logged in, `new_user_session_activation_time_` is null.
  std::optional<base::Time> new_user_session_activation_time_;

  bool app_list_target_visibility_ = false;
  bool app_list_visible_ = false;

  // If present, indicates whether the user associated with the primary profile
  // is considered new. A user is considered new if the first app list sync in
  // the session was the first sync ever across all ChromeOS devices and
  // sessions for the given user. As such, this value is absent until the first
  // app list sync of the session is completed.
  std::optional<bool> is_primary_profile_new_user_;

  std::unique_ptr<app_list::AppListSurveyHandler> survey_handler_;

  base::ScopedObservation<user_manager::UserManager,
                          user_manager::UserManager::Observer>
      user_manager_observation_{this};

  base::WeakPtrFactory<AppListClientImpl> weak_ptr_factory_{this};
};

#endif  // CHROME_BROWSER_ASH_APP_LIST_APP_LIST_CLIENT_IMPL_H_