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
ash / birch / birch_coral_provider.h [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_BIRCH_BIRCH_CORAL_PROVIDER_H_
#define ASH_BIRCH_BIRCH_CORAL_PROVIDER_H_
#include "ash/ash_export.h"
#include "ash/birch/birch_data_provider.h"
#include "ash/public/cpp/session/session_observer.h"
#include "ash/public/cpp/tab_cluster/tab_cluster_ui_controller.h"
#include "ash/wm/coral/coral_controller.h"
#include "ash/wm/overview/overview_controller.h"
#include "ash/wm/overview/overview_observer.h"
#include "base/containers/flat_map.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_multi_source_observation.h"
#include "base/token.h"
#include "chromeos/ash/services/coral/public/mojom/coral_service.mojom.h"
#include "ui/aura/window_observer.h"
namespace ash {
class CoralItemRemover;
class Desk;
class ASH_EXPORT BirchCoralProvider : public BirchDataProvider,
public TabClusterUIController::Observer,
public coral::mojom::TitleObserver,
public SessionObserver,
public aura::WindowObserver,
public OverviewObserver {
public:
class Observer : public base::CheckedObserver {
public:
Observer();
Observer(const Observer&) = delete;
Observer& operator=(const Observer&) = delete;
~Observer() override;
virtual void OnCoralGroupRemoved(const base::Token& group_id);
virtual void OnCoralEntityRemoved(const base::Token& group_id,
std::string_view identifier);
virtual void OnCoralGroupTitleUpdated(const base::Token& group_id,
const std::string& title);
};
BirchCoralProvider();
BirchCoralProvider(const BirchCoralProvider&) = delete;
BirchCoralProvider& operator=(const BirchCoralProvider&) = delete;
~BirchCoralProvider() override;
const Desk* in_session_source_desk() const { return in_session_source_desk_; }
static BirchCoralProvider* Get();
// Gets a group reference with given group ID. This operation will not remove
// the group from the `response_`.
const coral::mojom::GroupPtr& GetGroupById(const base::Token& group_id) const;
// Extracts a group from the response with given group ID. This operation will
// remove the group from the `response_`.
coral::mojom::GroupPtr ExtractGroupById(const base::Token& group_id);
// Removes the group with `group_id` from the `response_` and adds all items
// in the group to the coral item remover blocklist.
void RemoveGroup(const base::Token& group_id);
// Removes an item with `identifier` from the group with `group_id`.
void RemoveItemFromGroup(const base::Token& group_id,
const std::string& identifier);
void OnPostLoginClusterRestored();
mojo::PendingRemote<coral::mojom::TitleObserver> BindRemote();
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
// BirchDataProvider:
void RequestBirchDataFetch() override;
// TabClusterUIController::Observer:
void OnTabItemAdded(TabClusterUIItem* tab_item) override;
void OnTabItemUpdated(TabClusterUIItem* tab_item) override;
void OnTabItemRemoved(TabClusterUIItem* tab_item) override;
// coral::mojom::TitleObserver:
void TitleUpdated(const base::Token& id, const std::string& title) override;
// SessionObserver:
void OnSessionStateChanged(session_manager::SessionState state) override;
// aura::WindowObserver:
void OnWindowDestroyed(aura::Window* window) override;
void OnWindowParentChanged(aura::Window* window,
aura::Window* parent) override;
// OverviewObserver:
void OnOverviewModeEnded() override;
const CoralRequest& GetCoralRequestForTest() const { return request_; }
CoralItemRemover* GetCoralItemRemoverForTest() {
return coral_item_remover_.get();
}
void OverrideCoralResponseForTest(std::unique_ptr<CoralResponse> response);
private:
// Whether we should handle post-login or in-session data.
bool HasValidPostLoginData() const;
// Called during session restore. Sends a grouping request with session
// restore data to the coral backend.
void HandlePostLoginDataRequest();
// Called during user session. Sends a grouping request with active tab
// and app metadata to the coral backend.
void HandleInSessionDataRequest();
// Checks whether we have fresh post-login data.
bool HasValidPostLoginResponse();
// Callback passed to the coral backend when performing post login clustering.
void HandlePostLoginCoralResponse(std::unique_ptr<CoralResponse> response);
// Callback passed to the coral backend when performing in-session custering.
void HandleInSessionCoralResponse(std::unique_ptr<CoralResponse> response);
// Handles responses from coral backend.
void HandleCoralResponse(std::unique_ptr<CoralResponse> response);
// Erases from the ContentItem list any items which have been removed by the
// user. The list is mutated in place.
void FilterCoralContentItems(std::vector<coral::mojom::EntityPtr>* items);
// Only cache embeddings for valid tabs/windows.
void MaybeCacheTabEmbedding(TabClusterUIItem* tab_item);
// Sends a request to the coral backend to cache the embedding for `tab_item`.
void CacheTabEmbedding(TabClusterUIItem* tab_item);
void HandleEmbeddingResult(bool success);
// Observes all the valid app and browser windows associated with `response_`.
void ObserveAllWindowsInResponse();
// Called when the `tab_item` is removed or moved from its source desk.
void OnTabRemovedFromSourceDesk(TabClusterUIItem* tab_item);
// Called when an `app_window` is removed or moved from its source desk.
void OnAppWindowRemovedFromSourceDesk(aura::Window* app_window);
// Removes the entity corresponding to the given `entity_identifier` from
// current in-session `response_`.
void RemoveEntity(std::string_view entity_identifier);
// The request sent to the coral backend.
CoralRequest request_;
// Timestamp for when post login coral response expires.
base::TimeTicks post_login_response_expiration_timestamp_;
// Response generated by the coral backend.
std::unique_ptr<CoralResponse> response_;
// Take fake response for test using.
std::unique_ptr<CoralResponse> fake_response_;
// Used to filter out coral items which have been removed by the user in
// the current session.
std::unique_ptr<CoralItemRemover> coral_item_remover_;
mojo::Receiver<coral::mojom::TitleObserver> receiver_{this};
ScopedSessionObserver session_observer_{this};
// Observe the windows related to the in-session group entities.
base::ScopedMultiSourceObservation<aura::Window, aura::WindowObserver>
windows_observation_{this};
base::ScopedObservation<OverviewController, OverviewObserver>
overview_observation_{this};
// The source desk of the in-session groups. It will be set to the current
// active desk once in-session groups are generated. It will be reset when the
// in-session groups are extracted, e.g. launched or hidden by user, or all of
// the group entities are removed, e.g. the source desk is closed or merged.
raw_ptr<const Desk> in_session_source_desk_ = nullptr;
base::ObserverList<Observer> observers_;
base::WeakPtrFactory<BirchCoralProvider> weak_ptr_factory_{this};
};
} // namespace ash
#endif // ASH_BIRCH_BIRCH_CORAL_PROVIDER_H_