5#include "flutter/shell/platform/darwin/common/availability_version_check.h"
11#include <CoreFoundation/CoreFoundation.h>
12#include <dispatch/dispatch.h>
15#include "flutter/fml/build_config.h"
16#include "flutter/fml/file.h"
17#include "flutter/fml/logging.h"
18#include "flutter/fml/mapping.h"
19#include "flutter/fml/platform/darwin/cf_utils.h"
46#define CF_PROPERTY_LIST_IMMUTABLE 0
54 std::string plist_path =
"/System/Library/CoreServices/SystemVersion.plist";
55#if FML_OS_IOS_SIMULATOR
56 char* plist_path_prefix =
getenv(
"IPHONE_SIMULATOR_ROOT");
57 if (!plist_path_prefix) {
61 plist_path = std::string(plist_path_prefix) + plist_path;
69 nullptr, plist_mapping->GetMapping(),
70 static_cast<CFIndex
>(plist_mapping->GetSize()), kCFAllocatorNull));
72 FML_DLOG(
ERROR) <<
"Failed to CFDataCreateWithBytesNoCopyFunc";
77 reinterpret_cast<CFDictionaryRef
>(CFPropertyListCreateWithData(
81 FML_DLOG(
ERROR) <<
"Failed to CFPropertyListCreateWithDataFunc or "
82 "CFPropertyListCreateFromXMLDataFunc";
86 auto product_version =
88 nullptr,
"ProductVersion", kCFStringEncodingASCII, kCFAllocatorNull));
89 if (!product_version) {
90 FML_DLOG(
ERROR) <<
"Failed to CFStringCreateWithCStringNoCopyFunc";
93 CFTypeRef opaque_value = CFDictionaryGetValue(plist, product_version);
94 if (!opaque_value || CFGetTypeID(opaque_value) != CFStringGetTypeID()) {
100 if (!CFStringGetCString(
reinterpret_cast<CFStringRef
>(opaque_value),
101 version_str,
sizeof(version_str),
102 kCFStringEncodingUTF8)) {
109 int32_t subminor = 0;
110 int matches = sscanf(version_str,
"%d.%d.%d", &major, &minor, &subminor);
114 FML_DLOG(
ERROR) <<
"Failed to match product version string: "
124 const int32_t major = (encoded_lhs >> 16) & 0xffff;
125 const int32_t minor = (encoded_lhs >> 8) & 0xff;
126 const int32_t subminor = encoded_lhs & 0xff;
140typedef uint32_t dyld_platform_t;
143 dyld_platform_t platform;
145} dyld_build_version_t;
147typedef bool (*AvailabilityVersionCheckFn)(uint32_t
count,
148 dyld_build_version_t versions[]);
150AvailabilityVersionCheckFn AvailabilityVersionCheck;
152dispatch_once_t DispatchOnceCounter;
154void InitializeAvailabilityCheck(
void*
unused) {
155 if (AvailabilityVersionCheck) {
158 AvailabilityVersionCheck =
reinterpret_cast<AvailabilityVersionCheckFn
>(
159 dlsym(RTLD_DEFAULT,
"_availability_version_check"));
160 if (AvailabilityVersionCheck) {
167 if (product_version.has_value()) {
172#if FML_OS_IOS || FML_OS_IOS_SIMULATOR
180extern "C" bool _availability_version_check(uint32_t
count,
181 dyld_build_version_t versions[]) {
182 dispatch_once_f(&DispatchOnceCounter, NULL, InitializeAvailabilityCheck);
183 if (AvailabilityVersionCheck) {
184 return AvailabilityVersionCheck(
count, versions);
#define CF_PROPERTY_LIST_IMMUTABLE
static std::unique_ptr< FileMapping > CreateReadOnly(const std::string &path)
#define FML_DLOG(severity)
bool IsEncodedVersionLessThanOrSame(uint32_t encoded_lhs, ProductVersion rhs)
std::tuple< int32_t, int32_t, int32_t > ProductVersion
std::optional< ProductVersion > ProductVersionFromSystemVersionPList()
static const unsigned char * g_version