Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions Sentry.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,7 @@
A8F17B2E2901765900990B25 /* SentryRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = A8F17B2D2901765900990B25 /* SentryRequest.m */; };
A8F17B342902870300990B25 /* SentryHttpStatusCodeRange.m in Sources */ = {isa = PBXBuildFile; fileRef = A8F17B332902870300990B25 /* SentryHttpStatusCodeRange.m */; };
D4009EB22D771BC20007AF30 /* SentryFileIOTrackerSwiftHelpersTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4009EB12D771BB90007AF30 /* SentryFileIOTrackerSwiftHelpersTests.swift */; };
D40A826B2EAA62E900843F37 /* SentryAccessibilityEnabler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D40A82652EAA62E600843F37 /* SentryAccessibilityEnabler.swift */; };
D41415A72DEEE532003B14D5 /* SentryRedactViewHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D41415A62DEEE532003B14D5 /* SentryRedactViewHelper.swift */; };
D4291A6D2DD62ACE00772088 /* SentryDispatchFactoryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4291A6C2DD62AC800772088 /* SentryDispatchFactoryTests.m */; };
D42ADEEF2E9CF43200753166 /* SentrySessionReplayEnvironmentChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = D42ADEE92E9CF42800753166 /* SentrySessionReplayEnvironmentChecker.swift */; };
Expand All @@ -771,6 +772,7 @@
D4411DD52E02B74900EA4987 /* ArrayAccessesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4411DD42E02B74100EA4987 /* ArrayAccessesTests.swift */; };
D44311312EB22812006CABE4 /* SentryUIRedactBuilderTests+ReactNative.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4AF7D212E93FFCA004F0F59 /* SentryUIRedactBuilderTests+ReactNative.swift */; };
D44B16722DE464AD006DBDB3 /* TestDispatchFactoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D44B16712DE464A9006DBDB3 /* TestDispatchFactoryTests.swift */; };
D450A8672EB4CDC9002DB0B4 /* SentryAccessibilityRedactBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = D450A8662EB4CDC9002DB0B4 /* SentryAccessibilityRedactBuilder.swift */; };
D451ED5D2D92ECD200C9BEA8 /* SentryOnDemandReplayError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D451ED5C2D92ECD200C9BEA8 /* SentryOnDemandReplayError.swift */; };
D451ED5F2D92ECDE00C9BEA8 /* SentryReplayFrame.swift in Sources */ = {isa = PBXBuildFile; fileRef = D451ED5E2D92ECDE00C9BEA8 /* SentryReplayFrame.swift */; };
D452FC592DDB4B1700AFF56F /* SentryWatchdogTerminationBreadcrumbProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = D452FC572DDB4B1700AFF56F /* SentryWatchdogTerminationBreadcrumbProcessor.m */; };
Expand Down Expand Up @@ -816,6 +818,9 @@
D4AF00232D2E931000F5F3D7 /* SentryNSFileManagerSwizzling.h in Headers */ = {isa = PBXBuildFile; fileRef = D4AF00222D2E931000F5F3D7 /* SentryNSFileManagerSwizzling.h */; };
D4AF00252D2E93C400F5F3D7 /* SentryNSFileManagerSwizzlingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4AF00242D2E93C400F5F3D7 /* SentryNSFileManagerSwizzlingTests.m */; };
D4AF7D2A2E940493004F0F59 /* SentryUIRedactBuilderTests+Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4AF7D292E940492004F0F59 /* SentryUIRedactBuilderTests+Common.swift */; };
D4AF7E7D2E9537FD004F0F59 /* SentryUIRedactBuilderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4AF7E772E9537F5004F0F59 /* SentryUIRedactBuilderProtocol.swift */; };
D4AF7E7F2E953B43004F0F59 /* SentryMLRedactBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4AF7E7E2E953B3E004F0F59 /* SentryMLRedactBuilder.swift */; };
D4AF7E812E953D10004F0F59 /* SentryMaskingModel.mlpackage in Sources */ = {isa = PBXBuildFile; fileRef = D4AF7E802E953D10004F0F59 /* SentryMaskingModel.mlpackage */; };
D4B0DC7F2DA9257A00DE61B6 /* SentryRenderVideoResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4B0DC7E2DA9257200DE61B6 /* SentryRenderVideoResult.swift */; };
D4B339F92EA7823000359F3A /* SentryTestUtilsDynamic.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D84DAD4D2B17428D003CF120 /* SentryTestUtilsDynamic.framework */; };
D4B339FA2EA7823000359F3A /* SentryTestUtilsDynamic.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D84DAD4D2B17428D003CF120 /* SentryTestUtilsDynamic.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
Expand Down Expand Up @@ -2108,6 +2113,7 @@
A8F17B2D2901765900990B25 /* SentryRequest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryRequest.m; sourceTree = "<group>"; };
A8F17B332902870300990B25 /* SentryHttpStatusCodeRange.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryHttpStatusCodeRange.m; sourceTree = "<group>"; };
D4009EB12D771BB90007AF30 /* SentryFileIOTrackerSwiftHelpersTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryFileIOTrackerSwiftHelpersTests.swift; sourceTree = "<group>"; };
D40A82652EAA62E600843F37 /* SentryAccessibilityEnabler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryAccessibilityEnabler.swift; sourceTree = "<group>"; };
D41415A62DEEE532003B14D5 /* SentryRedactViewHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryRedactViewHelper.swift; sourceTree = "<group>"; };
D41909922D48FFF6002B83D0 /* SentryNSDictionarySanitize+Tests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SentryNSDictionarySanitize+Tests.h"; sourceTree = "<group>"; };
D41909942D490006002B83D0 /* SentryNSDictionarySanitize+Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "SentryNSDictionarySanitize+Tests.m"; sourceTree = "<group>"; };
Expand All @@ -2130,6 +2136,7 @@
D43B26D92D70A60E007747FD /* SentrySpanDataKey.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentrySpanDataKey.m; sourceTree = "<group>"; };
D4411DD42E02B74100EA4987 /* ArrayAccessesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrayAccessesTests.swift; sourceTree = "<group>"; };
D44B16712DE464A9006DBDB3 /* TestDispatchFactoryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestDispatchFactoryTests.swift; sourceTree = "<group>"; };
D450A8662EB4CDC9002DB0B4 /* SentryAccessibilityRedactBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryAccessibilityRedactBuilder.swift; sourceTree = "<group>"; };
D451ED5C2D92ECD200C9BEA8 /* SentryOnDemandReplayError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryOnDemandReplayError.swift; sourceTree = "<group>"; };
D451ED5E2D92ECDE00C9BEA8 /* SentryReplayFrame.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryReplayFrame.swift; sourceTree = "<group>"; };
D452FC562DDB4B1700AFF56F /* SentryWatchdogTerminationBreadcrumbProcessor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryWatchdogTerminationBreadcrumbProcessor.h; path = ../include/SentryWatchdogTerminationBreadcrumbProcessor.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2181,6 +2188,9 @@
D4AF00242D2E93C400F5F3D7 /* SentryNSFileManagerSwizzlingTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryNSFileManagerSwizzlingTests.m; sourceTree = "<group>"; };
D4AF7D212E93FFCA004F0F59 /* SentryUIRedactBuilderTests+ReactNative.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SentryUIRedactBuilderTests+ReactNative.swift"; sourceTree = "<group>"; };
D4AF7D292E940492004F0F59 /* SentryUIRedactBuilderTests+Common.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SentryUIRedactBuilderTests+Common.swift"; sourceTree = "<group>"; };
D4AF7E772E9537F5004F0F59 /* SentryUIRedactBuilderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryUIRedactBuilderProtocol.swift; sourceTree = "<group>"; };
D4AF7E7E2E953B3E004F0F59 /* SentryMLRedactBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryMLRedactBuilder.swift; sourceTree = "<group>"; };
D4AF7E802E953D10004F0F59 /* SentryMaskingModel.mlpackage */ = {isa = PBXFileReference; lastKnownFileType = folder.mlpackage; path = SentryMaskingModel.mlpackage; sourceTree = "<group>"; };
D4B0DC7E2DA9257200DE61B6 /* SentryRenderVideoResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryRenderVideoResult.swift; sourceTree = "<group>"; };
D4BCA0C22DA93C25009E49AB /* SentrySessionReplayIntegration+Test.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SentrySessionReplayIntegration+Test.h"; sourceTree = "<group>"; };
D4C5F5992D4249E0002A9BF6 /* DataSentryTracingIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataSentryTracingIntegrationTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -4956,11 +4966,16 @@
children = (
D4CD2A7C2DE9F91900DA9F59 /* SentryRedactRegion.swift */,
D4CD2A7D2DE9F91900DA9F59 /* SentryRedactRegionType.swift */,
D40A82652EAA62E600843F37 /* SentryAccessibilityEnabler.swift */,
D450A8662EB4CDC9002DB0B4 /* SentryAccessibilityRedactBuilder.swift */,
FA67DCDF2DDBD4EA00896B02 /* SentryDefaultMaskRenderer.swift */,
FA67DCE02DDBD4EA00896B02 /* SentryDefaultViewRenderer.swift */,
FA67DCE12DDBD4EA00896B02 /* SentryGraphicsImageRenderer.swift */,
FA67DCE22DDBD4EA00896B02 /* SentryMaskRenderer.swift */,
FA67DCE32DDBD4EA00896B02 /* SentryMaskRendererV2.swift */,
D4AF7E7E2E953B3E004F0F59 /* SentryMLRedactBuilder.swift */,
D4AF7E802E953D10004F0F59 /* SentryMaskingModel.mlpackage */,
D4AF7E772E9537F5004F0F59 /* SentryUIRedactBuilderProtocol.swift */,
FA67DCE42DDBD4EA00896B02 /* SentryViewPhotographer.swift */,
FA67DCE52DDBD4EA00896B02 /* SentryViewRenderer.swift */,
FA67DCE62DDBD4EA00896B02 /* SentryViewRendererV2.swift */,
Expand Down Expand Up @@ -5757,6 +5772,7 @@
623FD9042D3FA92700803EDA /* NSNumberDecodableWrapper.swift in Sources */,
63FE718D20DA4C1100CDBAE8 /* SentryCrashReportStore.c in Sources */,
7BA0C0482805600A003E0326 /* SentryTransportAdapter.m in Sources */,
D4AF7E812E953D10004F0F59 /* SentryMaskingModel.mlpackage in Sources */,
63FE712920DA4C1000CDBAE8 /* SentryCrashCPU_arm.c in Sources */,
03F84D3427DD4191008FE43F /* SentryThreadMetadataCache.cpp in Sources */,
62862B1E2B1DDC35009B16E3 /* SentryDelayedFrame.m in Sources */,
Expand All @@ -5782,6 +5798,7 @@
8E133FA225E72DEF00ABD0BF /* SentrySamplingContext.m in Sources */,
F451FAA62E0B304E0050ACF2 /* LoadValidator.swift in Sources */,
D81988C02BEBFFF70020E36C /* SentryReplayRecording.swift in Sources */,
D4AF7E7D2E9537FD004F0F59 /* SentryUIRedactBuilderProtocol.swift in Sources */,
7B6C5F8726034395007F7DFF /* SentryWatchdogTerminationLogic.m in Sources */,
63FE708D20DA4C1000CDBAE8 /* SentryCrashReportFilterBasic.m in Sources */,
F40E42352EA1887000E53876 /* SentryFramesTracker.swift in Sources */,
Expand Down Expand Up @@ -5958,12 +5975,14 @@
849B8F9C2C6E906900148E1F /* SentryUserFeedbackThemeConfiguration.swift in Sources */,
F452437E2DE60B71003E8F50 /* SentryUseNSExceptionCallstackWrapper.m in Sources */,
63FE70D320DA4C1000CDBAE8 /* SentryCrashMonitor_AppState.c in Sources */,
D4AF7E7F2E953B43004F0F59 /* SentryMLRedactBuilder.swift in Sources */,
FA1841832E4B457F005DEDC7 /* SentryApplication.swift in Sources */,
849B8F9D2C6E906900148E1F /* SentryUserFeedbackWidgetConfiguration.swift in Sources */,
620467AC2D3FFD230025F06C /* SentryNSErrorCodable.swift in Sources */,
639FCFA51EBC809A00778193 /* SentryStacktrace.m in Sources */,
D84D2CC32C29AD120011AF8A /* SentrySessionReplay.swift in Sources */,
F4FE9DFD2E622CD70014FED5 /* SentryDefaultObjCRuntimeWrapper.swift in Sources */,
D40A826B2EAA62E900843F37 /* SentryAccessibilityEnabler.swift in Sources */,
F4FE9DFE2E622CD70014FED5 /* SentryObjCRuntimeWrapper.swift in Sources */,
84A898542E163072009A551E /* SentryProfileConfiguration.m in Sources */,
849B8F9B2C6E906900148E1F /* SentryUserFeedbackIntegrationDriver.swift in Sources */,
Expand Down Expand Up @@ -6013,6 +6032,7 @@
63FE713120DA4C1100CDBAE8 /* SentryCrashDynamicLinker.c in Sources */,
03F84D3527DD4191008FE43F /* SentryThreadHandle.cpp in Sources */,
0A2D8DA9289BC905008720F6 /* SentryViewHierarchyProviderHelper.m in Sources */,
D450A8672EB4CDC9002DB0B4 /* SentryAccessibilityRedactBuilder.swift in Sources */,
D84D2CDD2C2BF7370011AF8A /* SentryReplayEvent.swift in Sources */,
D8BC28CC2BFF78220054DA4D /* SentryRRWebTouchEvent.swift in Sources */,
D452FC592DDB4B1700AFF56F /* SentryWatchdogTerminationBreadcrumbProcessor.m in Sources */,
Expand Down
11 changes: 10 additions & 1 deletion Sources/Sentry/SentrySessionReplayIntegration.m
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,19 @@ - (void)setupWith:(SentryReplayOptions *)replayOptions
viewRenderer = [[SentryDefaultViewRenderer alloc] init];
}

id<SentryUIRedactBuilderProtocol> redactBuilder;
if (experimentalOptions.sessionReplayMaskingStrategy == kSessionReplayMaskingStrategyAccessibilty) {
redactBuilder = [[SentryAccessibilityRedactBuilder alloc] initWithOptions:replayOptions];
} else if(experimentalOptions.sessionReplayMaskingStrategy == kSessionReplayMaskingStrategyMachineLearning) {
redactBuilder = [[SentryMLRedactBuilder alloc] initWithOptions:replayOptions];
} else {
redactBuilder = [[SentryUIRedactBuilder alloc] initWithOptions:replayOptions];
}

// We are using the flag for the view renderer V2 also for the mask renderer V2, as it would
// just introduce another option without affecting the SDK user experience.
_viewPhotographer = [[SentryViewPhotographer alloc] initWithRenderer:viewRenderer
redactOptions:replayOptions
redactBuilder:redactBuilder
enableMaskRendererV2:enableViewRendererV2];

if (touchTracker) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
//
// SentryAccessibilityEnabler.swift
// Sentry
//
// Enables accessibility temporarily for redaction purposes.
// Based on ASAccessibilityEnabler from AccessibilitySnapshot.
//

import Foundation
import Darwin

@objcMembers
public final class SentryAccessibilityEnabler: NSObject {
private typealias AXSAutomationEnabled = @convention(c) () -> Int32
private typealias AXSSetAutomationEnabled = @convention(c) (Int32) -> Void

private var getAutomationEnabled: AXSAutomationEnabled?
private var setAutomationEnabled: AXSSetAutomationEnabled?
private var previousValue: Int32 = 0
private var handle: UnsafeMutableRawPointer?

public override init() {
self.getAutomationEnabled = nil
self.setAutomationEnabled = nil
self.previousValue = 0
self.handle = nil
super.init()
}

/// Enables accessibility automation by calling the private _AXSSetAutomationEnabled API.
/// - Returns: true if accessibility was successfully enabled, false otherwise.
public func enable() -> Bool {
if handle != nil {
// Already loaded
return true
}

// Load the private accessibility dylib
guard let h = loadDylib(path: "/usr/lib/libAccessibility.dylib") else {
NSLog("[Sentry] Failed to load libAccessibility.dylib")
return false
}
handle = h

// Resolve function pointers to private APIs
guard let symEnabled = dlsym(h, "_AXSAutomationEnabled"),
let symSetEnabled = dlsym(h, "_AXSSetAutomationEnabled") else {
NSLog("[Sentry] Failed to find accessibility automation functions")
dlclose(h)
handle = nil
return false
}

getAutomationEnabled = unsafeBitCast(symEnabled, to: AXSAutomationEnabled.self)
setAutomationEnabled = unsafeBitCast(symSetEnabled, to: AXSSetAutomationEnabled.self)

// Save current state and enable accessibility
previousValue = getAutomationEnabled?() ?? 0
setAutomationEnabled?(1)

return true
}

/// Disables accessibility automation and restores the previous state.
public func disable() {
guard let handle else {
// Not enabled
return
}

// Restore previous state
if let setAutomationEnabled {
setAutomationEnabled(previousValue)
}

// Clean up
dlclose(handle)
self.handle = nil
self.getAutomationEnabled = nil
self.setAutomationEnabled = nil
}

private func loadDylib(path: String) -> UnsafeMutableRawPointer? {
// Handle simulator vs device paths
let environment = ProcessInfo.processInfo.environment
if let simulatorRoot = environment["IPHONE_SIMULATOR_ROOT"] {
let fullPath = simulatorRoot + path
return dlopen((fullPath as NSString).fileSystemRepresentation, RTLD_LOCAL)
} else {
return dlopen((path as NSString).fileSystemRepresentation, RTLD_LOCAL)
}
}

deinit {
disable()
}
}
Loading
Loading