blob: 11b31be4cb3a8c9a021a09c130bbceef7f10c040 [file] [log] [blame]
Joshua Pawlicki7e25bd32024-01-11 15:43:191// Copyright 2023 The Chromium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/google/google_brand.h"
6
7#include <string>
8
9#include "base/apple/bundle_locations.h"
10#include "base/apple/foundation_util.h"
Adam Norberge183beb2025-04-15 19:58:5411#include "base/check.h"
Joshua Pawlicki7e25bd32024-01-11 15:43:1912#include "base/files/file_path.h"
13#include "base/files/file_util.h"
14#include "base/no_destructor.h"
15#include "base/strings/sys_string_conversions.h"
Adam Norberge183beb2025-04-15 19:58:5416#include "base/types/expected.h"
Joshua Pawlicki7e25bd32024-01-11 15:43:1917#include "chrome/common/channel_info.h"
Adam Norberge183beb2025-04-15 19:58:5418#include "chrome/updater/tag.h"
Joshua Pawlicki7e25bd32024-01-11 15:43:1919
20namespace google_brand {
21
22namespace {
23
24std::string ReadBrandFile(NSString* path) {
Avi Drissmancb1cbcec2024-03-04 21:50:5225 NSURL* path_url = [NSURL fileURLWithPath:path];
26 NSDictionary* brand_dictionary =
27 [NSDictionary dictionaryWithContentsOfURL:path_url error:nil];
28 return base::SysNSStringToUTF8(
29 base::apple::ObjCCast<NSString>(brand_dictionary[@"KSBrandID"]));
Joshua Pawlicki7e25bd32024-01-11 15:43:1930}
31
32std::string GetBrandInternal() {
33 // Non-side-by-side dev and beta do not have a brand code.
34 if (!chrome::IsSideBySideCapable()) {
35 return {};
36 }
37
38 // If there is a system brand file, use it.
39 NSFileManager* fm = NSFileManager.defaultManager;
40 NSString* system_brand_file =
41 [@"/Library/Google/Google Chrome Brand.plist" stringByStandardizingPath];
42 if ([fm fileExistsAtPath:system_brand_file]) {
43 return ReadBrandFile(system_brand_file);
44 }
45
46 // Otherwise, use the brand code from within the app, if present.
47 // If this mismatches a user brand code file, the updater will fix it on the
48 // next update.
Adam Norberge183beb2025-04-15 19:58:5449
50 // Extended attribute brand codes, if present, have priority over Info.plist
51 // brand codes.
52 base::expected<updater::tagging::TagArgs, updater::tagging::ErrorCode>
53 xattr_tag = updater::tagging::ReadTagFromApplicationInstanceXattr(
54 base::apple::OuterBundlePath());
55 if (xattr_tag.has_value()) {
56 return xattr_tag->brand_code;
57 }
Joshua Pawlicki7e25bd32024-01-11 15:43:1958 NSString* app_bundle_brand_id = base::apple::ObjCCast<NSString>(
59 base::apple::OuterBundle().infoDictionary[@"KSBrandID"]);
60 if (app_bundle_brand_id) {
61 return base::SysNSStringToUTF8(app_bundle_brand_id);
62 }
63
64 // Otherwise, use the user brand code file, if present.
65 NSString* user_brand_file =
66 [@"~/Library/Google/Google Chrome Brand.plist" stringByStandardizingPath];
67 if ([fm fileExistsAtPath:user_brand_file]) {
68 return ReadBrandFile(user_brand_file);
69 }
70
71 // Otherwise, there is no brand code.
72 return {};
73}
74
75} // namespace
76
77bool GetBrand(std::string* brand) {
78 if (g_brand_for_testing) {
79 *brand = g_brand_for_testing;
80 return true;
81 }
82
83 static base::NoDestructor<std::string> s_brand_code(GetBrandInternal());
84 *brand = *s_brand_code;
85 return true;
86}
87
88bool GetReactivationBrand(std::string* brand) {
89 brand->clear();
90 return true;
91}
92
93} // namespace google_brand