1 // Copyright 2012 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 #ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_BASE_MAC_MAC_UTIL_H_
6 #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_BASE_MAC_MAC_UTIL_H_
7
8 #include <AvailabilityMacros.h>
9 #import <CoreGraphics/CoreGraphics.h>
10
11 #include "base/allocator/partition_allocator/partition_alloc_base/component_export.h"
12
13 namespace partition_alloc::internal::base::mac {
14
15 namespace internal {
16
17 // Returns the system's macOS major and minor version numbers combined into an
18 // integer value. For example, for macOS Sierra this returns 1012, and for macOS
19 // Big Sur it returns 1100. Note that the accuracy returned by this function is
20 // as granular as the major version number of Darwin.
21 PA_COMPONENT_EXPORT(PARTITION_ALLOC) int MacOSVersion();
22
23 } // namespace internal
24
25 // Run-time OS version checks. Prefer @available in Objective-C files. If that
26 // is not possible, use these functions instead of
27 // base::SysInfo::OperatingSystemVersionNumbers. Prefer the "AtLeast" and
28 // "AtMost" variants to those that check for a specific version, unless you know
29 // for sure that you need to check for a specific version.
30
31 #define PA_DEFINE_OLD_IS_OS_FUNCS_CR_MIN_REQUIRED(V, DEPLOYMENT_TARGET_TEST) \
32 inline bool IsOS10_##V() { \
33 DEPLOYMENT_TARGET_TEST(>, V, false) \
34 return internal::MacOSVersion() == 1000 + V; \
35 } \
36 inline bool IsAtMostOS10_##V() { \
37 DEPLOYMENT_TARGET_TEST(>, V, false) \
38 return internal::MacOSVersion() <= 1000 + V; \
39 }
40
41 #define PA_DEFINE_OLD_IS_OS_FUNCS(V, DEPLOYMENT_TARGET_TEST) \
42 PA_DEFINE_OLD_IS_OS_FUNCS_CR_MIN_REQUIRED(V, DEPLOYMENT_TARGET_TEST) \
43 inline bool IsAtLeastOS10_##V() { \
44 DEPLOYMENT_TARGET_TEST(>=, V, true) \
45 return internal::MacOSVersion() >= 1000 + V; \
46 }
47
48 #define PA_DEFINE_IS_OS_FUNCS_CR_MIN_REQUIRED(V, DEPLOYMENT_TARGET_TEST) \
49 inline bool IsOS##V() { \
50 DEPLOYMENT_TARGET_TEST(>, V, false) \
51 return internal::MacOSVersion() == V * 100; \
52 } \
53 inline bool IsAtMostOS##V() { \
54 DEPLOYMENT_TARGET_TEST(>, V, false) \
55 return internal::MacOSVersion() <= V * 100; \
56 }
57
58 #define PA_DEFINE_IS_OS_FUNCS(V, DEPLOYMENT_TARGET_TEST) \
59 PA_DEFINE_IS_OS_FUNCS_CR_MIN_REQUIRED(V, DEPLOYMENT_TARGET_TEST) \
60 inline bool IsAtLeastOS##V() { \
61 DEPLOYMENT_TARGET_TEST(>=, V, true) \
62 return internal::MacOSVersion() >= V * 100; \
63 }
64
65 #define PA_OLD_TEST_DEPLOYMENT_TARGET(OP, V, RET) \
66 if (MAC_OS_X_VERSION_MIN_REQUIRED OP MAC_OS_X_VERSION_10_##V) \
67 return RET;
68 #define PA_TEST_DEPLOYMENT_TARGET(OP, V, RET) \
69 if (MAC_OS_X_VERSION_MIN_REQUIRED OP MAC_OS_VERSION_##V##_0) \
70 return RET;
71 #define PA_IGNORE_DEPLOYMENT_TARGET(OP, V, RET)
72
73 // Notes:
74 // - When bumping the minimum version of the macOS required by Chromium, remove
75 // lines from below corresponding to versions of the macOS no longer
76 // supported. Ensure that the minimum supported version uses the
77 // PA_DEFINE_OLD_IS_OS_FUNCS_CR_MIN_REQUIRED macro. When macOS 11.0 is the
78 // minimum required version, remove all the OLD versions of the macros.
79 // - When bumping the minimum version of the macOS SDK required to build
80 // Chromium, remove the #ifdef that switches between
81 // PA_TEST_DEPLOYMENT_TARGET and PA_IGNORE_DEPLOYMENT_TARGET.
82
83 // Versions of macOS supported at runtime but whose SDK is not supported for
84 // building.
85 PA_DEFINE_OLD_IS_OS_FUNCS_CR_MIN_REQUIRED(13, PA_OLD_TEST_DEPLOYMENT_TARGET)
86 PA_DEFINE_OLD_IS_OS_FUNCS(14, PA_OLD_TEST_DEPLOYMENT_TARGET)
87 PA_DEFINE_OLD_IS_OS_FUNCS(15, PA_OLD_TEST_DEPLOYMENT_TARGET)
88 PA_DEFINE_IS_OS_FUNCS(11, PA_TEST_DEPLOYMENT_TARGET)
89
90 // Versions of macOS supported at runtime and whose SDK is supported for
91 // building.
92 #ifdef MAC_OS_VERSION_12_0
93 PA_DEFINE_IS_OS_FUNCS(12, PA_TEST_DEPLOYMENT_TARGET)
94 #else
95 PA_DEFINE_IS_OS_FUNCS(12, PA_IGNORE_DEPLOYMENT_TARGET)
96 #endif
97
98 #ifdef MAC_OS_VERSION_13_0
99 PA_DEFINE_IS_OS_FUNCS(13, PA_TEST_DEPLOYMENT_TARGET)
100 #else
101 PA_DEFINE_IS_OS_FUNCS(13, PA_IGNORE_DEPLOYMENT_TARGET)
102 #endif
103
104 #undef PA_DEFINE_OLD_IS_OS_FUNCS_CR_MIN_REQUIRED
105 #undef PA_DEFINE_OLD_IS_OS_FUNCS
106 #undef PA_DEFINE_IS_OS_FUNCS_CR_MIN_REQUIRED
107 #undef PA_DEFINE_IS_OS_FUNCS
108 #undef PA_OLD_TEST_DEPLOYMENT_TARGET
109 #undef PA_TEST_DEPLOYMENT_TARGET
110 #undef PA_IGNORE_DEPLOYMENT_TARGET
111
112 // This should be infrequently used. It only makes sense to use this to avoid
113 // codepaths that are very likely to break on future (unreleased, untested,
114 // unborn) OS releases, or to log when the OS is newer than any known version.
IsOSLaterThan13_DontCallThis()115 inline bool IsOSLaterThan13_DontCallThis() {
116 return !IsAtMostOS13();
117 }
118
119 } // namespace partition_alloc::internal::base::mac
120
121 #endif // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_BASE_MAC_MAC_UTIL_H_
122