diff --git a/src/SensitiveContentAnalysis/SCVideoStreamAnalyzer.cs b/src/SensitiveContentAnalysis/SCVideoStreamAnalyzer.cs new file mode 100644 index 000000000000..e43ed8560327 --- /dev/null +++ b/src/SensitiveContentAnalysis/SCVideoStreamAnalyzer.cs @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using Foundation; +using ObjCRuntime; + +namespace SensitiveContentAnalysis { +#if __IOS__ && !__MACCATALYST__ + public partial class SCVideoStreamAnalyzer { + /// Create a new instance with the specified particant and stream direction. + /// The unique identifier for a participant in the conference call. + /// Specifies whether the stream comes from the local camera or a remote location. + /// The error object if an error occurs. + /// A new instance with the specified particant and stream direction if successful, otherwise. + public static SCVideoStreamAnalyzer? Create (string participantUuid, SCVideoStreamAnalyzerStreamDirection streamDirection, out NSError? error) + { + var rv = new SCVideoStreamAnalyzer (NSObjectFlag.Empty); + rv.InitializeHandle (rv._InitWithParticipantUuid (participantUuid, streamDirection, out error), "initWithParticipantUUID:streamDirection:error:", false); + if (rv.Handle == NativeHandle.Zero) { + rv.Dispose (); + return null; + } + return rv; + } + } +#endif // __IOS__ && !__MACCATALYST__ +} diff --git a/src/frameworks.sources b/src/frameworks.sources index 3ba666934b97..131078ec1ea0 100644 --- a/src/frameworks.sources +++ b/src/frameworks.sources @@ -1571,6 +1571,11 @@ SECURITY_SOURCES = \ Security/SslConnection.cs \ Security/SslContext.cs \ +# SensitiveContentAnalysis + +SENSITIVECONTENTANALYSIS_SOURCES = \ + SensitiveContentAnalysis/SCVideoStreamAnalyzer.cs \ + # SensorKit SENSORKIT_CORE_SOURCES = \ diff --git a/src/sensitivecontentanalysis.cs b/src/sensitivecontentanalysis.cs index 5ecc6fcb7060..05274bb1119e 100644 --- a/src/sensitivecontentanalysis.cs +++ b/src/sensitivecontentanalysis.cs @@ -1,7 +1,10 @@ using System; +using AVFoundation; using CoreGraphics; +using CoreVideo; using Foundation; using ObjCRuntime; +using VideoToolbox; namespace SensitiveContentAnalysis { [NoTV, Mac (14, 0), iOS (17, 0), MacCatalyst (17, 0)] @@ -10,6 +13,21 @@ namespace SensitiveContentAnalysis { interface SCSensitivityAnalysis { [Export ("sensitive")] bool Sensitive { [Bind ("isSensitive")] get; } + + // From the VideoStreamAnalysis (SCSensitiveAnalysis) category + [NoTV, NoMacCatalyst, NoMac, iOS (26, 0)] + [Export ("shouldInterruptVideo")] + bool ShouldInterruptVideo { get; } + + // From the VideoStreamAnalysis (SCSensitiveAnalysis) category + [NoTV, NoMacCatalyst, NoMac, iOS (26, 0)] + [Export ("shouldIndicateSensitivity")] + bool ShouldIndicateSensitivity { get; } + + // From the VideoStreamAnalysis (SCSensitiveAnalysis) category + [NoTV, NoMacCatalyst, NoMac, iOS (26, 0)] + [Export ("shouldMuteAudio")] + bool ShouldMuteAudio { get; } } [NoTV, Mac (14, 0), iOS (17, 0), MacCatalyst (17, 0)] @@ -38,4 +56,48 @@ interface SCSensitivityAnalyzer { [Async] NSProgress AnalyzeVideo (NSUrl fileUrl, Action completionHandler); } + + [NoTV, NoMacCatalyst, NoMac, iOS (26, 0)] + [Native] + public enum SCVideoStreamAnalyzerStreamDirection : long { + Outgoing = 1, + Incoming = 2, + } + + delegate void SCVideoStreamAnalysisChangeHandler ([NullAllowed] SCSensitivityAnalysis analysis, [NullAllowed] NSError error); + + [NoTV, NoMacCatalyst, NoMac, iOS (26, 0)] + [BaseType (typeof (NSObject))] + [DisableDefaultCtor] + interface SCVideoStreamAnalyzer { + [NullAllowed, Export ("analysis")] + SCSensitivityAnalysis Analysis { get; } + + [Export ("analysisChangedHandler", ArgumentSemantic.Copy)] + [NullAllowed] + SCVideoStreamAnalysisChangeHandler AnalysisChangedHandler { get; set; } + + [Export ("initWithParticipantUUID:streamDirection:error:")] + [Internal] + NativeHandle _InitWithParticipantUuid (string participantUuid, SCVideoStreamAnalyzerStreamDirection streamDirection, [NullAllowed] out NSError error); + + [Export ("analyzePixelBuffer:")] + void AnalyzePixelBuffer (CVPixelBuffer pixelBuffer); + + // From the SessionManagement (SCVideoStreamAnalyzer) category + [Export ("beginAnalysisOfDecompressionSession:error:")] + bool BeginAnalysisOfDecompressionSession (VTDecompressionSession decompressionSession, [NullAllowed] out NSError error); + + // From the SessionManagement (SCVideoStreamAnalyzer) category + [Export ("beginAnalysisOfCaptureDeviceInput:error:")] + bool BeginAnalysisOfCaptureDeviceInput (AVCaptureDeviceInput captureDeviceInput, [NullAllowed] out NSError error); + + // From the SessionManagement (SCVideoStreamAnalyzer) category + [Export ("endAnalysis")] + void EndAnalysis (); + + // From the SessionManagement (SCVideoStreamAnalyzer) category + [Export ("continueStream")] + void ContinueStream (); + } } diff --git a/src/videotoolbox.cs b/src/videotoolbox.cs index 71aac73cc926..9015331cb238 100644 --- a/src/videotoolbox.cs +++ b/src/videotoolbox.cs @@ -17,6 +17,9 @@ namespace VideoToolbox { + interface VTSession : INativeObject { } + interface VTDecompressionSession : VTSession { } + /// A class that encapsulates keys necessary for compression sessions. Used by [MacCatalyst (13, 1)] [Static] diff --git a/tests/cecil-tests/Documentation.KnownFailures.txt b/tests/cecil-tests/Documentation.KnownFailures.txt index 9fc63610ff9b..0327eb64752a 100644 --- a/tests/cecil-tests/Documentation.KnownFailures.txt +++ b/tests/cecil-tests/Documentation.KnownFailures.txt @@ -6047,6 +6047,8 @@ F:Security.TlsProtocolVersion.Tls13 F:SensitiveContentAnalysis.SCSensitivityAnalysisPolicy.DescriptiveInterventions F:SensitiveContentAnalysis.SCSensitivityAnalysisPolicy.Disabled F:SensitiveContentAnalysis.SCSensitivityAnalysisPolicy.SimpleInterventions +F:SensitiveContentAnalysis.SCVideoStreamAnalyzerStreamDirection.Incoming +F:SensitiveContentAnalysis.SCVideoStreamAnalyzerStreamDirection.Outgoing F:SensorKit.SRAcousticSettingsAccessibilityBackgroundSoundsName.Airplane F:SensorKit.SRAcousticSettingsAccessibilityBackgroundSoundsName.Babble F:SensorKit.SRAcousticSettingsAccessibilityBackgroundSoundsName.BalancedNoise @@ -29149,6 +29151,8 @@ T:Security.TlsCipherSuiteGroup T:Security.TlsProtocolVersion T:SecurityUI.SFCertificatePresentation T:SensitiveContentAnalysis.SCSensitivityAnalysisPolicy +T:SensitiveContentAnalysis.SCVideoStreamAnalysisChangeHandler +T:SensitiveContentAnalysis.SCVideoStreamAnalyzerStreamDirection T:SensorKit.SRAbsoluteTime T:SensorKit.SRAcousticSettingsAccessibilityBackgroundSoundsName T:SensorKit.SRAcousticSettingsAccessibilityHeadphoneAccommodationsMediaEnhanceApplication diff --git a/tests/monotouch-test/SensitiveContentAnalysis/SCVideoStreamAnalyzerTest.cs b/tests/monotouch-test/SensitiveContentAnalysis/SCVideoStreamAnalyzerTest.cs new file mode 100644 index 000000000000..b07a4e380a46 --- /dev/null +++ b/tests/monotouch-test/SensitiveContentAnalysis/SCVideoStreamAnalyzerTest.cs @@ -0,0 +1,35 @@ +#if HAS_SENSITIVECONTENTANALYSIS + +using System; + +using Foundation; +using SensitiveContentAnalysis; + +using NUnit.Framework; + + +namespace MonoTouchFixtures.SensitiveContentAnalysis; + +#if __IOS__ && !__MACCATALYST__ + +[TestFixture] +[Preserve (AllMembers = true)] +public class SCVideoStreamAnalyzerTests { + [Test] + public void Create () + { + TestRuntime.AssertXcodeVersion (26, 0); + + using var obj = SCVideoStreamAnalyzer.Create ("placeholder", SCVideoStreamAnalyzerStreamDirection.Outgoing, out var error); + // There are a number of other reasons for this to fail: + // * We don't have a valid participant uuid. + // * A specific entitlement is required (com.apple.developer.sensitivecontentanalysis.client) + // * Only works when "the Communication Safety parental control in Screen Time is enabled, or when the Sensitive Content Warnings setting is turned on". + Assert.That (obj, Is.Null, "Null"); + Assert.That (error, Is.Not.Null, "Error"); + } +} + +#endif // __IOS__ && !__MACCATALYST__ + +#endif // HAS_SENSITIVECONTENTANALYSIS diff --git a/tests/xtro-sharpie/api-annotations-dotnet/iOS-SensitiveContentAnalysis.todo b/tests/xtro-sharpie/api-annotations-dotnet/iOS-SensitiveContentAnalysis.todo deleted file mode 100644 index 0e3675ce0b45..000000000000 --- a/tests/xtro-sharpie/api-annotations-dotnet/iOS-SensitiveContentAnalysis.todo +++ /dev/null @@ -1,14 +0,0 @@ -!missing-enum! SCVideoStreamAnalyzerStreamDirection not bound -!missing-selector! SCSensitivityAnalysis::shouldIndicateSensitivity not bound -!missing-selector! SCSensitivityAnalysis::shouldInterruptVideo not bound -!missing-selector! SCSensitivityAnalysis::shouldMuteAudio not bound -!missing-selector! SCVideoStreamAnalyzer::analysis not bound -!missing-selector! SCVideoStreamAnalyzer::analysisChangedHandler not bound -!missing-selector! SCVideoStreamAnalyzer::analyzePixelBuffer: not bound -!missing-selector! SCVideoStreamAnalyzer::beginAnalysisOfCaptureDeviceInput:error: not bound -!missing-selector! SCVideoStreamAnalyzer::beginAnalysisOfDecompressionSession:error: not bound -!missing-selector! SCVideoStreamAnalyzer::continueStream not bound -!missing-selector! SCVideoStreamAnalyzer::endAnalysis not bound -!missing-selector! SCVideoStreamAnalyzer::initWithParticipantUUID:streamDirection:error: not bound -!missing-selector! SCVideoStreamAnalyzer::setAnalysisChangedHandler: not bound -!missing-type! SCVideoStreamAnalyzer not bound