react-native-theoplayer 2.12.1 → 2.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.1.0/)
|
|
6
6
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.13.0] - 23-09-15
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Fixed an issue where setting a new source on iOS, during DRM handling, would crash the application due to unsafe array access by different threads.
|
|
13
|
+
|
|
8
14
|
## [2.12.1] - 23-09-14
|
|
9
15
|
|
|
10
16
|
### Fixed
|
|
@@ -19,16 +19,15 @@ let BRIDGE_REQUEST_TIMEOUT = 10.0
|
|
|
19
19
|
@objc(THEOplayerRCTContentProtectionAPI)
|
|
20
20
|
class THEOplayerRCTContentProtectionAPI: RCTEventEmitter {
|
|
21
21
|
|
|
22
|
-
private var buildIntegrationCompletions:
|
|
23
|
-
private var certificateRequestCompletions:
|
|
24
|
-
private var certificateResponseCompletions:
|
|
25
|
-
private var licenseRequestCompletions:
|
|
26
|
-
private var licenseResponseCompletions:
|
|
27
|
-
private var extractFairplayCompletions:
|
|
28
|
-
private var requestTimers:
|
|
29
|
-
private var requestIntegrationIds:
|
|
30
|
-
private var requestKeySystemIds:
|
|
31
|
-
|
|
22
|
+
private var buildIntegrationCompletions: THEOplayerRCTSafeMap<String, (Bool) -> Void> = THEOplayerRCTSafeMap<String, (Bool) -> Void>() // [requestId : completion]
|
|
23
|
+
private var certificateRequestCompletions: THEOplayerRCTSafeMap<String, (Data?, Error?) -> Void> = THEOplayerRCTSafeMap<String, (Data?, Error?) -> Void>() // [requestId : completion]
|
|
24
|
+
private var certificateResponseCompletions: THEOplayerRCTSafeMap<String, (Data?, Error?) -> Void> = THEOplayerRCTSafeMap<String, (Data?, Error?) -> Void>() // [requestId : completion]
|
|
25
|
+
private var licenseRequestCompletions: THEOplayerRCTSafeMap<String, (Data?, Error?) -> Void> = THEOplayerRCTSafeMap<String, (Data?, Error?) -> Void>() // [requestId : completion]
|
|
26
|
+
private var licenseResponseCompletions: THEOplayerRCTSafeMap<String, (Data?, Error?) -> Void> = THEOplayerRCTSafeMap<String, (Data?, Error?) -> Void>() // [requestId : completion]
|
|
27
|
+
private var extractFairplayCompletions: THEOplayerRCTSafeMap<String, (String, Error?) -> Void> = THEOplayerRCTSafeMap<String, (String, Error?) -> Void>() // [requestId : completion]
|
|
28
|
+
private var requestTimers: THEOplayerRCTSafeMap<String, Timer> = THEOplayerRCTSafeMap<String, Timer>() // [requestId : Timer]
|
|
29
|
+
private var requestIntegrationIds: THEOplayerRCTSafeMap<String, String> = THEOplayerRCTSafeMap<String, String>() // [requestId : integrationId]
|
|
30
|
+
private var requestKeySystemIds: THEOplayerRCTSafeMap<String, String> = THEOplayerRCTSafeMap<String, String>() // [requestId : keySystemId]
|
|
32
31
|
|
|
33
32
|
override static func moduleName() -> String! {
|
|
34
33
|
return "ContentProtectionModule"
|
|
@@ -51,7 +50,7 @@ class THEOplayerRCTContentProtectionAPI: RCTEventEmitter {
|
|
|
51
50
|
private func invalidateRequestWithId(_ requestId: String) {
|
|
52
51
|
if let timer = self.requestTimers[requestId] {
|
|
53
52
|
timer.invalidate()
|
|
54
|
-
self.requestTimers.removeValue(forKey: requestId)
|
|
53
|
+
_ = self.requestTimers.removeValue(forKey: requestId)
|
|
55
54
|
}
|
|
56
55
|
}
|
|
57
56
|
|
|
@@ -68,7 +67,7 @@ class THEOplayerRCTContentProtectionAPI: RCTEventEmitter {
|
|
|
68
67
|
self.requestTimers[requestId] = Timer.scheduledTimer(withTimeInterval: BRIDGE_REQUEST_TIMEOUT, repeats: false, block: { t in
|
|
69
68
|
if DEBUG_CONTENT_PROTECTION_API { print(CPI_TAG, "Build timeout reached: removing completion for request with Id \(requestId)") }
|
|
70
69
|
self.invalidateRequestWithId(requestId)
|
|
71
|
-
self.buildIntegrationCompletions.removeValue(forKey: requestId)
|
|
70
|
+
_ = self.buildIntegrationCompletions.removeValue(forKey: requestId)
|
|
72
71
|
})
|
|
73
72
|
}
|
|
74
73
|
|
|
@@ -86,9 +85,9 @@ class THEOplayerRCTContentProtectionAPI: RCTEventEmitter {
|
|
|
86
85
|
self.requestTimers[requestId] = Timer.scheduledTimer(withTimeInterval: BRIDGE_REQUEST_TIMEOUT, repeats: false, block: { t in
|
|
87
86
|
if DEBUG_CONTENT_PROTECTION_API { print(CPI_TAG, "onCertificateRequest timeout reached: removing completion for request with Id \(requestId)") }
|
|
88
87
|
self.invalidateRequestWithId(requestId)
|
|
89
|
-
self.requestIntegrationIds.removeValue(forKey: requestId)
|
|
90
|
-
self.requestKeySystemIds.removeValue(forKey: requestId)
|
|
91
|
-
self.certificateRequestCompletions.removeValue(forKey: requestId)
|
|
88
|
+
_ = self.requestIntegrationIds.removeValue(forKey: requestId)
|
|
89
|
+
_ = self.requestKeySystemIds.removeValue(forKey: requestId)
|
|
90
|
+
_ = self.certificateRequestCompletions.removeValue(forKey: requestId)
|
|
92
91
|
})
|
|
93
92
|
}
|
|
94
93
|
|
|
@@ -104,7 +103,7 @@ class THEOplayerRCTContentProtectionAPI: RCTEventEmitter {
|
|
|
104
103
|
self.requestTimers[requestId] = Timer.scheduledTimer(withTimeInterval: BRIDGE_REQUEST_TIMEOUT, repeats: false, block: { t in
|
|
105
104
|
if DEBUG_CONTENT_PROTECTION_API { print(CPI_TAG, "onCertificateResponse timeout reached: removing completion for request with Id \(requestId)") }
|
|
106
105
|
self.invalidateRequestWithId(requestId)
|
|
107
|
-
self.certificateResponseCompletions.removeValue(forKey: requestId)
|
|
106
|
+
_ = self.certificateResponseCompletions.removeValue(forKey: requestId)
|
|
108
107
|
})
|
|
109
108
|
}
|
|
110
109
|
|
|
@@ -122,9 +121,9 @@ class THEOplayerRCTContentProtectionAPI: RCTEventEmitter {
|
|
|
122
121
|
self.requestTimers[requestId] = Timer.scheduledTimer(withTimeInterval: BRIDGE_REQUEST_TIMEOUT, repeats: false, block: { t in
|
|
123
122
|
if DEBUG_CONTENT_PROTECTION_API { print(CPI_TAG, "onLicenseRequest timeout reached: removing completion for request with Id \(requestId)") }
|
|
124
123
|
self.invalidateRequestWithId(requestId)
|
|
125
|
-
self.requestIntegrationIds.removeValue(forKey: requestId)
|
|
126
|
-
self.requestKeySystemIds.removeValue(forKey: requestId)
|
|
127
|
-
self.licenseRequestCompletions.removeValue(forKey: requestId)
|
|
124
|
+
_ = self.requestIntegrationIds.removeValue(forKey: requestId)
|
|
125
|
+
_ = self.requestKeySystemIds.removeValue(forKey: requestId)
|
|
126
|
+
_ = self.licenseRequestCompletions.removeValue(forKey: requestId)
|
|
128
127
|
})
|
|
129
128
|
}
|
|
130
129
|
|
|
@@ -140,7 +139,7 @@ class THEOplayerRCTContentProtectionAPI: RCTEventEmitter {
|
|
|
140
139
|
self.requestTimers[requestId] = Timer.scheduledTimer(withTimeInterval: BRIDGE_REQUEST_TIMEOUT, repeats: false, block: { t in
|
|
141
140
|
if DEBUG_CONTENT_PROTECTION_API { print(CPI_TAG, "onLicenseResponse timeout reached: removing completion for request with Id \(requestId)") }
|
|
142
141
|
self.invalidateRequestWithId(requestId)
|
|
143
|
-
self.licenseResponseCompletions.removeValue(forKey: requestId)
|
|
142
|
+
_ = self.licenseResponseCompletions.removeValue(forKey: requestId)
|
|
144
143
|
})
|
|
145
144
|
}
|
|
146
145
|
|
|
@@ -157,7 +156,7 @@ class THEOplayerRCTContentProtectionAPI: RCTEventEmitter {
|
|
|
157
156
|
self.requestTimers[requestId] = Timer.scheduledTimer(withTimeInterval: BRIDGE_REQUEST_TIMEOUT, repeats: false, block: { t in
|
|
158
157
|
if DEBUG_CONTENT_PROTECTION_API { print(CPI_TAG, "Fairplay contentId extraction timeout reached: removing completion for request with Id \(requestId)") }
|
|
159
158
|
self.invalidateRequestWithId(requestId)
|
|
160
|
-
self.extractFairplayCompletions.removeValue(forKey: requestId)
|
|
159
|
+
_ = self.extractFairplayCompletions.removeValue(forKey: requestId)
|
|
161
160
|
})
|
|
162
161
|
}
|
|
163
162
|
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
//
|
|
2
|
+
// THEOplayerRCTSafeMap.swift
|
|
3
|
+
// Theoplayer
|
|
4
|
+
//
|
|
5
|
+
|
|
6
|
+
import Foundation
|
|
7
|
+
|
|
8
|
+
class THEOplayerRCTSafeMap<K: Hashable,V>: Collection {
|
|
9
|
+
private var unsafeMap: [K: V]
|
|
10
|
+
private let concurrentQueue = DispatchQueue(label: "Safe Queue", attributes: .concurrent)
|
|
11
|
+
|
|
12
|
+
var startIndex: Dictionary<K, V>.Index {
|
|
13
|
+
self.concurrentQueue.sync {
|
|
14
|
+
return self.unsafeMap.startIndex
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
var endIndex: Dictionary<K, V>.Index {
|
|
19
|
+
self.concurrentQueue.sync {
|
|
20
|
+
return self.unsafeMap.endIndex
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
init(dict: [K: V] = [K: V]()) {
|
|
25
|
+
self.unsafeMap = dict
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
func index(after i: Dictionary<K, V>.Index) -> Dictionary<K, V>.Index {
|
|
29
|
+
self.concurrentQueue.sync {
|
|
30
|
+
return self.unsafeMap.index(after: i)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
subscript(key: K) -> V? {
|
|
35
|
+
set(newValue) {
|
|
36
|
+
self.concurrentQueue.sync(flags: .barrier) {[weak self] in
|
|
37
|
+
self?.unsafeMap[key] = newValue
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
get {
|
|
41
|
+
self.concurrentQueue.sync {
|
|
42
|
+
return self.unsafeMap[key]
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
subscript(index: Dictionary<K, V>.Index) -> Dictionary<K, V>.Element {
|
|
48
|
+
self.concurrentQueue.sync {
|
|
49
|
+
return self.unsafeMap[index]
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
func removeValue(forKey key: K) -> V? {
|
|
54
|
+
self.concurrentQueue.sync(flags: .barrier) {[weak self] in
|
|
55
|
+
return self?.unsafeMap.removeValue(forKey: key)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
func removeAll() {
|
|
60
|
+
self.concurrentQueue.sync(flags: .barrier) {[weak self] in
|
|
61
|
+
self?.unsafeMap.removeAll()
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|