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
|
// 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 COMPONENTS_COLLABORATION_INTERNAL_MESSAGING_MESSAGING_BACKEND_SERVICE_IMPL_H_
#define COMPONENTS_COLLABORATION_INTERNAL_MESSAGING_MESSAGING_BACKEND_SERVICE_IMPL_H_
#include <memory>
#include <unordered_map>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "base/scoped_observation.h"
#include "components/collaboration/internal/messaging/configuration.h"
#include "components/collaboration/internal/messaging/data_sharing_change_notifier.h"
#include "components/collaboration/internal/messaging/instant_message_processor.h"
#include "components/collaboration/internal/messaging/storage/messaging_backend_store.h"
#include "components/collaboration/internal/messaging/tab_group_change_notifier.h"
#include "components/collaboration/public/messaging/message.h"
#include "components/collaboration/public/messaging/messaging_backend_service.h"
#include "components/saved_tab_groups/public/tab_group_sync_service.h"
#include "components/signin/public/identity_manager/identity_manager.h"
namespace collaboration_pb {
class Message;
} // namespace collaboration_pb
namespace data_sharing {
class DataSharingService;
} // namespace data_sharing
namespace tab_groups {
class TabGroupSyncService;
} // namespace tab_groups
namespace collaboration::messaging {
class DataSharingChangeNotifier;
class MessagingBackendStore;
// The implementation of the MessagingBackendService.
class MessagingBackendServiceImpl : public MessagingBackendService,
public TabGroupChangeNotifier::Observer,
public DataSharingChangeNotifier::Observer {
public:
MessagingBackendServiceImpl(
const MessagingBackendConfiguration& configuration,
std::unique_ptr<TabGroupChangeNotifier> tab_group_change_notifier,
std::unique_ptr<DataSharingChangeNotifier> data_sharing_change_notifier,
std::unique_ptr<MessagingBackendStore> messaging_backend_store,
std::unique_ptr<InstantMessageProcessor> instant_message_processor,
tab_groups::TabGroupSyncService* tab_group_sync_service,
data_sharing::DataSharingService* data_sharing_service,
signin::IdentityManager* identity_manager);
~MessagingBackendServiceImpl() override;
// MessagingBackendService implementation.
void SetInstantMessageDelegate(
InstantMessageDelegate* instant_message_delegate) override;
void AddPersistentMessageObserver(
PersistentMessageObserver* observer) override;
void RemovePersistentMessageObserver(
PersistentMessageObserver* observer) override;
bool IsInitialized() override;
std::vector<PersistentMessage> GetMessagesForTab(
tab_groups::EitherTabID tab_id,
std::optional<PersistentNotificationType> type) override;
std::vector<PersistentMessage> GetMessagesForGroup(
tab_groups::EitherGroupID group_id,
std::optional<PersistentNotificationType> type) override;
std::vector<PersistentMessage> GetMessages(
std::optional<PersistentNotificationType> type) override;
std::vector<ActivityLogItem> GetActivityLog(
const ActivityLogQueryParams& params) override;
void ClearDirtyTabMessagesForGroup(
const data_sharing::GroupId& collaboration_group_id) override;
void ClearPersistentMessage(
const base::Uuid& message_id,
std::optional<PersistentNotificationType> type) override;
void RemoveMessages(const std::vector<base::Uuid>& message_ids) override;
void AddActivityLogForTesting(
data_sharing::GroupId collaboration_id,
const std::vector<ActivityLogItem>& activity_log) override;
// TabGroupChangeNotifier::Observer.
void OnTabGroupChangeNotifierInitialized() override;
void OnSyncDisabled() override;
void OnTabGroupAdded(const tab_groups::SavedTabGroup& added_group,
tab_groups::TriggerSource source) override;
void OnTabGroupRemoved(tab_groups::SavedTabGroup removed_group,
tab_groups::TriggerSource source) override;
void OnTabGroupNameUpdated(const tab_groups::SavedTabGroup& updated_group,
tab_groups::TriggerSource source) override;
void OnTabGroupColorUpdated(const tab_groups::SavedTabGroup& updated_group,
tab_groups::TriggerSource source) override;
void OnTabAdded(const tab_groups::SavedTabGroupTab& added_tab,
tab_groups::TriggerSource source) override;
void OnTabRemoved(tab_groups::SavedTabGroupTab removed_tab,
tab_groups::TriggerSource source,
bool is_selected) override;
void OnTabUpdated(const tab_groups::SavedTabGroupTab& before,
const tab_groups::SavedTabGroupTab& after,
tab_groups::TriggerSource source,
bool is_selected) override;
void OnTabSelectionChanged(const tab_groups::LocalTabID& tab_id,
bool is_selected) override;
void OnTabLastSeenTimeChanged(const base::Uuid& tab_id,
tab_groups::TriggerSource source) override;
void OnTabGroupOpened(const tab_groups::SavedTabGroup& tab_group) override;
void OnTabGroupClosed(const tab_groups::SavedTabGroup& tab_group) override;
// DataSharingChangeNotifier::Observer.
void OnDataSharingChangeNotifierInitialized() override;
void OnGroupMemberAdded(const data_sharing::GroupData& group_data,
const GaiaId& member_gaia_id,
const base::Time& event_time) override;
void OnGroupMemberRemoved(const data_sharing::GroupData& group_data,
const GaiaId& member_gaia_id,
const base::Time& event_time) override;
static std::u16string GetTruncatedTabTitleForTesting(
const std::u16string& original_title);
private:
void OnStoreInitialized(bool success);
void ClearDirtyTabMessagesForGroup(
const data_sharing::GroupId& collaboration_group_id,
const std::optional<tab_groups::SavedTabGroup>& tab_group);
// Uses all available sources to try to retrieve a name that describes the
// given user.
std::optional<std::string> GetDisplayNameForUserInGroup(
const data_sharing::GroupId& group_id,
const GaiaId& gaia_id);
// Converts a stored message to an ActivityLogItem for display. Some events
// should not be part of the activity log and for those std::nullopt is
// return.
std::optional<ActivityLogItem> ConvertMessageToActivityLogItem(
const collaboration_pb::Message& message,
bool is_tab_activity);
// Looks for the related collaboration GroupId for the given tab, using the
// information available in the tab group sync service.
std::optional<data_sharing::GroupId> GetCollaborationGroupIdForTab(
const tab_groups::SavedTabGroupTab& tab);
// Uses the provided data to create TabGroupMessageMetadata.
TabGroupMessageMetadata CreateTabGroupMessageMetadataFromCollaborationId(
const collaboration_pb::Message& message,
std::optional<tab_groups::SavedTabGroup> tab_group,
std::optional<data_sharing::GroupId> collaboration_group_id);
// Creates a TabGroupMessageMetadata based on the sources given as input.
TabGroupMessageMetadata CreateTabGroupMessageMetadataFromMessageOrTabGroup(
const collaboration_pb::Message& message,
const std::optional<tab_groups::SavedTabGroup>& tab_group);
// Tries to retrieve the tab group from CollaborationId.
std::optional<tab_groups::SavedTabGroup> GetTabGroupFromCollaborationId(
const std::string& collaboration_id);
// Uses the available data to look up a GroupMember.
std::optional<data_sharing::GroupMember> GetGroupMemberFromGaiaId(
const data_sharing::GroupId& collaboration_group_id,
std::optional<GaiaId> gaia_id);
// Retrieves the relevant tab group from the TabGroupSyncService and looks up
// its collaboration group id.
std::optional<data_sharing::GroupId> GetCollaborationGroupId(
tab_groups::EitherGroupID group_id);
// Looks up the tab from tab group sync service.
std::optional<tab_groups::SavedTabGroupTab> GetTabFromTabId(
tab_groups::EitherTabID tab_id);
// Convert all the provided stored Messages to PersistentMessages.
std::vector<PersistentMessage> ConvertMessagesToPersistentMessages(
const std::vector<collaboration_pb::Message>& messages,
DirtyType lookup_dirty_type,
const std::optional<PersistentNotificationType>& type);
// Convert a single stored Message to PersistentMessages. Each stored message
// may result in multiple PersistentMessages, e.g. both CHIP and DIRTY_TAB.
std::vector<PersistentMessage> ConvertMessageToPersistentMessages(
const collaboration_pb::Message& message,
DirtyType lookup_dirty_type,
const std::optional<PersistentNotificationType>& type,
bool allow_dirty_tab_group_message);
// Creates a PersistentMessage based on the provided information.
PersistentMessage CreatePersistentMessage(
const collaboration_pb::Message& message,
const std::optional<tab_groups::SavedTabGroup>& tab_group,
const std::optional<tab_groups::SavedTabGroupTab>& tab,
const std::optional<PersistentNotificationType>& type);
InstantMessage CreateInstantMessage(
const collaboration_pb::Message& message,
const std::optional<tab_groups::SavedTabGroup>& tab_group,
const std::optional<tab_groups::SavedTabGroupTab>& tab);
// Creates individual messages based on `base_message` per type, and notifies
// oservers to display the messages.
void NotifyDisplayPersistentMessagesForTypes(
const PersistentMessage& base_message,
const std::vector<PersistentNotificationType>& types);
// Creates individual messages based on `base_message` per type, and notifies
// oservers to hide the messages.
void NotifyHidePersistentMessagesForTypes(
const PersistentMessage& base_message,
const std::vector<PersistentNotificationType>& types);
// Notifies observers to display or hide the dirty dot for a tab group.
void DisplayOrHideTabGroupDirtyDotForTabGroup(
const data_sharing::GroupId& collaboration_group_id,
base::Uuid shared_tab_group_id);
// Creates MessageAttribution based on all the provided information.
MessageAttribution CreateMessageAttributionForTabUpdates(
const collaboration_pb::Message& message,
const std::optional<tab_groups::SavedTabGroup>& tab_group,
const std::optional<tab_groups::SavedTabGroupTab>& tab);
// Notifies the InstantMessageDelegate to display the message for all the
// provided levels.
void DisplayInstantMessage(
const base::Uuid& db_message_uuid,
const InstantMessage& base_message,
const std::vector<InstantNotificationLevel>& levels);
// Clears the dirty bit for the given DB message ID if `success` is true.
void ClearMessageDirtyBit(base::Uuid db_message_id, bool success);
// Creates a PersistentMessage based on tab group and tab for when we do not
// have a db Message available.
PersistentMessage CreatePersistentMessageFromTabGroupAndTab(
const data_sharing::GroupId& collaboration_group_id,
const tab_groups::SavedTabGroupTab tab,
CollaborationEvent collaboration_event);
// A configuration for how the MessagingBackendService should behave.
MessagingBackendConfiguration configuration_;
// Provides functionality to go from observing the TabGroupSyncService to
// a delta based observer API.
std::unique_ptr<TabGroupChangeNotifier> tab_group_change_notifier_;
// Provides functionality to go from observing the DataSharingService to a
// smaller API surface and delta observation.
std::unique_ptr<DataSharingChangeNotifier> data_sharing_change_notifier_;
// Store for reading and writing messages:
std::unique_ptr<MessagingBackendStore> store_;
// Scoped observers for our delta change notifiers.
base::ScopedObservation<TabGroupChangeNotifier,
TabGroupChangeNotifier::Observer>
tab_group_change_notifier_observer_{this};
base::ScopedObservation<DataSharingChangeNotifier,
DataSharingChangeNotifier::Observer>
data_sharing_change_notifier_observer_{this};
// Whether initialization has completed.
bool initialized_ = false;
// A callback invoked when we are ready to flush all the events from the
// data sharing service.
DataSharingChangeNotifier::FlushCallback data_sharing_flush_callback_;
// Queues and processes instant messages. Invokes the delegate to ask UI to
// show the instant message.
std::unique_ptr<InstantMessageProcessor> instant_message_processor_;
// Service providing information about tabs and tab groups.
raw_ptr<tab_groups::TabGroupSyncService> tab_group_sync_service_;
// Service providing information about people groups.
raw_ptr<data_sharing::DataSharingService> data_sharing_service_;
// Service providing information about sign in.
raw_ptr<signin::IdentityManager> identity_manager_;
// The list of observers for any changes to persistent messages.
base::ObserverList<PersistentMessageObserver> persistent_message_observers_;
// Test-only mock activity log, keyed by collaboration id.
std::unordered_map<data_sharing::GroupId, const std::vector<ActivityLogItem>&>
activity_log_for_testing_;
base::WeakPtrFactory<MessagingBackendServiceImpl> weak_ptr_factory_{this};
};
} // namespace collaboration::messaging
#endif // COMPONENTS_COLLABORATION_INTERNAL_MESSAGING_MESSAGING_BACKEND_SERVICE_IMPL_H_
|