File: birch_recent_tabs_provider.cc

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 (126 lines) | stat: -rw-r--r-- 4,786 bytes parent folder | download | duplicates (6)
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
// 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.

#include "chrome/browser/ui/ash/birch/birch_recent_tabs_provider.h"

#include "ash/birch/birch_item.h"
#include "ash/birch/birch_model.h"
#include "ash/constants/ash_pref_names.h"
#include "ash/shell.h"
#include "base/callback_list.h"
#include "base/functional/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sync/session_sync_service_factory.h"
#include "chrome/browser/sync/sync_service_factory.h"
#include "components/prefs/pref_service.h"
#include "components/sync/service/sync_service.h"
#include "components/sync/service/sync_user_settings.h"
#include "components/sync_sessions/open_tabs_ui_delegate.h"
#include "components/sync_sessions/session_sync_service.h"

namespace ash {

namespace {

BirchTabItem::DeviceFormFactor GetTabItemFormFactor(
    syncer::DeviceInfo::FormFactor form_factor) {
  // Convert to a BirchTabItem specific form factor to ensure any changes
  // to DeviceInfo::FormFactor won't break the BirchTabItem's form factor.
  switch (form_factor) {
    case syncer::DeviceInfo::FormFactor::kUnknown:
    case syncer::DeviceInfo::FormFactor::kAutomotive:
    case syncer::DeviceInfo::FormFactor::kWearable:
    case syncer::DeviceInfo::FormFactor::kTv:
    case syncer::DeviceInfo::FormFactor::kDesktop:
      return BirchTabItem::DeviceFormFactor::kDesktop;
    case syncer::DeviceInfo::FormFactor::kPhone:
      return BirchTabItem::DeviceFormFactor::kPhone;
    case syncer::DeviceInfo::FormFactor::kTablet:
      return BirchTabItem::DeviceFormFactor::kTablet;
  }
}

}  // namespace

BirchRecentTabsProvider::BirchRecentTabsProvider(Profile* profile)
    : profile_(profile) {}

BirchRecentTabsProvider::~BirchRecentTabsProvider() = default;

void BirchRecentTabsProvider::RequestBirchDataFetch() {
  syncer::SyncService* sync_service =
      SyncServiceFactory::GetForProfile(profile_);
  // `sync_service_` can be null in some tests, so check that here.
  bool tab_sync_enabled =
      sync_service && sync_service->GetUserSettings()->GetSelectedTypes().Has(
                          syncer::UserSelectableType::kTabs);
  if (!tab_sync_enabled) {
    // Complete the request with an empty set of tabs when tab sync is
    // disabled
    Shell::Get()->birch_model()->SetRecentTabItems({});
    return;
  }

  const auto* const pref_service = profile_->GetPrefs();
  if (!pref_service ||
      !base::Contains(pref_service->GetList(
                          prefs::kContextualGoogleIntegrationsConfiguration),
                      prefs::kChromeSyncIntegrationName)) {
    // ChromeSync integration is disabled by policy.
    Shell::Get()->birch_model()->SetRecentTabItems({});
    return;
  }

  auto* session_sync_service =
      SessionSyncServiceFactory::GetInstance()->GetForProfile(profile_);
  sync_sessions::OpenTabsUIDelegate* open_tabs =
      session_sync_service->GetOpenTabsUIDelegate();

  if (!open_tabs) {
    // When no open tabs delegate is available, return early and wait for a
    // foreign session change to occur before attempting to fetch tab items.
    foreign_sessions_subscription_ =
        session_sync_service->SubscribeToForeignSessionsChanged(
            base::BindRepeating(
                &BirchRecentTabsProvider::OnForeignSessionsChanged,
                weak_factory_.GetWeakPtr()));
    return;
  }

  std::vector<raw_ptr<const sync_sessions::SyncedSession, VectorExperimental>>
      remote_sessions;
  if (!open_tabs->GetAllForeignSessions(&remote_sessions)) {
    Shell::Get()->birch_model()->SetRecentTabItems({});
    return;
  }

  std::vector<BirchTabItem> items;

  for (auto& session : remote_sessions) {
    const std::string& session_tag = session->GetSessionTag();
    std::vector<const sessions::SessionTab*> tabs_in_session;
    if (open_tabs->GetForeignSessionTabs(session_tag, &tabs_in_session) &&
        !tabs_in_session.empty()) {
      for (auto* tab : tabs_in_session) {
        const sessions::SerializedNavigationEntry& current_navigation =
            tab->navigations.at(tab->normalized_navigation_index());
        items.emplace_back(
            current_navigation.title(), current_navigation.virtual_url(),
            current_navigation.timestamp(), current_navigation.favicon_url(),
            session->GetSessionName(),
            GetTabItemFormFactor(session->GetDeviceFormFactor()));
      }
    }
  }

  Shell::Get()->birch_model()->SetRecentTabItems(std::move(items));
}

void BirchRecentTabsProvider::OnForeignSessionsChanged() {
  foreign_sessions_subscription_ = base::CallbackListSubscription();
  RequestBirchDataFetch();
}

}  // namespace ash