Loading...
libkern/coreanalytics/coreanalytics_shim.cpp xnu-12377.101.15 /dev/null
--- xnu/xnu-12377.101.15/libkern/coreanalytics/coreanalytics_shim.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (c) 2021 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#define IOKIT_ENABLE_SHARED_PTR
-#include <kern/debug.h>
-#include <libkern/coreanalytics/coreanalytics.h>
-#include <libkern/coreanalytics/coreanalytics_shim.h>
-#include <libkern/c++/OSBoolean.h>
-#include <libkern/c++/OSDictionary.h>
-#include <libkern/c++/OSNumber.h>
-#include <libkern/c++/OSMetaClass.h>
-#include <libkern/c++/OSString.h>
-#include <os/atomic.h>
-#include <os/log.h>
-#include <sys/errno.h>
-
-/* Pulled from CoreAnalyticsHub.h in CoreAnalytics project */
-static const char *kCoreAnalyticsMatchingClassName = "CoreAnalyticsHub";
-
-core_analytics_hub_functions_t *core_analytics_hub_functions = NULL;
-
-core_analytics_family_service_t *
-core_analytics_family_match()
-{
-	OSSharedPtr<OSDictionary> dict = IOService::serviceMatching(kCoreAnalyticsMatchingClassName);
-	OSSharedPtr<IOService> service = nullptr;
-	if (dict) {
-		service = IOService::waitForMatchingService(dict.get());
-	} else {
-		os_log_with_startup_serial(OS_LOG_DEFAULT, "No service matching %s\n", kCoreAnalyticsMatchingClassName);
-	}
-	if (service) {
-		return service.detach();
-	} else {
-		os_log_with_startup_serial(OS_LOG_DEFAULT, "Unable to match CoreAnalyticsHub\n");
-		return nullptr;
-	}
-}
-
-void
-core_analytics_family_release(core_analytics_family_service_t *service)
-{
-	service->release();
-}
-
-typedef struct core_analytics_serialized_event_s {
-	OSSharedPtr<OSString> case_event_name;
-	OSSharedPtr<OSDictionary> case_event;
-} core_analytics_serialized_event_t;
-
-/*
- * Stringifying CA_BOOL is different in C vs. C++ b/c the underlying
- * bool typename is different (_Bool vs bool).
- * We want to support both since the event may have been defined in C or C++ code.
- */
-extern const char *core_analytics_ca_bool_c_stringified;
-const char *core_analytics_ca_bool_cpp_stringified = _CA_STRINGIFY_EXPAND(CA_BOOL);
-
-static OSSharedPtr<OSObject>
-serialize_event_field(const char **field_spec, ptrdiff_t *event, OSSharedPtr<const OSSymbol> *key)
-{
-	OSSharedPtr<OSObject> field = nullptr;
-	ptrdiff_t field_value = (ptrdiff_t) *event;
-	uint64_t number_value;
-	const char *str_value;
-	size_t str_len = 0;
-	bool bool_value;
-
-	if (strcmp(*field_spec, _CA_STRINGIFY_EXPAND(CA_INT)) == 0) {
-		number_value = *(const uint64_t *)field_value;
-		field = OSNumber::withNumber(number_value, sizeof(uint64_t) * 8);
-		*event += sizeof(const uint64_t);
-	} else if (strcmp(*field_spec, core_analytics_ca_bool_cpp_stringified) == 0 ||
-	    strcmp(*field_spec, core_analytics_ca_bool_c_stringified) == 0) {
-		bool_value = *(const bool *)field_value;
-		field = OSBoolean::withBoolean(bool_value);
-		*event += sizeof(const bool);
-	} else if ((str_len = core_analytics_field_is_string(*field_spec)) != 0) {
-		str_value = (const char *) field_value;
-		assert(strlen(str_value) < str_len);
-		if (strlen(str_value) < str_len) {
-			field = OSString::withCString(str_value);
-		} else {
-			field = nullptr;
-		}
-		*event += str_len;
-	} else {
-		panic("Unknown CoreAnalytics event type: %s.", *field_spec);
-	}
-	*field_spec += strlen(*field_spec) + 1;
-
-	*key = OSSymbol::withCString(*field_spec);
-	assert(*key != nullptr);
-	if (!*key) {
-		return nullptr;
-	}
-	*field_spec += strlen(*field_spec) + 1;
-	return field;
-}
-
-static int
-core_analytics_serialize_event(const char *event_spec,
-    const ca_event_t event,
-    core_analytics_serialized_event_t *serialized_event)
-{
-	serialized_event->case_event_name = nullptr;
-	serialized_event->case_event = nullptr;
-	OSSharedPtr<OSDictionary> dict = nullptr;
-	bool success;
-	OSSharedPtr<OSString> name = OSString::withCStringNoCopy(event_spec);
-	if (!name) {
-		return ENOMEM;
-	}
-	dict = OSDictionary::withCapacity(1);
-	if (!dict) {
-		return ENOMEM;
-	}
-	const char *spec_curr = event_spec + strlen(event_spec) + 1;
-	ptrdiff_t event_curr = (ptrdiff_t) event->data;
-	while (strlen(spec_curr) != 0) {
-		OSSharedPtr<const OSSymbol> key = NULL;
-		OSSharedPtr<OSObject> object = serialize_event_field(&spec_curr, &event_curr, &key);
-		if (!object) {
-			return ENOMEM;
-		}
-		success = dict->setObject(key, object);
-		if (!success) {
-			return ENOMEM;
-		}
-	}
-
-	serialized_event->case_event_name = name;
-	serialized_event->case_event = dict;
-	return 0;
-}
-
-int
-core_analytics_send_event_lazy(
-	core_analytics_family_service_t *core_analytics_hub,
-	const char *event_spec, const ca_event_t event)
-{
-	int ret = 0;
-	bool success;
-	static constexpr size_t kMaxRetries = 5;
-	static constexpr uint64_t kDelayBetweenRetries = 1000; // microseconds
-	core_analytics_serialized_event_t serialized;
-	if (!core_analytics_hub_functions) {
-		return EAGAIN;
-	}
-
-	ret = core_analytics_serialize_event(event_spec, event, &serialized);
-	if (ret != 0) {
-		return ret;
-	}
-	for (size_t i = 0; i < kMaxRetries; i++) {
-		success = core_analytics_hub_functions->analytics_send_event_lazy(core_analytics_hub, serialized.case_event_name.get(), serialized.case_event.get());
-		if (success) {
-			break;
-		} else {
-			if (i != kMaxRetries - 1) {
-				delay(kDelayBetweenRetries);
-			} else {
-				ret = EAGAIN;
-				break;
-			}
-		}
-	}
-	return ret;
-}
-
-void
-core_analytics_hub_register(core_analytics_hub_functions_t *fns)
-{
-	if (fns->version != CORE_ANALYTICS_FUNCTIONS_TABLE_VERSION) {
-		panic("CoreAnalyticsHub is out of sync with xnu. CoreAnalyticsHub table version: %d. xnu table version: %d", fns->version, CORE_ANALYTICS_FUNCTIONS_TABLE_VERSION);
-	}
-	core_analytics_hub_functions = fns;
-	os_log_with_startup_serial(OS_LOG_DEFAULT, "Registered CoreAnalyticsHub functions with xnu.\n");
-}