objc2-av-foundation 0.3.2

Bindings to the AVFoundation framework
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::ffi::*;
use core::ptr::NonNull;
#[cfg(feature = "dispatch2")]
use dispatch2::*;
use objc2::__framework_prelude::*;
#[cfg(feature = "objc2-core-media")]
use objc2_core_media::*;
use objc2_foundation::*;

use crate::*;

/// Used by AVContentKeySession to determine the method of key delivery
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avcontentkeysystem?language=objc)
// NS_TYPED_ENUM
pub type AVContentKeySystem = NSString;

extern "C" {
    /// Used to specify FairPlay Streaming (FPS) as the method of key delivery.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avcontentkeysystemfairplaystreaming?language=objc)
    pub static AVContentKeySystemFairPlayStreaming: &'static AVContentKeySystem;
}

extern "C" {
    /// Used to specify clear key as the method of key delivery.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avcontentkeysystemclearkey?language=objc)
    pub static AVContentKeySystemClearKey: &'static AVContentKeySystem;
}

extern "C" {
    /// Used to specify a token that could be used to authorize playback of associated content key recipients.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avcontentkeysystemauthorizationtoken?language=objc)
    pub static AVContentKeySystemAuthorizationToken: &'static AVContentKeySystem;
}

/// Options keys used to specify additional information for generating server playback context (SPC) in
/// -[AVContentKeySession invalidatePersistableContentKey:options:completionHandler:] and
/// -[AVContentKeySession invalidateAllPersistableContentKeysForApp:options:completionHandler:]
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avcontentkeysessionserverplaybackcontextoption?language=objc)
// NS_TYPED_ENUM
pub type AVContentKeySessionServerPlaybackContextOption = NSString;

extern "C" {
    /// Specifies the versions of the content protection protocol supported by the application; as an NSArray of one or more NSNumber objects. If this option is not set, an appropriate protocol version will be selected based on sideband information such as an associated HLS playlist. If such information is not available, a protocol version of 1 is assumed
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avcontentkeysessionserverplaybackcontextoptionprotocolversions?language=objc)
    pub static AVContentKeySessionServerPlaybackContextOptionProtocolVersions:
        &'static AVContentKeySessionServerPlaybackContextOption;
}

extern "C" {
    /// Specifies a nonce as a 8-byte NSData object to be included in the secure server playback context (SPC) in order to prevent replay attacks. If not specified default server challenge of 0 is assumed.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avcontentkeysessionserverplaybackcontextoptionserverchallenge?language=objc)
    pub static AVContentKeySessionServerPlaybackContextOptionServerChallenge:
        &'static AVContentKeySessionServerPlaybackContextOption;
}

extern_class!(
    /// An AVContentKeySession is used to create and track decryption keys for media data. Objects conforming to the AVContentKeyRecipient protocol, such as AVURLAssets, can be added to an AVContentKeySession to employ the services of the AVContentKeySession in handling new key requests and to obtain access to the session's already existing keys.
    ///
    /// Its secondary purpose is to provide a report of expired sessions to assist a controlling entity that wishes to track the set of sessions that are still active. If initialized with a location at which to store them, AVContentKeySession maintains a global collection of pending "expired session reports", each associated with an identifier for the app that created the session. The contents of this identifier are specified by the controlling entity that provides media data or that grants permission for its use.
    ///
    /// Expired sessions are tracked as follows: a stream processing session is considered to be started after an instance of AVContentKeySession is created and the first object conforming to the AVContentKeyRecipient protocol is added to it. If an instance of AVContentKeySession that has reached this state does not receive an expire message before it's deallocated or the process in which it's running is terminated, an "expired session report" will subsequently be added to the pending list of expired session reports that indicates that the session expired abnormally. In contrast, for AVContentKeySessions that reach the state of having at least one object conforming to the AVContentKeyRecipient protocol added to them and later receive an expire message, "expired session reports" will be generated that indicate that the session expired normally.
    ///
    /// To obtain the collection of pending expired session reports in order to provide them to the controlling entity associated with a specific app identifier, use +pendingExpiredSessionReportsWithAppIdentifier:.
    ///
    /// After pending expired session reports have been sent to the controlling entity and their receipt has been acknowledged, they can be removed from the collection of pending expired session reports maintained by AVContentKeySession by using +removePendingExpiredSessionReports:withAppIdentifier:.
    ///
    /// Subclasses of this type that are used from Swift must fulfill the requirements of a Sendable type.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avcontentkeysession?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct AVContentKeySession;
);

unsafe impl Send for AVContentKeySession {}

unsafe impl Sync for AVContentKeySession {}

extern_conformance!(
    unsafe impl NSObjectProtocol for AVContentKeySession {}
);

impl AVContentKeySession {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;

        /// Creates a new instance of AVContentKeySession to manage a collection of media content keys.
        ///
        /// This method returns an AVContentKeySession instance that is capable of managing collection of media content keys corresponding to the input keySystem. An NSInvalidArgumentException will be raised if the value of keySystem is unsupported.
        ///
        /// - Parameter keySystem: A valid key system for retrieving keys.
        ///
        /// - Returns: A new AVContentKeySession.
        #[unsafe(method(contentKeySessionWithKeySystem:))]
        #[unsafe(method_family = none)]
        pub unsafe fn contentKeySessionWithKeySystem(
            key_system: &AVContentKeySystem,
        ) -> Retained<Self>;

        /// Creates a new instance of AVContentKeySession to manage a collection of media content keys.
        ///
        /// This method returns an AVContentKeySession instance that is capable of managing collection of media content keys corresponding to the input keySystem. An NSInvalidArgumentException will be raised if the value of keySystem is unsupported.
        ///
        /// - Parameter keySystem: A valid key system for retrieving keys.
        /// - Parameter storageURL: URL to a writable directory that the session will use to facilitate expired session reports after abnormal session termination.
        ///
        /// - Returns: A new AVContentKeySession.
        #[unsafe(method(contentKeySessionWithKeySystem:storageDirectoryAtURL:))]
        #[unsafe(method_family = none)]
        pub unsafe fn contentKeySessionWithKeySystem_storageDirectoryAtURL(
            key_system: &AVContentKeySystem,
            storage_url: &NSURL,
        ) -> Retained<Self>;

        #[cfg(feature = "dispatch2")]
        /// Sets the receiver's delegate. A delegate is required to handle content key initialization.
        ///
        /// - Parameter delegate: An object conforming to the AVContentKeySessionDelegate protocol.
        /// - Parameter delegateQueue: A dispatch queue on which delegate methods will be invoked whenever processes requiring content keys are executed asynchronously. Passing a value of nil for the delegateQueue parameter along with a non-nil value for the delegate parameter will result in an invalid argument exception.
        ///
        /// # Safety
        ///
        /// `delegate_queue` possibly has additional threading requirements.
        #[unsafe(method(setDelegate:queue:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setDelegate_queue(
            &self,
            delegate: Option<&ProtocolObject<dyn AVContentKeySessionDelegate>>,
            delegate_queue: Option<&DispatchQueue>,
        );

        /// The receiver's delegate.
        ///
        /// The value of this property is an object conforming to the AVContentKeySessionDelegate protocol. The delegate is set using the setDelegate:queue: method.
        #[unsafe(method(delegate))]
        #[unsafe(method_family = none)]
        pub unsafe fn delegate(
            &self,
        ) -> Option<Retained<ProtocolObject<dyn AVContentKeySessionDelegate>>>;

        #[cfg(feature = "dispatch2")]
        /// The dispatch queue on which all delegate methods will be invoked whenever processes requiring content keys are executed asynchronously.
        ///
        /// The value of this property is a dispatch_queue_t. The queue is set using the setDelegate:queue: method.
        #[unsafe(method(delegateQueue))]
        #[unsafe(method_family = none)]
        pub unsafe fn delegateQueue(&self) -> Option<Retained<DispatchQueue>>;

        /// The storage URL provided when the AVContentKeySession was created. May be nil.
        ///
        /// URL to a writable directory; may be nil. The session will use this to facilitate expired session reports after abnormal session termination.
        #[unsafe(method(storageURL))]
        #[unsafe(method_family = none)]
        pub unsafe fn storageURL(&self) -> Option<Retained<NSURL>>;

        /// The key system used for retrieving keys
        #[unsafe(method(keySystem))]
        #[unsafe(method_family = none)]
        pub unsafe fn keySystem(&self) -> Retained<AVContentKeySystem>;

        /// Tells the receiver to treat the session as having been intentionally and normally expired.
        ///
        /// When an instance of AVContentKeySession receives an expire message, all of its associated objects conforming to the AVContentKeyRecipient protocol will become inoperable. Send this message only after you have finished operating on the media data.
        #[unsafe(method(expire))]
        #[unsafe(method_family = none)]
        pub unsafe fn expire(&self);

        /// An opaque identifier for the current content protection session.
        ///
        /// May be nil. Will call the delegate's contentKeySessionContentProtectionSessionIdentifierDidChange: when the identifier changes. The protection session ID is a unique string identifier generated by the AVContentKeySession that can be used by the application to identify content key session objects.
        #[unsafe(method(contentProtectionSessionIdentifier))]
        #[unsafe(method_family = none)]
        pub unsafe fn contentProtectionSessionIdentifier(&self) -> Option<Retained<NSData>>;

        /// Informs the receiver that it should attempt to instantiate a content decryption key using the specified initialization data.
        ///
        /// May be used to generate an AVContentKeyRequest from request initialization data already in hand, without awaiting such data during the processing of media data of an associated recipient.
        ///
        /// - Parameter identifier: Container- and protocol-specific identifier to be used to obtain a key response. Either identifier or initializationData must be non-nil. Both can be non-nil, if the content protection protocol requires both.
        /// - Parameter initializationData: Container- and protocol-specific data to be used to obtain a key response. Either identifier or initializationData must be non-nil. Both can be non-nil, if the content protection protocol requires both.
        /// - Parameter options: Additional information necessary to obtain the key, or nil if none. See AVContentKeyRequest*Key below.
        ///
        /// # Safety
        ///
        /// - `identifier` should be of the correct type.
        /// - `options` generic should be of the correct type.
        #[unsafe(method(processContentKeyRequestWithIdentifier:initializationData:options:))]
        #[unsafe(method_family = none)]
        pub unsafe fn processContentKeyRequestWithIdentifier_initializationData_options(
            &self,
            identifier: Option<&AnyObject>,
            initialization_data: Option<&NSData>,
            options: Option<&NSDictionary<NSString, AnyObject>>,
        );

        /// Informs the receiver that the already provided response data for an earlier AVContentKeyRequest will imminently expire.
        ///
        /// In response the receiver will invoke your delegate with a new content key request entreating it to renew the expiring response data, via -contentKeySession:didProvideRenewingContentKeyRequest:.
        #[unsafe(method(renewExpiringResponseDataForContentKeyRequest:))]
        #[unsafe(method_family = none)]
        pub unsafe fn renewExpiringResponseDataForContentKeyRequest(
            &self,
            content_key_request: &AVContentKeyRequest,
        );

        #[cfg(feature = "block2")]
        /// Creates a secure server playback context (SPC) that the client could send to the key server to obtain an expiration date for the provided persistable content key data.
        ///
        /// - Parameter persistableContentKeyData: Persistable content key data that was previously created using -[AVContentKeyRequest persistableContentKeyFromKeyVendorResponse:options:error:] or obtained via AVContentKeySessionDelegate callback -contentKeySession:didUpdatePersistableContentKey:forContentKeyIdentifier:.
        /// - Parameter handler: Once the secure token is ready, this block will be called with the token or an error describing the failure.
        ///
        /// # Safety
        ///
        /// `handler` block must be sendable.
        #[unsafe(method(makeSecureTokenForExpirationDateOfPersistableContentKey:completionHandler:))]
        #[unsafe(method_family = none)]
        pub unsafe fn makeSecureTokenForExpirationDateOfPersistableContentKey_completionHandler(
            &self,
            persistable_content_key_data: &NSData,
            handler: &block2::DynBlock<dyn Fn(*mut NSData, *mut NSError)>,
        );

        #[cfg(feature = "block2")]
        /// Invalidates the persistable content key and creates a secure server playback context (SPC) that the client could send to the key server to verify the outcome of invalidation request.
        ///
        /// Once invalidated, a persistable content key cannot be used to answer key requests during later playback sessions.
        ///
        /// - Parameter persistableContentKeyData: Persistable content key data that was previously created using -[AVContentKeyRequest persistableContentKeyFromKeyVendorResponse:options:error:] or obtained via AVContentKeySessionDelegate callback -contentKeySession:didUpdatePersistableContentKey:forContentKeyIdentifier:.
        /// - Parameter options: Additional information necessary to generate the server playback context, or nil if none. See AVContentKeySessionServerPlaybackContextOption for supported options.
        /// - Parameter handler: Once the server playback context is ready, this block will be called with the data or an error describing the failure.
        ///
        /// # Safety
        ///
        /// - `options` generic should be of the correct type.
        /// - `handler` block must be sendable.
        #[unsafe(method(invalidatePersistableContentKey:options:completionHandler:))]
        #[unsafe(method_family = none)]
        pub unsafe fn invalidatePersistableContentKey_options_completionHandler(
            &self,
            persistable_content_key_data: &NSData,
            options: Option<
                &NSDictionary<AVContentKeySessionServerPlaybackContextOption, AnyObject>,
            >,
            handler: &block2::DynBlock<dyn Fn(*mut NSData, *mut NSError)>,
        );

        #[cfg(feature = "block2")]
        /// Invalidates all persistable content keys associated with the application and creates a secure server playback context (SPC) that the client could send to the key server to verify the outcome of invalidation request.
        ///
        /// Once invalidated, persistable content keys cannot be used to answer key requests during later playback sessions.
        ///
        /// - Parameter appIdentifier: An opaque identifier for the application. The contents of this identifier depend on the particular protocol in use by the entity that controls the use of the media data.
        /// - Parameter options: Additional information necessary to generate the server playback context, or nil if none. See AVContentKeySessionServerPlaybackContextOption for supported options.
        /// - Parameter handler: Once the server playback context is ready, this block will be called with the data or an error describing the failure.
        ///
        /// # Safety
        ///
        /// - `options` generic should be of the correct type.
        /// - `handler` block must be sendable.
        #[unsafe(method(invalidateAllPersistableContentKeysForApp:options:completionHandler:))]
        #[unsafe(method_family = none)]
        pub unsafe fn invalidateAllPersistableContentKeysForApp_options_completionHandler(
            &self,
            app_identifier: &NSData,
            options: Option<
                &NSDictionary<AVContentKeySessionServerPlaybackContextOption, AnyObject>,
            >,
            handler: &block2::DynBlock<dyn Fn(*mut NSData, *mut NSError)>,
        );
    );
}

/// AVContentKeyRecipients.
impl AVContentKeySession {
    extern_methods!(
        /// Informs the receiver that the specified recipient will be used for the session.
        ///
        /// It is an error to add recipient to sessions that have received an expire message. It is also an error to add recipients after they have already begun to process media data (e.g. after an AVURLAsset has loaded the values of any of its keys). Such errors will result in NSInternalInconsistencyExceptions. Sending this message to an AVContentKeySession is atomic.
        #[unsafe(method(addContentKeyRecipient:))]
        #[unsafe(method_family = none)]
        pub unsafe fn addContentKeyRecipient(
            &self,
            recipient: &ProtocolObject<dyn AVContentKeyRecipient>,
        );

        /// Informs the receiver that the specified recipient will no longer be used.
        ///
        /// After the specified recipient is removed from the receiver it will become inoperable. Remove the recipient only after you have finished operating on the media data associated with it. Sending this message to an AVContentKeySession is atomic.
        #[unsafe(method(removeContentKeyRecipient:))]
        #[unsafe(method_family = none)]
        pub unsafe fn removeContentKeyRecipient(
            &self,
            recipient: &ProtocolObject<dyn AVContentKeyRecipient>,
        );

        /// The array of recipients of content keys currently associated with the AVContentKeySession.
        #[unsafe(method(contentKeyRecipients))]
        #[unsafe(method_family = none)]
        pub unsafe fn contentKeyRecipients(
            &self,
        ) -> Retained<NSArray<ProtocolObject<dyn AVContentKeyRecipient>>>;
    );
}

/// AVContentKeySessionPendingExpiredSessionReports.
impl AVContentKeySession {
    extern_methods!(
        /// Provides "expired session reports" for prior AVContentKeySessions created with the specified app identifier that have expired either normally or abnormally.
        ///
        /// Note that no reports for sessions still in progress will be included.
        ///
        /// - Parameter appIdentifier: An opaque identifier for the application. The contents of this identifier depend on the particular protocol in use by the entity that controls the use of the media data.
        /// - Parameter storageURL: URL to a directory previously used with one or more instances of AVContentKeySession for the storage of expired session reports.
        ///
        /// - Returns: An NSArray containing instances of NSData, each containing a pending expired session report as a property-list serialization of an NSDictionary object. The contents of expired session reports depend on the particular protocol in use by the entity that controls the use of the media data.
        #[unsafe(method(pendingExpiredSessionReportsWithAppIdentifier:storageDirectoryAtURL:))]
        #[unsafe(method_family = none)]
        pub unsafe fn pendingExpiredSessionReportsWithAppIdentifier_storageDirectoryAtURL(
            app_identifier: &NSData,
            storage_url: &NSURL,
        ) -> Retained<NSArray<NSData>>;

        /// Removes expired session reports for prior AVContentKeySessions from storage. Once they have been removed, they will no longer be available via subsequent invocations of +pendingExpiredSessionReportsWithAppIdentifier:.
        ///
        /// This method is most suitable for use only after the specified expired session reports have been sent to the entity that controls the use of the media data and the entity has acknowledged their receipt.
        ///
        /// - Parameter expiredSessionReports: An array of expired session reports to be discarded.
        /// - Parameter appIdentifier: An opaque identifier for the application. The contents of this identifier depend on the particular protocol in use by the entity that controls the use of the media data.
        /// - Parameter storageURL: URL to a writable folder.
        #[unsafe(method(removePendingExpiredSessionReports:withAppIdentifier:storageDirectoryAtURL:))]
        #[unsafe(method_family = none)]
        pub unsafe fn removePendingExpiredSessionReports_withAppIdentifier_storageDirectoryAtURL(
            expired_session_reports: &NSArray<NSData>,
            app_identifier: &NSData,
            storage_url: &NSURL,
        );
    );
}

/// Used to specify a reason for asking the client to retry a content key request.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avcontentkeyrequestretryreason?language=objc)
// NS_TYPED_ENUM
pub type AVContentKeyRequestRetryReason = NSString;

extern "C" {
    /// Indicates that the content key request should be retried because the key response was not set soon enough either due the initial request/response was taking too long, or a lease was expiring in the meantime.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avcontentkeyrequestretryreasontimedout?language=objc)
    pub static AVContentKeyRequestRetryReasonTimedOut: &'static AVContentKeyRequestRetryReason;
}

extern "C" {
    /// Indicates that the content key request should be retried because a key response with expired lease was set on the previous content key request.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avcontentkeyrequestretryreasonreceivedresponsewithexpiredlease?language=objc)
    pub static AVContentKeyRequestRetryReasonReceivedResponseWithExpiredLease:
        &'static AVContentKeyRequestRetryReason;
}

extern "C" {
    /// Indicates that the content key request should be retried because an obsolete key response was set on the previous content key request.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avcontentkeyrequestretryreasonreceivedobsoletecontentkey?language=objc)
    pub static AVContentKeyRequestRetryReasonReceivedObsoleteContentKey:
        &'static AVContentKeyRequestRetryReason;
}

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avcontentkeysessiondelegate?language=objc)
    pub unsafe trait AVContentKeySessionDelegate: NSObjectProtocol + Send + Sync {
        #[unsafe(method(contentKeySession:didProvideContentKeyRequest:))]
        #[unsafe(method_family = none)]
        unsafe fn contentKeySession_didProvideContentKeyRequest(
            &self,
            session: &AVContentKeySession,
            key_request: &AVContentKeyRequest,
        );

        #[optional]
        #[unsafe(method(contentKeySession:didProvideRenewingContentKeyRequest:))]
        #[unsafe(method_family = none)]
        unsafe fn contentKeySession_didProvideRenewingContentKeyRequest(
            &self,
            session: &AVContentKeySession,
            key_request: &AVContentKeyRequest,
        );

        #[optional]
        #[unsafe(method(contentKeySession:didProvidePersistableContentKeyRequest:))]
        #[unsafe(method_family = none)]
        unsafe fn contentKeySession_didProvidePersistableContentKeyRequest(
            &self,
            session: &AVContentKeySession,
            key_request: &AVPersistableContentKeyRequest,
        );

        /// # Safety
        ///
        /// `key_identifier` should be of the correct type.
        #[optional]
        #[unsafe(method(contentKeySession:didUpdatePersistableContentKey:forContentKeyIdentifier:))]
        #[unsafe(method_family = none)]
        unsafe fn contentKeySession_didUpdatePersistableContentKey_forContentKeyIdentifier(
            &self,
            session: &AVContentKeySession,
            persistable_content_key: &NSData,
            key_identifier: &AnyObject,
        );

        #[optional]
        #[unsafe(method(contentKeySession:contentKeyRequest:didFailWithError:))]
        #[unsafe(method_family = none)]
        unsafe fn contentKeySession_contentKeyRequest_didFailWithError(
            &self,
            session: &AVContentKeySession,
            key_request: &AVContentKeyRequest,
            err: &NSError,
        );

        #[optional]
        #[unsafe(method(contentKeySession:shouldRetryContentKeyRequest:reason:))]
        #[unsafe(method_family = none)]
        unsafe fn contentKeySession_shouldRetryContentKeyRequest_reason(
            &self,
            session: &AVContentKeySession,
            key_request: &AVContentKeyRequest,
            retry_reason: &AVContentKeyRequestRetryReason,
        ) -> bool;

        #[optional]
        #[unsafe(method(contentKeySession:contentKeyRequestDidSucceed:))]
        #[unsafe(method_family = none)]
        unsafe fn contentKeySession_contentKeyRequestDidSucceed(
            &self,
            session: &AVContentKeySession,
            key_request: &AVContentKeyRequest,
        );

        #[optional]
        #[unsafe(method(contentKeySessionContentProtectionSessionIdentifierDidChange:))]
        #[unsafe(method_family = none)]
        unsafe fn contentKeySessionContentProtectionSessionIdentifierDidChange(
            &self,
            session: &AVContentKeySession,
        );

        #[optional]
        #[unsafe(method(contentKeySessionDidGenerateExpiredSessionReport:))]
        #[unsafe(method_family = none)]
        unsafe fn contentKeySessionDidGenerateExpiredSessionReport(
            &self,
            session: &AVContentKeySession,
        );

        #[optional]
        #[unsafe(method(contentKeySession:externalProtectionStatusDidChangeForContentKey:))]
        #[unsafe(method_family = none)]
        unsafe fn contentKeySession_externalProtectionStatusDidChangeForContentKey(
            &self,
            session: &AVContentKeySession,
            content_key: &AVContentKey,
        );

        #[optional]
        #[unsafe(method(contentKeySession:didProvideContentKeyRequests:forInitializationData:))]
        #[unsafe(method_family = none)]
        unsafe fn contentKeySession_didProvideContentKeyRequests_forInitializationData(
            &self,
            session: &AVContentKeySession,
            key_requests: &NSArray<AVContentKeyRequest>,
            initialization_data: Option<&NSData>,
        );
    }
);

/// [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avcontentkeyrequeststatus?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct AVContentKeyRequestStatus(pub NSInteger);
impl AVContentKeyRequestStatus {
    /// Indicates that the request has just been created.
    #[doc(alias = "AVContentKeyRequestStatusRequestingResponse")]
    pub const RequestingResponse: Self = Self(0);
    /// Indicates that a response to a key reequest was received and key is in use. This does not indicate that the key is valid.
    #[doc(alias = "AVContentKeyRequestStatusReceivedResponse")]
    pub const ReceivedResponse: Self = Self(1);
    /// Indicates that the key request was renewed. This does not indicate that the key is valid.
    #[doc(alias = "AVContentKeyRequestStatusRenewed")]
    pub const Renewed: Self = Self(2);
    /// Indicates that the key request was retried.
    #[doc(alias = "AVContentKeyRequestStatusRetried")]
    pub const Retried: Self = Self(3);
    /// Indicates that the key request was cancelled.
    #[doc(alias = "AVContentKeyRequestStatusCancelled")]
    pub const Cancelled: Self = Self(4);
    /// Indicates that the request has encountered an error. See also the error property.
    #[doc(alias = "AVContentKeyRequestStatusFailed")]
    pub const Failed: Self = Self(5);
}

unsafe impl Encode for AVContentKeyRequestStatus {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

unsafe impl RefEncode for AVContentKeyRequestStatus {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

extern "C" {
    /// Request secure token to have extended validation data. The value for the key should be previously created offline key using -[AVContentKeyRequest persistableContentKeyFromKeyVendorResponse:options:error:].
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avcontentkeyrequestrequiresvalidationdatainsecuretokenkey?language=objc)
    pub static AVContentKeyRequestRequiresValidationDataInSecureTokenKey: &'static NSString;
}

extern_class!(
    /// Subclasses of this type that are used from Swift must fulfill the requirements of a Sendable type.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avcontentkeyrequest?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct AVContentKeyRequest;
);

unsafe impl Send for AVContentKeyRequest {}

unsafe impl Sync for AVContentKeyRequest {}

extern_conformance!(
    unsafe impl NSObjectProtocol for AVContentKeyRequest {}
);

impl AVContentKeyRequest {
    extern_methods!(
        /// This describes the state of the AVContentKeyRequest, value is one of AVContentKeyRequestStatus.
        #[unsafe(method(status))]
        #[unsafe(method_family = none)]
        pub unsafe fn status(&self) -> AVContentKeyRequestStatus;

        /// If the receiver's status is AVContentKeyRequestStatusFailed, this describes the error that caused the failure.
        ///
        /// The value of this property is an NSError that describes what caused the content key request to fail. If the receiver's status is not AVContentKeyRequestStatusFailed, the value of this property is nil.
        #[unsafe(method(error))]
        #[unsafe(method_family = none)]
        pub unsafe fn error(&self) -> Option<Retained<NSError>>;

        /// Container- and protocol-specific identifier for the content key.
        ///
        /// In order to use a key with an HTTP Live Streaming AVURLAsset, the identifier must be an NSURL that matches a key URI in the Media Playlist.
        #[unsafe(method(identifier))]
        #[unsafe(method_family = none)]
        pub unsafe fn identifier(&self) -> Option<Retained<AnyObject>>;

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(initializationData))]
        #[unsafe(method_family = none)]
        pub unsafe fn initializationData(&self) -> Option<Retained<NSData>>;

        /// Additional information specified while initiaing key loading using -processContentKeyRequestWithIdentifier:initializationData:options:.
        #[unsafe(method(options))]
        #[unsafe(method_family = none)]
        pub unsafe fn options(&self) -> Retained<NSDictionary<NSString, AnyObject>>;

        /// When the value of this property is YES, you can use the method -persistableContentKeyFromKeyVendorResponse:options:error: to create a persistable content key from the content key response.
        ///
        /// The value of this property will be YES only when the receiver is provided to your AVContentKeySession delegate via the method -contentKeySession:didProvidePersistableContentKeyRequest:. If you have an AVContentKeyRequest for which the value of canProvidePersistableContentKey is NO, but you wish to obtain a persistable content key, send the AVContentKeyRequest the message -respondByRequestingPersistableContentKeyRequest.
        #[unsafe(method(canProvidePersistableContentKey))]
        #[unsafe(method_family = none)]
        pub unsafe fn canProvidePersistableContentKey(&self) -> bool;

        /// Specifies the requested content key.
        #[unsafe(method(contentKeySpecifier))]
        #[unsafe(method_family = none)]
        pub unsafe fn contentKeySpecifier(&self) -> Retained<AVContentKeySpecifier>;

        /// Represents an AVContentKey that results from an invocation of -processContentKeyResponse:.
        ///
        /// Before the receiver achieves the status AVContentKeyRequestReceivedResponse, the value of this property will be nil. Once that status has been achieved, the value of this property becomes a non-nil AVContentKey that can be provided to content key recipients that apply content keys manually to objects that require them, such as CMSampleBuffers, or to initiate renewal. A non-nil value does not indicate that the content key is valid; authorization failures may yet be possible.
        #[unsafe(method(contentKey))]
        #[unsafe(method_family = none)]
        pub unsafe fn contentKey(&self) -> Option<Retained<AVContentKey>>;

        /// The AVContentKeyRecipient which initiated this request, if any.
        ///
        /// The originatingRecipient is an AVFoundation object responsible for initiating an AVContentKeyRequest.
        /// For example, an AVURLAsset used for playback can trigger an AVContentKeyRequest.
        ///
        /// If an application triggers key loading directly, for example with
        /// -[AVContentKeySession processContentKeyRequestWithIdentifier:initializationData:options:],
        /// the value of originatingRecipient will be nil.
        ///
        /// The originatingRecipient of key requests from HLS interstitials will always be the corresponding
        /// interstitial AVURLAsset. To receive key requests for DRM-protected interstitial content, applications
        /// must ensure their AVContentKeySession is attached to these interstitial AVURLAssets.
        ///
        /// These interstitial AVURLAssets may be retrieved from the primary AVURLAsset via AVPlayerInterstitialEventMonitor.
        #[unsafe(method(originatingRecipient))]
        #[unsafe(method_family = none)]
        pub unsafe fn originatingRecipient(
            &self,
        ) -> Option<Retained<ProtocolObject<dyn AVContentKeyRecipient>>>;

        #[cfg(feature = "block2")]
        /// Obtains a content key request data for a specific combination of application and content.
        ///
        /// If option AVContentKeyRequestProtocolVersionsKey is not specified the default protocol version of 1 is assumed.
        ///
        /// - Parameter appIdentifier: An opaque identifier for the application. The value of this identifier depends on the particular system used to provide the content key.
        /// - Parameter contentIdentifier: An optional opaque identifier for the content. The value of this identifier depends on the particular system used to provide the content key.
        /// - Parameter options: Additional information necessary to obtain the key, or nil if none. See AVContentKeyRequest*Key below.
        /// - Parameter handler: Once the streaming content key request is prepared, this block will be called with the request data or an error describing the failure.
        ///
        /// # Safety
        ///
        /// - `options` generic should be of the correct type.
        /// - `handler` block must be sendable.
        #[unsafe(method(makeStreamingContentKeyRequestDataForApp:contentIdentifier:options:completionHandler:))]
        #[unsafe(method_family = none)]
        pub unsafe fn makeStreamingContentKeyRequestDataForApp_contentIdentifier_options_completionHandler(
            &self,
            app_identifier: &NSData,
            content_identifier: Option<&NSData>,
            options: Option<&NSDictionary<NSString, AnyObject>>,
            handler: &block2::DynBlock<dyn Fn(*mut NSData, *mut NSError)>,
        );

        /// Informs the receiver to process the specified content key response.
        ///
        /// After you receive an AVContentKeyRequest via -contentKeySession:didProvideContentKeyRequest: and after you invoke -[AVContentKeyRequest makeStreamingContentKeyRequestDataForApp:contentIdentifier:options:completionHandler:] on that request, you must obtain a response to the request in accordance with the protocol in use by the entity that controls the use of the media data. This is the method you use to provide the content key response to make protected content available for processing. If obtaining the content key response fails, use -processContentKeyResponseError:.
        ///
        /// - Parameter keyResponse: An instance of AVContentKeyResponse carrying a response to a content key request.
        #[unsafe(method(processContentKeyResponse:))]
        #[unsafe(method_family = none)]
        pub unsafe fn processContentKeyResponse(&self, key_response: &AVContentKeyResponse);

        /// Informs the receiver that obtaining a content key response has failed, resulting in failure handling.
        ///
        /// - Parameter error: An instance of NSError that describes the specific failure that occurred.
        #[unsafe(method(processContentKeyResponseError:))]
        #[unsafe(method_family = none)]
        pub unsafe fn processContentKeyResponseError(&self, error: &NSError);

        /// Informs the receiver to process a persistable content key request.
        ///
        /// When you receive an AVContentKeyRequest via -contentKeySession:didProvideContentKeyRequest: and you want the resulting key response to produce a key that can persist across multiple playback sessions, you must invoke -respondByRequestingPersistableContentKeyRequest on that AVContentKeyRequest in order to signal that you want to process an AVPersistableContentKeyRequest instead. If the underlying protocol supports persistable content keys, in response your delegate will receive an AVPersistableContentKeyRequest via -contentKeySession:didProvidePersistableContentKeyRequest:. NSInternalInconsistencyException will be raised, if you are attempting to create and use a persistable key but your AVContentKeySession delegate does not respond to contentKeySession:didProvidePersistableContentKeyRequest:.
        #[deprecated]
        #[unsafe(method(respondByRequestingPersistableContentKeyRequest))]
        #[unsafe(method_family = none)]
        pub unsafe fn respondByRequestingPersistableContentKeyRequest(&self);

        /// Informs the receiver to process a persistable content key request.
        ///
        /// When you receive an AVContentKeyRequest via -contentKeySession:didProvideContentKeyRequest: and you want the resulting key response to produce a key that can persist across multiple playback sessions, you must invoke -respondByRequestingPersistableContentKeyRequest on that AVContentKeyRequest in order to signal that you want to process an AVPersistableContentKeyRequest instead. If the underlying protocol supports persistable content keys, in response your delegate will receive an AVPersistableContentKeyRequest via -contentKeySession:didProvidePersistableContentKeyRequest:. NSInternalInconsistencyException will be raised, if you are attempting to create and use a persistable key but your AVContentKeySession delegate does not respond to contentKeySession:didProvidePersistableContentKeyRequest:.
        ///
        /// - Parameter outError: The error returned if a persistable content key request cannot be requested.
        ///
        /// - Returns: YES if sucessful. If NO, this request should be responded to via processContentKeyResponse: or processContentKeyResponseError:.
        #[unsafe(method(respondByRequestingPersistableContentKeyRequestAndReturnError:_))]
        #[unsafe(method_family = none)]
        pub unsafe fn respondByRequestingPersistableContentKeyRequestAndReturnError(
            &self,
        ) -> Result<(), Retained<NSError>>;
    );
}

/// Methods declared on superclass `NSObject`.
impl AVContentKeyRequest {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;
    );
}

extern_class!(
    /// Subclasses of this type that are used from Swift must fulfill the requirements of a Sendable type.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avpersistablecontentkeyrequest?language=objc)
    #[unsafe(super(AVContentKeyRequest, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct AVPersistableContentKeyRequest;
);

unsafe impl Send for AVPersistableContentKeyRequest {}

unsafe impl Sync for AVPersistableContentKeyRequest {}

extern_conformance!(
    unsafe impl NSObjectProtocol for AVPersistableContentKeyRequest {}
);

impl AVPersistableContentKeyRequest {
    extern_methods!(
        /// Obtains a persistable content key from a context.
        ///
        /// The data returned from this method may be used to immediately satisfy an AVPersistableContentKeyRequest, as well as any subsequent requests for the same key url using processContentKeyResponse: method. When you receive an AVContentKeyRequest via -contentKeySession:didProvideContentKeyRequest: and you want to use existing persistent content key from storage, you must invoke -respondByRequestingPersistableContentKeyRequest on that AVContentKeyRequest in order to signal that you want to process an AVPersistableContentKeyRequest instead. If the underlying protocol supports persistable content keys, in response your delegate will receive an AVPersistableContentKeyRequest via -contentKeySession:didProvidePersistableContentKeyRequest:. You can set the persistent key from storage on the AVPersistableContentKeyRequest using processContentKeyResponse:.
        ///
        /// - Parameter keyVendorResponse: The response returned from the key vendor as a result of a request generated from makeStreamingContentKeyRequestDataForApp:contentIdentifier:options:completionHandler:.
        /// - Parameter options: Additional information necessary to obtain the persistable content key, or nil if none.
        /// - Parameter outError: If obtaining the persistable content key fails, will be set to an instance of NSError describing the failure.
        ///
        /// - Returns: The persistable content key data that may be stored offline to answer future loading requests of the same content key.
        ///
        /// # Safety
        ///
        /// `options` generic should be of the correct type.
        #[unsafe(method(persistableContentKeyFromKeyVendorResponse:options:error:_))]
        #[unsafe(method_family = none)]
        pub unsafe fn persistableContentKeyFromKeyVendorResponse_options_error(
            &self,
            key_vendor_response: &NSData,
            options: Option<&NSDictionary<NSString, AnyObject>>,
        ) -> Result<Retained<NSData>, Retained<NSError>>;
    );
}

/// Methods declared on superclass `NSObject`.
impl AVPersistableContentKeyRequest {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;
    );
}

/// AVContentKeyRequestRenewal.
impl AVContentKeyRequest {
    extern_methods!(
        /// Indicates whether the receiver represents a request to renew previously provided response data that is expiring or has expired.
        #[unsafe(method(renewsExpiringResponseData))]
        #[unsafe(method_family = none)]
        pub unsafe fn renewsExpiringResponseData(&self) -> bool;
    );
}

extern_class!(
    /// AVContentKeyResponse is used to represent the data returned from the key server when requesting a key for decrypting content.
    ///
    /// Subclasses of this type that are used from Swift must fulfill the requirements of a Sendable type.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avcontentkeyresponse?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct AVContentKeyResponse;
);

unsafe impl Send for AVContentKeyResponse {}

unsafe impl Sync for AVContentKeyResponse {}

extern_conformance!(
    unsafe impl NSObjectProtocol for AVContentKeyResponse {}
);

impl AVContentKeyResponse {
    extern_methods!(
        /// Create an AVContentKeyResponse from the server response to a key request made when using FairPlayStreaming (FPS) as the method of key delivery.
        ///
        /// The object created by this method is typically used with an AVContentKeyRequest created by an AVContentKeySession using keySystem AVContentKeySystemFairPlayStreaming. It is passed to AVContentKeyRequest -processContentKeyResponse: in order to supply the decryptor with key data
        ///
        /// - Parameter keyResponseData: The response from the FairPlayStreaming key server
        ///
        /// - Returns: A new AVContentKeyResponse holding data from a FairPlayStreaming key server that is used to decrypt the content
        #[unsafe(method(contentKeyResponseWithFairPlayStreamingKeyResponseData:))]
        #[unsafe(method_family = none)]
        pub unsafe fn contentKeyResponseWithFairPlayStreamingKeyResponseData(
            key_response_data: &NSData,
        ) -> Retained<Self>;

        /// Create an AVContentKeyResponse from the key and IV when using AVContentKeySystemClearKey as the key system
        ///
        /// The object created by this method is typically used with an AVContentKeyRequest created by an AVContentKeySession using keySystem AVContentKeySystemClearKey. It is passed to AVContentKeyRequest -processContentKeyResponse: in order to supply the decryptor with key data.
        ///
        /// - Parameter keyData: The key used for decrypting content.
        /// - Parameter initializationVector: The initialization vector used for decrypting content, or nil if initialization vector is available in the media to be decrypted
        ///
        /// - Returns: A new AVContentKeyResponse holding Clear Key data.
        #[unsafe(method(contentKeyResponseWithClearKeyData:initializationVector:))]
        #[unsafe(method_family = none)]
        pub unsafe fn contentKeyResponseWithClearKeyData_initializationVector(
            key_data: &NSData,
            initialization_vector: Option<&NSData>,
        ) -> Retained<Self>;

        /// Create an AVContentKeyResponse from authorization token data when using AVContentKeySystemAuthorizationToken key system.
        ///
        /// The object created by this method is typically used with an AVContentKeyRequest created by an AVContentKeySession using keySystem AVContentKeySystemAuthorizationToken. It is passed to AVContentKeyRequest -processContentKeyResponse: in order to supply the authorization token data.
        ///
        /// - Parameter authorizationTokenData: Data blob containing the authorization token.
        ///
        /// - Returns: A new AVContentKeyResponse holding the authorization token data.
        #[unsafe(method(contentKeyResponseWithAuthorizationTokenData:))]
        #[unsafe(method_family = none)]
        pub unsafe fn contentKeyResponseWithAuthorizationTokenData(
            authorization_token_data: &NSData,
        ) -> Retained<Self>;
    );
}

/// Methods declared on superclass `NSObject`.
impl AVContentKeyResponse {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;
    );
}

extern "C" {
    /// Specifies the versions of the content protection protocol supported by the application as an NSArray of one or more NSNumber objects.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avcontentkeyrequestprotocolversionskey?language=objc)
    pub static AVContentKeyRequestProtocolVersionsKey: &'static NSString;
}

extern "C" {
    /// Value is an Boolean indicating whether the user's deviceID contained in the SPC blob during FairPlay key exchange should be randomized using a system generated seed
    ///
    /// Content providers use the SPC to distinguish the playback device from other devices, typically to enforce per-screen business rule limits.
    /// If the app developer, in cooperation with the content vendor, does not require to distinguish the playback device, they can further enhance user
    /// privacy by making this identifier non-constant, using this option.
    /// In either case, apps are not allowed to store or use the FairPlay anonymized device ID for anything other than to enforce business rule limits.
    /// App developers must use the AppTrackingTransparency framework to disclose to users if the application or the related FairPlay Key Server collect
    /// data about end users and share it with other companies for purposes of tracking across apps and web sites.
    /// When true, the system generates a random seed with which the device id will be randomized. To override the seed used; use this property in conjunction with AVContentKeyRequestRandomDeviceIdentifierSeedKey
    /// to provide a seed generated by your application.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avcontentkeyrequestshouldrandomizedeviceidentifierkey?language=objc)
    pub static AVContentKeyRequestShouldRandomizeDeviceIdentifierKey: &'static NSString;
}

extern "C" {
    /// Value is an NSData containing a 16-byte seed to randomize the user's deviceID contained in the SPC blob during FairPlay key exchange
    ///
    /// This property must be used in conjunction with AVContentKeyRequestShouldRandomizeDeviceIdentifierKey. Use a RND function to generate a 16 byte seed.
    /// This seed will be used to randomize the user's anonymized device ID if AVContentKeyRequestShouldRandomizeDeviceIdentifierKey is true.
    /// Content providers use the SPC to distinguish the playback device from other devices, typically to enforce per-screen business rule limits.
    /// If the app developer, in cooperation with the content vendor, does not require to distinguish the playback device, they can further enhance user
    /// privacy by making this identifier non-constant, using this option.
    /// In either case, apps are not allowed to store or use the FairPlay anonymized device ID for anything other than to enforce business rule limits.
    /// App developers must use the AppTrackingTransparency framework to disclose to users if the application or the related FairPlay Key Server collect
    /// data about end users and share it with other companies for purposes of tracking across apps and web sites.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avcontentkeyrequestrandomdeviceidentifierseedkey?language=objc)
    pub static AVContentKeyRequestRandomDeviceIdentifierSeedKey: &'static NSString;
}

extern_protocol!(
    /// Classes of objects that may require decryption keys for media data in order to enable processing, such as parsing or playback, conform to this protocol.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avcontentkeyrecipient?language=objc)
    pub unsafe trait AVContentKeyRecipient {
        /// Informs the receiver that an AVContentKey has been obtained as the result of an invocation of -[AVContentKeyRequest processContentKeyResponse:].
        ///
        /// The recipient may employ the AVContentKey for use with objects that support manual attachment of keys, such as CMSampleBuffer via an invocation of AVSampleBufferAttachContentKey.
        #[optional]
        #[unsafe(method(contentKeySession:didProvideContentKey:))]
        #[unsafe(method_family = none)]
        unsafe fn contentKeySession_didProvideContentKey(
            &self,
            content_key_session: &AVContentKeySession,
            content_key: &AVContentKey,
        );

        /// Indicates whether the receiver may require decryption keys for media data in order to enable processing.
        ///
        /// When the value of mayRequireContentKeysForMediaDataProcessing is YES, adding the receiver to an AVContentKeySession allows it to employ the session's already existing keys and also enables the handling of new key requests by the AVContentKeySession's delegate.
        #[unsafe(method(mayRequireContentKeysForMediaDataProcessing))]
        #[unsafe(method_family = none)]
        unsafe fn mayRequireContentKeysForMediaDataProcessing(&self) -> bool;
    }
);

extern_class!(
    /// Subclasses of this type that are used from Swift must fulfill the requirements of a Sendable type.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avcontentkeyspecifier?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct AVContentKeySpecifier;
);

unsafe impl Send for AVContentKeySpecifier {}

unsafe impl Sync for AVContentKeySpecifier {}

extern_conformance!(
    unsafe impl NSObjectProtocol for AVContentKeySpecifier {}
);

impl AVContentKeySpecifier {
    extern_methods!(
        /// Creates a new instance of AVContentKeySpecifier.
        ///
        /// This method returns an AVContentKeySpecifier instance that represents a content key in a specific content key system.
        ///
        /// - Parameter keySystem: A valid key system for content keys.
        /// - Parameter contentKeyIdentifier: Container and protocol-specific key identifier.
        /// - Parameter options: Additional information necessary to obtain the key, can be empty if none needed.
        ///
        /// - Returns: A new AVContentKeySpecifier
        ///
        /// # Safety
        ///
        /// - `content_key_identifier` should be of the correct type.
        /// - `options` generic should be of the correct type.
        #[unsafe(method(contentKeySpecifierForKeySystem:identifier:options:))]
        #[unsafe(method_family = none)]
        pub unsafe fn contentKeySpecifierForKeySystem_identifier_options(
            key_system: &AVContentKeySystem,
            content_key_identifier: &AnyObject,
            options: &NSDictionary<NSString, AnyObject>,
        ) -> Retained<Self>;

        /// Initialize an instance of AVContentKeySpecifier.
        ///
        /// This method returns an AVContentKeySpecifier instance that represents a content key in a specific content key system.
        ///
        /// - Parameter keySystem: A valid key system for content keys.
        /// - Parameter contentKeyIdentifier: Container and protocol-specific key identifier.
        /// - Parameter options: Additional information necessary to obtain the key, can be empty if none needed.
        ///
        /// - Returns: An instance of AVContentKeySpecifier
        ///
        /// # Safety
        ///
        /// - `content_key_identifier` should be of the correct type.
        /// - `options` generic should be of the correct type.
        #[unsafe(method(initForKeySystem:identifier:options:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initForKeySystem_identifier_options(
            this: Allocated<Self>,
            key_system: &AVContentKeySystem,
            content_key_identifier: &AnyObject,
            options: &NSDictionary<NSString, AnyObject>,
        ) -> Retained<Self>;

        /// A valid key system for content keys.
        #[unsafe(method(keySystem))]
        #[unsafe(method_family = none)]
        pub unsafe fn keySystem(&self) -> Retained<AVContentKeySystem>;

        /// Container and protocol-specific key identifier.
        #[unsafe(method(identifier))]
        #[unsafe(method_family = none)]
        pub unsafe fn identifier(&self) -> Retained<AnyObject>;

        /// Additional information necessary to obtain the key, can be empty if none needed.
        #[unsafe(method(options))]
        #[unsafe(method_family = none)]
        pub unsafe fn options(&self) -> Retained<NSDictionary<NSString, AnyObject>>;
    );
}

/// Methods declared on superclass `NSObject`.
impl AVContentKeySpecifier {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;
    );
}

/// The constants can be used to derive whether or not we have established sufficient protection to display content protected by this AVContentKey on some set of attached displays.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avexternalcontentprotectionstatus?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct AVExternalContentProtectionStatus(pub NSInteger);
impl AVExternalContentProtectionStatus {
    /// Indicates that the current protection status has not yet been discovered for the attached display(s).
    #[doc(alias = "AVExternalContentProtectionStatusPending")]
    pub const Pending: Self = Self(0);
    /// Indicates that sufficient protection with the attached display(s) has been established, content protected by the associated AVContentKey will be eligible to be displayed on the display(s).
    #[doc(alias = "AVExternalContentProtectionStatusSufficient")]
    pub const Sufficient: Self = Self(1);
    /// Indicates that sufficient protection with the attached display(s) has failed to be established, content protected by the associated AVContentKey will not be displayed.
    #[doc(alias = "AVExternalContentProtectionStatusInsufficient")]
    pub const Insufficient: Self = Self(2);
}

unsafe impl Encode for AVExternalContentProtectionStatus {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

unsafe impl RefEncode for AVExternalContentProtectionStatus {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

extern_class!(
    /// Subclasses of this type that are used from Swift must fulfill the requirements of a Sendable type.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avcontentkey?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct AVContentKey;
);

unsafe impl Send for AVContentKey {}

unsafe impl Sync for AVContentKey {}

extern_conformance!(
    unsafe impl NSObjectProtocol for AVContentKey {}
);

impl AVContentKey {
    extern_methods!(
        /// Specifies the content key.
        #[unsafe(method(contentKeySpecifier))]
        #[unsafe(method_family = none)]
        pub unsafe fn contentKeySpecifier(&self) -> Retained<AVContentKeySpecifier>;

        /// The external protection status for the AVContentKey based on all attached displays.
        ///
        /// This property is not key-value observable, instead the contentKeySession:externalProtectionStatusDidChangeForContentKey: delegate method should be used.
        #[unsafe(method(externalContentProtectionStatus))]
        #[unsafe(method_family = none)]
        pub unsafe fn externalContentProtectionStatus(&self) -> AVExternalContentProtectionStatus;

        /// Revokes the decryption context of the content key, and removes it from its associated AVContentKeySession.
        ///
        /// Once revoked, the AVContentKey is no longer eligible to be used with any media.
        /// If the key is required again, or if the key is requested to be loaded by the application, a new AVContentKeyRequest will be dispatched to the delegate.
        /// If there is media playback occurring which is dependent on the content key it will fail and may result in an error being generated with the playback halting.
        #[unsafe(method(revoke))]
        #[unsafe(method_family = none)]
        pub unsafe fn revoke(&self);
    );
}

/// Methods declared on superclass `NSObject`.
impl AVContentKey {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;
    );
}

/// Attaches an AVContentKey to a CMSampleBuffer for the purpose of content decryption.
///
/// The client is expected to attach AVContentKeys to CMSampleBuffers that have been created by the client for enqueueing with AVSampleBufferDisplayLayer or AVSampleBufferAudioRenderer, for which the AVContentKeySpecifier matches indications of suitability that are available to the client according to the content key system that's in use.
///
/// - Parameter sbuf: The sample buffer to which the content key is to be attached.
/// - Parameter contentKey: The content key to be attached.
/// - Parameter outError: If the result is NO and errorOut is non-NULL, the location referenced by errorOut receives an instance of NSError that describes the reason for failure to attach the content key.
///
/// # Safety
///
/// `out_error` must be a valid pointer or null.
#[cfg(feature = "objc2-core-media")]
#[inline]
pub unsafe extern "C-unwind" fn AVSampleBufferAttachContentKey(
    sbuf: &CMSampleBuffer,
    content_key: &AVContentKey,
    out_error: *mut *mut NSError,
) -> bool {
    extern "C-unwind" {
        fn AVSampleBufferAttachContentKey(
            sbuf: &CMSampleBuffer,
            content_key: &AVContentKey,
            out_error: *mut *mut NSError,
        ) -> Bool;
    }
    unsafe { AVSampleBufferAttachContentKey(sbuf, content_key, out_error) }.as_bool()
}