File: browsing_data_counter_utils.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 (308 lines) | stat: -rw-r--r-- 12,045 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
295
296
297
298
299
300
301
302
303
304
305
306
307
308
// Copyright 2015 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/browsing_data/counters/browsing_data_counter_utils.h"

#include <string>
#include <vector>

#include "base/feature_list.h"
#include "base/i18n/number_formatting.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/browser/browsing_data/counters/cache_counter.h"
#include "chrome/browser/browsing_data/counters/signin_data_counter.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/account_consistency_mode_manager.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/generated_resources.h"
#include "components/browsing_data/core/features.h"
#include "components/browsing_data/core/pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/signin/public/base/consent_level.h"
#include "components/signin/public/base/signin_switches.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/signin/public/identity_manager/identity_utils.h"
#include "components/strings/grit/components_strings.h"
#include "components/sync/base/features.h"
#include "google_apis/gaia/core_account_id.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/text/bytes_formatting.h"

#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS)
#include "ui/strings/grit/ui_strings.h"
#endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS)

#if BUILDFLAG(IS_ANDROID)
#include "chrome/browser/browsing_data/counters/tabs_counter.h"
#endif

#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "base/numerics/safe_conversions.h"
#include "base/strings/string_util.h"
#include "chrome/browser/browsing_data/counters/hosted_apps_counter.h"
#endif

#if BUILDFLAG(ENABLE_DICE_SUPPORT)
#include "chrome/browser/sync/sync_ui_util.h"
#endif

namespace browsing_data_counter_utils {

using BrowsingDataCounter = browsing_data::BrowsingDataCounter;
using SigninDataCounter = browsing_data::SigninDataCounter;
using ResultInt = browsing_data::BrowsingDataCounter::ResultInt;

namespace {
// A helper function to display the size of cache in units of MB or higher.
// We need this, as 1 MB is the lowest nonzero cache size displayed by the
// counter.
std::u16string FormatBytesMBOrHigher(ResultInt bytes) {
  if (ui::GetByteDisplayUnits(bytes) >= ui::DataUnits::DATA_UNITS_MEBIBYTE)
    return ui::FormatBytes(bytes);

  return ui::FormatBytesWithUnits(
      bytes, ui::DataUnits::DATA_UNITS_MEBIBYTE, true);
}
}  // namespace

bool ShouldShowCookieException(Profile* profile) {
  if (AccountConsistencyModeManager::IsMirrorEnabledForProfile(profile)) {
    signin::ConsentLevel consent_level =
        base::FeatureList::IsEnabled(syncer::kReplaceSyncPromosWithSignInPromos)
            ? signin::ConsentLevel::kSignin
            : signin::ConsentLevel::kSync;
    auto* identity_manager = IdentityManagerFactory::GetForProfile(profile);
    return identity_manager->HasPrimaryAccount(consent_level);
  }
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
  if (AccountConsistencyModeManager::IsDiceEnabledForProfile(profile)) {
    return GetSyncStatusMessageType(profile) == SyncStatusMessageType::kSynced;
  }
#endif
  return false;
}

std::u16string GetChromeCounterTextFromResult(
    const BrowsingDataCounter::Result* result,
    Profile* profile) {
  std::string pref_name = result->source()->GetPrefName();

  if (!result->Finished()) {
    // The counter is still counting.
    return l10n_util::GetStringUTF16(IDS_CLEAR_BROWSING_DATA_CALCULATING);
  }

  if (pref_name == browsing_data::prefs::kDeleteCache ||
      pref_name == browsing_data::prefs::kDeleteCacheBasic) {
    // Cache counter.
    const auto* cache_result =
        static_cast<const CacheCounter::CacheResult*>(result);
    int64_t cache_size_bytes = cache_result->cache_size();
    bool is_upper_limit = cache_result->is_upper_limit();
    bool is_basic_tab = pref_name == browsing_data::prefs::kDeleteCacheBasic;

    // Three cases: Nonzero result for the entire cache, nonzero result for
    // a subset of cache (i.e. a finite time interval), and almost zero (< 1MB).
    static const int kBytesInAMegabyte = 1024 * 1024;
    if (cache_size_bytes >= kBytesInAMegabyte) {
      std::u16string formatted_size = FormatBytesMBOrHigher(cache_size_bytes);
      if (!is_upper_limit) {
#if BUILDFLAG(IS_ANDROID)
        if (!is_basic_tab) {
          return l10n_util::GetStringFUTF16(
              IDS_ANDROID_DEL_CACHE_COUNTER_ADVANCED, formatted_size);
        }
#endif
        return is_basic_tab ? l10n_util::GetStringFUTF16(
                                  IDS_DEL_CACHE_COUNTER_BASIC, formatted_size)
                            : formatted_size;
      }

#if BUILDFLAG(IS_ANDROID)
      if (!is_basic_tab) {
        return l10n_util::GetStringFUTF16(
            IDS_ANDROID_DEL_CACHE_COUNTER_ADVANCED_UPPER_ESTIMATE,
            formatted_size);
      }
#endif
      return l10n_util::GetStringFUTF16(
          is_basic_tab ? IDS_DEL_CACHE_COUNTER_UPPER_ESTIMATE_BASIC
                       : IDS_DEL_CACHE_COUNTER_UPPER_ESTIMATE,
          formatted_size);
    }

#if BUILDFLAG(IS_ANDROID)
    if (!is_basic_tab) {
      return l10n_util::GetStringUTF16(
          IDS_ANDROID_DEL_CACHE_COUNTER_ADVANCED_ALMOST_EMPTY);
    }
#endif
    return l10n_util::GetStringUTF16(
        is_basic_tab ? IDS_DEL_CACHE_COUNTER_ALMOST_EMPTY_BASIC
                     : IDS_DEL_CACHE_COUNTER_ALMOST_EMPTY);
  }
  if (pref_name == browsing_data::prefs::kDeleteCookiesBasic) {
    // The basic tab doesn't show cookie counter results.
    NOTREACHED();
  }
  if (pref_name == browsing_data::prefs::kDeleteCookies) {
    // Site data counter.
    ResultInt origins =
        static_cast<const BrowsingDataCounter::FinishedResult*>(result)
            ->Value();

#if BUILDFLAG(IS_ANDROID)
    return l10n_util::GetPluralStringFUTF16(
        IDS_ANDROID_DEL_COOKIES_COUNTER_ADVANCED, origins);
#else
    // Determines whether or not to show the count with exception message.
    auto* identity_manager = IdentityManagerFactory::GetForProfile(profile);
    // Notes:
    // * `ShouldShowCookieException()` returns true if the exception footer is
    //   shown. This is a sufficient condition to use the exception string,
    // * `AreGoogleCookiesRebuiltAfterClearingWhenSignedIn()` may return false
    //   when the user is signed out and always return false if syncing. The
    //   counter should only be shown if the user is signed in, non-syncing, and
    //   has no error.
    bool is_signed_in = false;
    if (identity_manager) {
      CoreAccountId account_id =
          identity_manager->GetPrimaryAccountId(signin::ConsentLevel::kSignin);
      if (!account_id.empty() &&
          !identity_manager->HasAccountWithRefreshTokenInPersistentErrorState(
              account_id)) {
        is_signed_in = true;
      }
    }

#if !BUILDFLAG(IS_CHROMEOS)
    if (base::FeatureList::IsEnabled(
            browsing_data::features::kDbdRevampDesktop)) {
      std::u16string cookies_counter_text = l10n_util::GetPluralStringFUTF16(
          IDS_DEL_COOKIES_COUNTER_ADVANCED, origins);

      if (origins > 0 &&
          (ShouldShowCookieException(profile) ||
           (is_signed_in &&
            signin::AreGoogleCookiesRebuiltAfterClearingWhenSignedIn(
                *identity_manager, *profile->GetPrefs())))) {
        cookies_counter_text +=
            (l10n_util::GetStringUTF16(IDS_SENTENCE_END) + u" " +
             l10n_util::GetStringUTF16(IDS_DEL_GOOGLE_COOKIES_SIGNOUT_LINK));
      }
      return cookies_counter_text;
    }
#endif  // !BUILDFLAG(IS_CHROMEOS)

    int del_cookie_counter_msg_id =
        ShouldShowCookieException(profile) ||
                (is_signed_in &&
                 signin::AreGoogleCookiesRebuiltAfterClearingWhenSignedIn(
                     *identity_manager, *profile->GetPrefs()))
            ? IDS_DEL_COOKIES_COUNTER_ADVANCED_WITH_SIGNED_IN_EXCEPTION
            : IDS_DEL_COOKIES_COUNTER_ADVANCED;

    return l10n_util::GetPluralStringFUTF16(del_cookie_counter_msg_id, origins);
#endif
  }

#if BUILDFLAG(ENABLE_EXTENSIONS)
  if (pref_name == browsing_data::prefs::kDeleteHostedAppsData) {
    // Hosted apps counter.
    const HostedAppsCounter::HostedAppsResult* hosted_apps_result =
        static_cast<const HostedAppsCounter::HostedAppsResult*>(result);
    int hosted_apps_count = hosted_apps_result->Value();

    DCHECK_GE(
        hosted_apps_result->Value(),
        base::checked_cast<ResultInt>(hosted_apps_result->examples().size()));

    std::vector<std::u16string> replacements;
    if (hosted_apps_count > 0) {
      replacements.push_back(                                     // App1,
          base::UTF8ToUTF16(hosted_apps_result->examples()[0]));
    }
    if (hosted_apps_count > 1) {
      replacements.push_back(
          base::UTF8ToUTF16(hosted_apps_result->examples()[1]));  // App2,
    }
    if (hosted_apps_count > 2) {
      replacements.push_back(l10n_util::GetPluralStringFUTF16(  // and X-2 more.
          IDS_DEL_HOSTED_APPS_COUNTER_AND_X_MORE,
          hosted_apps_count - 2));
    }

    // The output string has both the number placeholder (#) and substitution
    // placeholders ($1, $2, $3). First fetch the correct plural string first,
    // then substitute the $ placeholders.
    return base::ReplaceStringPlaceholders(
        l10n_util::GetPluralStringFUTF16(
            IDS_DEL_HOSTED_APPS_COUNTER, hosted_apps_count),
        replacements,
        nullptr);
  }
#endif

  if (pref_name == browsing_data::prefs::kDeletePasswords) {
    auto* signin_result =
        static_cast<const SigninDataCounter::SigninDataResult*>(result);

    ResultInt profile_passwords = signin_result->Value();
    ResultInt account_passwords = signin_result->account_passwords();
    ResultInt signin_data_count = signin_result->WebAuthnCredentialsValue();

    std::vector<std::u16string> counts;
    // TODO(crbug.com/40132590): If there are profile passwords, account
    // passwords and other sign-in data, these are combined as
    // "<1>; <2>; <3>" by recursively applying a "<1>; <2>" message.
    // Maybe we should do something more pretty?
    if (profile_passwords || account_passwords) {
      counts.emplace_back(browsing_data::GetCounterTextFromResult(result));
    }
    if (signin_data_count) {
      counts.emplace_back(l10n_util::GetPluralStringFUTF16(
          IDS_DEL_SIGNIN_DATA_COUNTER, signin_data_count));
    }
    switch (counts.size()) {
      case 0:
        return l10n_util::GetStringUTF16(
            IDS_DEL_PASSWORDS_AND_SIGNIN_DATA_COUNTER_NONE);
      case 1:
        return counts[0];
      case 2:
        return l10n_util::GetStringFUTF16(
            IDS_DEL_PASSWORDS_AND_SIGNIN_DATA_COUNTER_COMBINATION, counts[0],
            counts[1]);
      default:
        NOTREACHED();
    }
  }

#if BUILDFLAG(IS_ANDROID)
  if (pref_name == browsing_data::prefs::kCloseTabs) {
    const TabsCounter::TabsResult* tabs_result =
        static_cast<const TabsCounter::TabsResult*>(result);
    BrowsingDataCounter::ResultInt tab_count = tabs_result->Value();
    BrowsingDataCounter::ResultInt window_count = tabs_result->window_count();

    if (window_count > 1) {
      std::u16string tabs_counter_string =
          l10n_util::GetPluralStringFUTF16(IDS_TABS_COUNT, tab_count);
      std::u16string windows_counter_string =
          l10n_util::GetPluralStringFUTF16(IDS_WINDOWS_COUNT, window_count);
      return l10n_util::GetStringFUTF16(IDS_DEL_TABS_MULTIWINDOW_COUNTER,
                                        tabs_counter_string,
                                        windows_counter_string);
    } else {
      return l10n_util::GetPluralStringFUTF16(IDS_DEL_TABS_COUNTER, tab_count);
    }
  }
#endif

  return browsing_data::GetCounterTextFromResult(result);
}

}  // namespace browsing_data_counter_utils