@24i/smartapps-bigscreen-rnv-build-engine 5.0.0-alpha.16 → 5.0.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/build-freshness.js +158 -0
- package/dist/.build-freshness.json +1010 -0
- package/dist/templates/platforms/firetv/project/README.md +196 -0
- package/dist/templates/platforms/firetv/project/amazoniap/build.gradle +41 -0
- package/dist/templates/platforms/firetv/project/amazoniap/consumer-rules.pro +0 -0
- package/dist/templates/platforms/firetv/project/amazoniap/proguard-rules.pro +21 -0
- package/dist/templates/platforms/firetv/project/amazoniap/src/main/kotlin/com/twentyfouri/bridgetv/amazoniap/AmazonIapService.kt +91 -0
- package/dist/templates/platforms/firetv/project/amazoniap/src/main/kotlin/com/twentyfouri/bridgetv/amazoniap/AmazonIapServiceFactory.kt +13 -0
- package/dist/templates/platforms/firetv/project/app/build.gradle +138 -0
- package/dist/templates/platforms/firetv/project/app/proguard-rules.pro +47 -0
- package/dist/templates/platforms/firetv/project/app/src/bigscreenAppstage/kotlin/com/twentyfouri/tvbridge/Flavor.kt +9 -0
- package/dist/templates/platforms/firetv/project/app/src/bigscreenAppstage/res/raw/configuration.json +8 -0
- package/dist/templates/platforms/firetv/project/app/src/main/AndroidManifest.xml +52 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/FlavorBase.kt +9 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/bridge/BridgeFromJavaScript.kt +421 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/bridge/BridgeToJavaScript.kt +121 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/configuration/BridgeConfig.kt +19 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/configuration/ConfigCallback.kt +6 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/configuration/ConfigProvider.kt +27 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/configuration/Drm.kt +10 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/configuration/UserAgent.kt +6 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/BaseApplication.kt +73 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/di/ActivityComponent.kt +13 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/di/ActivityModule.kt +14 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/di/ApplicationComponent.kt +23 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/di/ApplicationModule.kt +51 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/di/PerActivity.kt +26 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/utils/LocalStorage.kt +30 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/utils/LoggingDrmCallback.kt +38 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/utils/OverriddenHttpMediaDrmCallback.kt +134 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/utils/PlayerFactoryBitmovinCustomized.kt +19 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/utils/PlayerFactoryConfigured.kt +37 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/utils/PlayerFactoryExoPlayerCustomized.kt +106 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/utils/PlayerFactoryExoPlayerNpaw.kt +581 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/utils/PlayerFactoryVersion.kt +27 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/utils/SimpleActivityLifecycleCallback.kt +32 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/utils/SourceDrmOverridden.kt +91 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/sound/TouchPlayer.kt +86 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/client/BridgeWebView.kt +82 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/client/BridgeWebViewClient.kt +114 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/model/AnalyticsPlaybackInfo.kt +10 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/model/ContentModel.kt +14 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/model/DrmModel.kt +20 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/model/MediaEventType.kt +31 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/parser/PlaybackInfoParser.kt +10 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/parser/SourceParser.kt +89 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/parser/TrackJsonModelParser.kt +58 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/view/Mainview.kt +18 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/view/PlayerCache.kt +15 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/view/WebViewActivity.kt +252 -0
- package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/viewmodel/WebViewModel.kt +748 -0
- package/dist/templates/platforms/firetv/project/app/src/main/res/drawable/button_background_focus.xml +10 -0
- package/dist/templates/platforms/firetv/project/app/src/main/res/drawable/button_background_normal.xml +7 -0
- package/dist/templates/platforms/firetv/project/app/src/main/res/drawable/button_background_pressed.xml +7 -0
- package/dist/templates/platforms/firetv/project/app/src/main/res/drawable/button_focus.xml +8 -0
- package/dist/templates/platforms/firetv/project/app/src/main/res/layout/activity_web_view.xml +28 -0
- package/dist/templates/platforms/firetv/project/app/src/main/res/raw/click.ogg +0 -0
- package/dist/templates/platforms/firetv/project/app/src/main/res/values/styles.xml +12 -0
- package/dist/templates/platforms/firetv/project/app/src/main/res/xml/network_security_config.xml +4 -0
- package/dist/templates/platforms/firetv/project/build.gradle +45 -0
- package/dist/templates/platforms/firetv/project/common/build.gradle +41 -0
- package/dist/templates/platforms/firetv/project/common/consumer-rules.pro +0 -0
- package/dist/templates/platforms/firetv/project/common/proguard-rules.pro +21 -0
- package/dist/templates/platforms/firetv/project/common/src/main/kotlin/com/twentyfouri/tvbridge/common/Util.kt +11 -0
- package/dist/templates/platforms/firetv/project/common/src/main/kotlin/com/twentyfouri/tvbridge/common/iap/IapCallback.kt +11 -0
- package/dist/templates/platforms/firetv/project/common/src/main/kotlin/com/twentyfouri/tvbridge/common/iap/IapException.kt +14 -0
- package/dist/templates/platforms/firetv/project/common/src/main/kotlin/com/twentyfouri/tvbridge/common/iap/IapProduct.kt +16 -0
- package/dist/templates/platforms/firetv/project/common/src/main/kotlin/com/twentyfouri/tvbridge/common/iap/IapPurchase.kt +9 -0
- package/dist/templates/platforms/firetv/project/common/src/main/kotlin/com/twentyfouri/tvbridge/common/iap/IapService.kt +14 -0
- package/dist/templates/platforms/firetv/project/common/src/main/kotlin/com/twentyfouri/tvbridge/common/iap/IapServiceFactory.kt +8 -0
- package/dist/templates/platforms/firetv/project/common/src/main/kotlin/com/twentyfouri/tvbridge/common/iap/NullIapService.kt +32 -0
- package/dist/templates/platforms/firetv/project/googleiap/build.gradle +41 -0
- package/dist/templates/platforms/firetv/project/googleiap/consumer-rules.pro +0 -0
- package/dist/templates/platforms/firetv/project/googleiap/proguard-rules.pro +21 -0
- package/dist/templates/platforms/firetv/project/googleiap/src/main/kotlin/com/twentyfouri/tvbridge/googleiap/GoogleIapService.kt +6 -0
- package/dist/templates/platforms/firetv/project/googleiap/src/main/kotlin/com/twentyfouri/tvbridge/googleiap/GoogleIapServiceFactory.kt +13 -0
- package/dist/templates/platforms/firetv/project/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/dist/templates/platforms/firetv/project/gradle/wrapper/gradle-wrapper.properties +7 -0
- package/dist/templates/platforms/firetv/project/gradle.properties +4 -0
- package/dist/templates/platforms/firetv/project/gradlew +251 -0
- package/dist/templates/platforms/firetv/project/gradlew.bat +94 -0
- package/dist/templates/platforms/firetv/project/proguard-rules.pro +42 -0
- package/dist/templates/platforms/firetv/project/settings.gradle +4 -0
- package/index.js +2 -31
- package/package.json +7 -3
- package/project.json +96 -0
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
package com.twentyfouri.tvbridge.bridge
|
|
2
|
+
|
|
3
|
+
import android.media.AudioManager
|
|
4
|
+
import android.os.Handler
|
|
5
|
+
import android.os.Looper
|
|
6
|
+
import android.util.Log
|
|
7
|
+
import android.webkit.JavascriptInterface
|
|
8
|
+
import com.google.gson.JsonObject
|
|
9
|
+
import com.twentyfouri.player.base.TextTrack
|
|
10
|
+
import com.twentyfouri.player.base.TrackKind
|
|
11
|
+
import com.twentyfouri.tvbridge.webview.parser.PlaybackInfoParser.parse
|
|
12
|
+
import com.twentyfouri.tvbridge.webview.parser.SourceParser.stringToJson
|
|
13
|
+
import com.twentyfouri.tvbridge.webview.parser.TrackJsonModelParser.audioFromJson
|
|
14
|
+
import com.twentyfouri.tvbridge.webview.parser.TrackJsonModelParser.textFromJson
|
|
15
|
+
import com.twentyfouri.tvbridge.webview.parser.TrackJsonModelParser.toJson
|
|
16
|
+
import com.twentyfouri.tvbridge.webview.viewmodel.WebViewModel
|
|
17
|
+
import org.json.JSONObject
|
|
18
|
+
import java.text.SimpleDateFormat
|
|
19
|
+
import java.util.Arrays
|
|
20
|
+
import java.util.concurrent.CountDownLatch
|
|
21
|
+
import java.util.concurrent.TimeUnit
|
|
22
|
+
import kotlin.math.roundToInt
|
|
23
|
+
|
|
24
|
+
@SuppressWarnings("unused")
|
|
25
|
+
class BridgeFromJavaScript(
|
|
26
|
+
private val viewModel: WebViewModel
|
|
27
|
+
) {
|
|
28
|
+
private val handler = Handler(Looper.getMainLooper())
|
|
29
|
+
|
|
30
|
+
private fun launch(block: () -> Unit) {
|
|
31
|
+
handler.post(block)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private fun <T> runBlocking(logName: String? = null, timeoutMs: Long = 100L, block: () -> T): T? {
|
|
35
|
+
val latch = CountDownLatch(1)
|
|
36
|
+
var result: T? = null
|
|
37
|
+
handler.post {
|
|
38
|
+
result = block()
|
|
39
|
+
latch.countDown()
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
val success = latch.await(timeoutMs, TimeUnit.MILLISECONDS)
|
|
43
|
+
Log.v(LOG_TAG, if (success) "$logName $result" else "$logName TIMEOUT")
|
|
44
|
+
} catch (e: InterruptedException) {
|
|
45
|
+
result = null
|
|
46
|
+
Log.v(LOG_TAG, "$logName INTERRUPT")
|
|
47
|
+
}
|
|
48
|
+
return result
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/*
|
|
52
|
+
Bridge Android 2 JS to send messages
|
|
53
|
+
*/
|
|
54
|
+
@JavascriptInterface
|
|
55
|
+
fun bridgeJavaScriptToAndroid_Message(messageString: String) = launch {
|
|
56
|
+
Log.d(LOG_TAG, "bridgeJavaScriptToAndroid_Message - messageString: $messageString")
|
|
57
|
+
viewModel.showMessage(messageString)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/*
|
|
61
|
+
Bridge Js 2 Android to set the video to the player
|
|
62
|
+
*/
|
|
63
|
+
@JavascriptInterface
|
|
64
|
+
fun bridgeJavaScriptToAndroid_SetVideoPath(jsonString: String) = launch {
|
|
65
|
+
bridgeJavaScriptToAndroid_SetVideoPath(jsonString, null)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@JavascriptInterface
|
|
69
|
+
fun bridgeJavaScriptToAndroid_SetVideoPath(jsonString: String, mimeType: String?) = launch {
|
|
70
|
+
Log.d(LOG_TAG, "bridgeJavaScriptToAndroid_SetVideoPath = $jsonString")
|
|
71
|
+
try {
|
|
72
|
+
viewModel.stopPlayer()
|
|
73
|
+
stringToJson(jsonString)?.also { source ->
|
|
74
|
+
viewModel.setVideo(source)
|
|
75
|
+
}
|
|
76
|
+
} catch (e: Exception) {
|
|
77
|
+
Log.v(LOG_TAG, "bridgeJavaScriptToAndroid_SetVideoPathError - ${e.message}")
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/*
|
|
82
|
+
Bridge Js 2 Android to pause video object
|
|
83
|
+
*/
|
|
84
|
+
@JavascriptInterface
|
|
85
|
+
fun bridgeJavaScriptToAndroid_PlayVideo() = launch {
|
|
86
|
+
Log.d(LOG_TAG, "bridgeJavaScriptToAndroid_PlayVideo")
|
|
87
|
+
viewModel.requestAudioFocus()
|
|
88
|
+
viewModel.startPlayer()
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/*
|
|
92
|
+
Bridge Js 2 Android to pause video object
|
|
93
|
+
*/
|
|
94
|
+
@JavascriptInterface
|
|
95
|
+
fun bridgeJavaScriptToAndroid_PauseVideo() = launch {
|
|
96
|
+
Log.d(LOG_TAG, "bridgeJavaScriptToAndroid_PauseVideo")
|
|
97
|
+
viewModel.pausePlayer()
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@JavascriptInterface /*
|
|
102
|
+
Bridge JS 2 Android to stop and reset the player
|
|
103
|
+
*/
|
|
104
|
+
fun bridgeJavaScriptToAndroid_StopVideo() = launch {
|
|
105
|
+
Log.d(LOG_TAG, "bridgeJavaScriptToAndroid_StopVideo")
|
|
106
|
+
viewModel.abandonAudioFocus()
|
|
107
|
+
viewModel.stopPlayer()
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/*
|
|
111
|
+
Request the audio focus to discard background audio from other apps
|
|
112
|
+
*/
|
|
113
|
+
@JavascriptInterface
|
|
114
|
+
fun bridgeJavaScriptToAndroid_RequestAudioFocus(): Int = runBlocking("bridgeJavaScriptToAndroid_RequestAudioFocus") {
|
|
115
|
+
viewModel.requestAudioFocus()
|
|
116
|
+
} ?: AudioManager.AUDIOFOCUS_REQUEST_FAILED
|
|
117
|
+
|
|
118
|
+
/*
|
|
119
|
+
Request the audio focus to discard background audio from other apps
|
|
120
|
+
*/
|
|
121
|
+
@JavascriptInterface
|
|
122
|
+
fun bridgeJavaScriptToAndroid_AbandonAudioFocus() = launch {
|
|
123
|
+
viewModel.abandonAudioFocus()
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/*
|
|
127
|
+
Bridge JS 2 Android to get the current time
|
|
128
|
+
*/
|
|
129
|
+
@JavascriptInterface
|
|
130
|
+
fun bridgeJavaScriptToAndroid_GetCurrentTime(): Int = runBlocking("bridgeJavaScriptToAndroid_GetCurrentTime") {
|
|
131
|
+
viewModel.currentPosition.roundToInt() / 1000
|
|
132
|
+
} ?: 0
|
|
133
|
+
|
|
134
|
+
/*
|
|
135
|
+
Bridge JS 2 Android to get the current time
|
|
136
|
+
*/
|
|
137
|
+
@JavascriptInterface
|
|
138
|
+
fun bridgeJavaScriptToAndroid_GetCurrentTimeFloat(): Float = runBlocking("bridgeJavaScriptToAndroid_GetCurrentTimeFloat") {
|
|
139
|
+
viewModel.currentPosition.toFloat() / 1000
|
|
140
|
+
} ?: 0f
|
|
141
|
+
|
|
142
|
+
/*
|
|
143
|
+
Bridge JS 2 Android to get the live status
|
|
144
|
+
*/
|
|
145
|
+
@JavascriptInterface
|
|
146
|
+
fun bridgeJavaScriptToAndroid_IsLive(): Boolean = runBlocking("bridgeJavaScriptToAndroid_IsLive") {
|
|
147
|
+
viewModel.player?.live
|
|
148
|
+
} ?: false
|
|
149
|
+
|
|
150
|
+
/*
|
|
151
|
+
Bridge JS 2 Android to get the current time
|
|
152
|
+
Deprecated - use bridgeJavaScriptToAndroid_SetTrack("false") instead to disable
|
|
153
|
+
*/
|
|
154
|
+
@JavascriptInterface
|
|
155
|
+
@Deprecated("")
|
|
156
|
+
fun bridgeJavaScriptToAndroid_setNativeSubtitlesEnabled(subtitlesEnabled: Boolean) = launch {
|
|
157
|
+
Log.d(LOG_TAG, "bridgeJavaScriptToAndroid_setNativeSubtitlesEnabled($subtitlesEnabled)")
|
|
158
|
+
viewModel.setSubtitlesVisibility(subtitlesEnabled)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/*
|
|
162
|
+
Bridge JS 2 Android to get the total time
|
|
163
|
+
*/
|
|
164
|
+
@JavascriptInterface
|
|
165
|
+
fun bridgeJavaScriptToAndroid_GetTotalTime(): Float = runBlocking("bridgeJavaScriptToAndroid_GetTotalTime") {
|
|
166
|
+
viewModel.duration.toFloat() / 1000
|
|
167
|
+
} ?: 0f
|
|
168
|
+
|
|
169
|
+
/*
|
|
170
|
+
Bridge JS 2 Android to seek to the time in seconds
|
|
171
|
+
@param seconds time to seek in seconds
|
|
172
|
+
*/
|
|
173
|
+
@JavascriptInterface
|
|
174
|
+
fun bridgeJavaScriptToAndroid_SeekTo(seconds: Int) = launch {
|
|
175
|
+
Log.d(LOG_TAG, "bridgeJavaScriptToAndroid_SeekTo($seconds)")
|
|
176
|
+
viewModel.seekToPosition(1000 * seconds.toDouble())
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/*
|
|
180
|
+
Bridge JS 2 Android to get if the player is playing
|
|
181
|
+
*/
|
|
182
|
+
@JavascriptInterface
|
|
183
|
+
fun bridgeJavaScriptToAndroid_IsPlaying(): Boolean = runBlocking("bridgeJavaScriptToAndroid_IsPlaying") {
|
|
184
|
+
viewModel.isPlayerPlaying
|
|
185
|
+
} ?: false
|
|
186
|
+
|
|
187
|
+
/*
|
|
188
|
+
Bridge JS 2 Android to get if the player is presented to user
|
|
189
|
+
*/
|
|
190
|
+
@JavascriptInterface
|
|
191
|
+
fun bridgeJavaScriptToAndroid_IsInPlayer(): Boolean = runBlocking("bridgeJavaScriptToAndroid_IsInPlayer") {
|
|
192
|
+
viewModel.isInPlayer
|
|
193
|
+
} ?: false
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
/*
|
|
197
|
+
Bridge JS 2 Android to put the video in fullscreen mode
|
|
198
|
+
*/
|
|
199
|
+
@JavascriptInterface
|
|
200
|
+
fun bridgeJavaScriptToAndroid_FullScreenVideo() = launch {
|
|
201
|
+
Log.d(LOG_TAG, "bridgeJavaScriptToAndroid_FullScreenVideo")
|
|
202
|
+
viewModel.requestAudioFocus()
|
|
203
|
+
viewModel.enableFullScreen()
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
/*
|
|
208
|
+
Bridge JS 2 Android to set the video layout measures
|
|
209
|
+
@param width size in px
|
|
210
|
+
* @param height size in px
|
|
211
|
+
* @param left position in px
|
|
212
|
+
* @param top position in px
|
|
213
|
+
*/
|
|
214
|
+
@JavascriptInterface
|
|
215
|
+
fun bridgeJavaScriptToAndroid_SetVideoLayout(width: Int, height: Int, left: Int, top: Int) = launch {
|
|
216
|
+
Log.d(LOG_TAG, "bridgeJavaScriptToAndroid_PartialScreenVideo $width $height $left $top")
|
|
217
|
+
viewModel.disableFullScreen(width, height, left, top)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
/*
|
|
222
|
+
Bridge JS 2 Android to go back and reset the view
|
|
223
|
+
*/
|
|
224
|
+
@JavascriptInterface
|
|
225
|
+
fun bridgeJavaScriptToAndroid_Back() = launch {
|
|
226
|
+
Log.d(LOG_TAG, "bridgeJavaScriptToAndroid_Back")
|
|
227
|
+
viewModel.onBackPressed()
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/*
|
|
231
|
+
Set the new SUBTITLE track to the player
|
|
232
|
+
*/
|
|
233
|
+
@JavascriptInterface
|
|
234
|
+
fun bridgeJavaScriptToAndroid_SetTrack(trackJson: String) = launch {
|
|
235
|
+
if (trackJson == "") {
|
|
236
|
+
Log.d(LOG_TAG, "bridgeJavaScriptToAndroid_SetTrack empty => DEFAULT")
|
|
237
|
+
viewModel.setSubtitleTrack(null)
|
|
238
|
+
} else if (trackJson == "false") {
|
|
239
|
+
Log.d(LOG_TAG, "bridgeJavaScriptToAndroid_SetTrack false => DISABLED")
|
|
240
|
+
viewModel.setSubtitleTrack(TextTrack {
|
|
241
|
+
id = "text_off"
|
|
242
|
+
kind = TrackKind.EMPTY
|
|
243
|
+
})
|
|
244
|
+
} else {
|
|
245
|
+
Log.d(LOG_TAG, "bridgeJavaScriptToAndroid_SetTrack $trackJson")
|
|
246
|
+
viewModel.setSubtitleTrack(textFromJson(trackJson))
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/*
|
|
251
|
+
Set the new AUDIO track to the player
|
|
252
|
+
*/
|
|
253
|
+
@JavascriptInterface
|
|
254
|
+
fun bridgeJavaScriptToAndroid_SetAudioTrack(trackJson: String?) = launch {
|
|
255
|
+
Log.d(LOG_TAG, "bridgeJavaScriptToAndroid_SetAudioTrack ${trackJson ?: "(none)"}")
|
|
256
|
+
viewModel.setAudioTrack(audioFromJson(trackJson))
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/*
|
|
260
|
+
Returns current AUDIO track to the player
|
|
261
|
+
*/
|
|
262
|
+
@JavascriptInterface
|
|
263
|
+
fun bridgeJavaScriptToAndroid_getCurrentAudioTrack(): String? = runBlocking("bridgeJavaScriptToAndroid_getCurrentAudioTrack") {
|
|
264
|
+
viewModel.audioTrack?.let { toJson(it) }
|
|
265
|
+
} ?: DISABLED_AUDIO_TRACK
|
|
266
|
+
|
|
267
|
+
/*
|
|
268
|
+
Returns current AUDIO track to the player
|
|
269
|
+
*/
|
|
270
|
+
@JavascriptInterface
|
|
271
|
+
fun bridgeJavaScriptToAndroid_getCurrentSubtitleTrack(): String? = runBlocking("bridgeJavaScriptToAndroid_getCurrentSubtitleTrack") {
|
|
272
|
+
viewModel.subtitleTrack?.let { toJson(it) }
|
|
273
|
+
} ?: DISABLED_SUBTITLE_TRACK
|
|
274
|
+
|
|
275
|
+
/*
|
|
276
|
+
Set the cookies to localstorage
|
|
277
|
+
*/
|
|
278
|
+
@JavascriptInterface
|
|
279
|
+
fun bridgeJavaScriptToAndroid_SaveToLocalStorage(key: String?, value: String?) = launch {
|
|
280
|
+
Log.d(LOG_TAG, "bridgeJavaScriptToAndroid_SaveToLocalStorage")
|
|
281
|
+
viewModel.saveToLocalStorage(key, value)
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/*
|
|
285
|
+
clears the cookies from localstorage
|
|
286
|
+
*/
|
|
287
|
+
@JavascriptInterface
|
|
288
|
+
fun bridgeJavaScriptToAndroid_RemoveFromLocalStorage(key: String?) = launch {
|
|
289
|
+
Log.d(LOG_TAG, "bridgeJavaScriptToAndroid_RemoveFromLocalStorage")
|
|
290
|
+
viewModel.removeFromLocalStorage(key)
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/*
|
|
294
|
+
Gets the cookies
|
|
295
|
+
*/
|
|
296
|
+
@JavascriptInterface
|
|
297
|
+
fun bridgeJavaScriptToAndroid_GetFromLocalStorage(key: String?): String? = runBlocking("bridgeJavaScriptToAndroid_GetFromLocalStorage") {
|
|
298
|
+
Log.d(LOG_TAG, "bridgeJavaScriptToAndroid_GetFromLocalStorage")
|
|
299
|
+
viewModel.getFromLocalStorage(key)
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/***
|
|
303
|
+
* Bridge JS 2 Android to get the device information
|
|
304
|
+
*/
|
|
305
|
+
@JavascriptInterface
|
|
306
|
+
fun bridgeJavaScriptToAndroid_GetDeviceInfo(): String? = runBlocking("bridgeJavaScriptToAndroid_GetDeviceInfo", 300L) {
|
|
307
|
+
viewModel.detectDeviceInfo().toString()
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
@JavascriptInterface
|
|
311
|
+
fun bridgeJavaScriptToAndroid_GetMediaInfo(): String? = runBlocking("bridgeJavaScriptToAndroid_GetMediaInfo") {
|
|
312
|
+
viewModel.detectMediaInfo()?.toString()
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
@JavascriptInterface
|
|
316
|
+
fun bridgeJavaScriptToAndroid_SetPlaybackInfo(playbackInfo: String) = launch {
|
|
317
|
+
Log.d(LOG_TAG, "bridgeJavaScriptToAndroid_SetPlaybackInfo($playbackInfo)")
|
|
318
|
+
viewModel.setPlaybackInfo(parse(playbackInfo))
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
@JavascriptInterface
|
|
322
|
+
fun bridgeJavaScriptToAndroid_SignData(dataJson: String?): String? {
|
|
323
|
+
// Log.v(LOG_TAG, "bridgeJavaScriptToAndroid_SignData dataJson = " + dataJson);
|
|
324
|
+
return viewModel.signData(dataJson)
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
@JavascriptInterface
|
|
328
|
+
fun bridgeJavaScriptToAndroid_GetCurrentDateTime(): String? {
|
|
329
|
+
return SimpleDateFormat().toLocalizedPattern()
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
@JavascriptInterface
|
|
333
|
+
fun bridgeReceiptAmazonIAPValidation(sku: String?) {
|
|
334
|
+
bridgeReceiptIAPValidation(sku)
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
@JavascriptInterface
|
|
338
|
+
fun bridgeReceiptIAPValidation(sku: String?) = launch {
|
|
339
|
+
Log.d(LOG_TAG, "bridgeReceiptIAPValidation")
|
|
340
|
+
viewModel.launchIapPurchase(sku)
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/***
|
|
344
|
+
* Bridget JS 2 Android to check skus detail
|
|
345
|
+
*
|
|
346
|
+
* @param skus SKUS
|
|
347
|
+
*/
|
|
348
|
+
@JavascriptInterface
|
|
349
|
+
fun bridgeJavaScriptToAndroid_getInAppProductDetail(skus: Array<String>) {
|
|
350
|
+
Log.d(LOG_TAG, "bridgeJavaScriptToAndroid_getProductDetail SKU: " + Arrays.toString(skus))
|
|
351
|
+
viewModel.getIapProductDetails(skus.toList())
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/***
|
|
355
|
+
* Bridget JS 2 Android to validate a receipt
|
|
356
|
+
*/
|
|
357
|
+
@JavascriptInterface
|
|
358
|
+
fun bridgeReceiptAmazonIAPValidated(receiptId: String?) {
|
|
359
|
+
bridgeReceiptIAPValidated(receiptId)
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
@JavascriptInterface
|
|
363
|
+
fun bridgeReceiptIAPValidated(receipt: String?) {
|
|
364
|
+
Log.d(LOG_TAG, "bridgeReceiptIAPValidated receipt=$receipt")
|
|
365
|
+
val json = when {
|
|
366
|
+
receipt == null -> JSONObject()
|
|
367
|
+
receipt.startsWith('{') -> JSONObject(receipt)
|
|
368
|
+
else -> JSONObject().also {
|
|
369
|
+
it.put("receiptId", receipt) // Amazon
|
|
370
|
+
it.put("purchaseToken", receipt) // Google
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
viewModel.acknowledgeIapReceipt(json)
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/***
|
|
377
|
+
* Bridget JS 2 Android to get the old IAP receipts
|
|
378
|
+
*/
|
|
379
|
+
@JavascriptInterface
|
|
380
|
+
fun bridgeGetHistoricPurchases(): String? {
|
|
381
|
+
// I think this is not needed, but might come back in future
|
|
382
|
+
// return AmazonIAPListener.getInstance().getIAPManager().getHistoricPurchases().toString();
|
|
383
|
+
return ""
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/***
|
|
387
|
+
* Bridget JS 2 Android to get advertising id
|
|
388
|
+
*/
|
|
389
|
+
@JavascriptInterface
|
|
390
|
+
fun bridgeJavaScriptToAndroid_GetAdId() = viewModel.adId
|
|
391
|
+
|
|
392
|
+
/***
|
|
393
|
+
* Bridget JS 2 Android to get limit ad tracking info
|
|
394
|
+
*/
|
|
395
|
+
@JavascriptInterface
|
|
396
|
+
fun bridgeJavaScriptToAndroid_GetLimitAdTracking() = viewModel.limitAdTracking
|
|
397
|
+
|
|
398
|
+
/***
|
|
399
|
+
* Bridget JS 2 Android to get default OS language
|
|
400
|
+
*/
|
|
401
|
+
@JavascriptInterface
|
|
402
|
+
fun bridgeJavaScriptToAndroid_GetOsLanguage() = viewModel.language
|
|
403
|
+
|
|
404
|
+
/*
|
|
405
|
+
Bridge Android 2 JS to reload the player
|
|
406
|
+
*/
|
|
407
|
+
@JavascriptInterface
|
|
408
|
+
fun bridgeJavaScriptToAndroid_ReloadPlayer() {
|
|
409
|
+
viewModel.reloadPlayer()
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
companion object {
|
|
413
|
+
const val LOG_TAG = "JavaScriptBridge"
|
|
414
|
+
val DISABLED_AUDIO_TRACK = JsonObject().apply {
|
|
415
|
+
addProperty("type", "audio")
|
|
416
|
+
}.toString()
|
|
417
|
+
val DISABLED_SUBTITLE_TRACK = JsonObject().apply {
|
|
418
|
+
addProperty("type", "subtitles")
|
|
419
|
+
}.toString()
|
|
420
|
+
}
|
|
421
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
package com.twentyfouri.tvbridge.bridge
|
|
2
|
+
|
|
3
|
+
import android.util.Log
|
|
4
|
+
import com.twentyfouri.player.base.Ad
|
|
5
|
+
import com.twentyfouri.player.base.AdBreak
|
|
6
|
+
import com.twentyfouri.player.base.AudioTrack
|
|
7
|
+
import com.twentyfouri.player.base.DefaultSourceSerializer
|
|
8
|
+
import com.twentyfouri.player.base.TextTrack
|
|
9
|
+
import com.twentyfouri.player.base.TimelineEvent
|
|
10
|
+
import com.twentyfouri.tvbridge.bridge.BridgeFromJavaScript.Companion.LOG_TAG
|
|
11
|
+
import com.twentyfouri.tvbridge.configuration.BridgeConfig
|
|
12
|
+
import com.twentyfouri.tvbridge.webview.parser.TrackJsonModelParser.toJson
|
|
13
|
+
import org.json.JSONArray
|
|
14
|
+
import org.json.JSONObject
|
|
15
|
+
|
|
16
|
+
class BridgeToJavaScript(
|
|
17
|
+
config: BridgeConfig,
|
|
18
|
+
private val executeJavaScript: (String) -> Unit
|
|
19
|
+
) {
|
|
20
|
+
private val keyEventPrefix: String = config.keyEventPrefix
|
|
21
|
+
private val mediaEventPrefix: String = config.mediaEventPrefix
|
|
22
|
+
private val iapEventPrefix: String = config.iapEventPrefix
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Android 2 JavaScript keyevent Event. Dispatch key custom event to the page document element
|
|
26
|
+
*
|
|
27
|
+
* @param keyCode the keycode which is being sent from the Android code.
|
|
28
|
+
* @param keyEvent the keyevent which is being sent from the Android code.
|
|
29
|
+
*/
|
|
30
|
+
fun bridgeAndroidToJavaScript_KeyEvent(keyCode: Int, keyEvent: String) {
|
|
31
|
+
Log.d(LOG_TAG, "bridgeAndroidToJavaScript_KeyEvent keyCode = $keyCode, keyEvent = $keyEvent")
|
|
32
|
+
executeJavaScript("javascript:((function dispatchEvent(){var evt = document.createEvent('Events');evt.initEvent('$keyEventPrefix$keyEvent',true,true);evt.keyCode=$keyCode;evt.which=$keyCode;(document.activeElement?document.activeElement:document).dispatchEvent(evt);})())")
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Android 2 JavaScript media Event. Dispatch key custom event to the page document element
|
|
37
|
+
*
|
|
38
|
+
* @param mediaEvent the mediaEvent which is being sent from the Android code.
|
|
39
|
+
*/
|
|
40
|
+
fun bridgeAndroidToJavaScript_MediaEvent(mediaEvent: String) {
|
|
41
|
+
Log.d(LOG_TAG, "bridgeAndroidToJavaScript_MediaEvent $mediaEventPrefix$mediaEvent")
|
|
42
|
+
executeJavaScript("javascript:((function dispatchEvent(){var evt = document.createEvent('Events');evt.initEvent('$mediaEventPrefix$mediaEvent',true,true);document.dispatchEvent(evt);})())")
|
|
43
|
+
}
|
|
44
|
+
fun bridgeAndroidToJavaScript_ErrorEvent(mediaEvent: String, message: String?) {
|
|
45
|
+
Log.d(LOG_TAG, "bridgeAndroidToJavaScript_ErrorEvent $mediaEventPrefix$mediaEvent: $message")
|
|
46
|
+
executeJavaScript("javascript:((function dispatchEvent(){var evt = document.createEvent('Events');evt.initEvent('$mediaEventPrefix$mediaEvent',true,true);evt.name='PlayerError';evt.message='$message';document.dispatchEvent(evt);})())")
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Android 2 JavaScript media Event. Dispatch key custom event to the page document element
|
|
53
|
+
*
|
|
54
|
+
* @param mediaEvent the mediaEvent
|
|
55
|
+
* @param tracks tracks from the players stream.
|
|
56
|
+
*/
|
|
57
|
+
fun bridgeAndroidToJavaScript_MediaTrackEvent(
|
|
58
|
+
mediaEvent: String,
|
|
59
|
+
audioTracks: List<AudioTrack>,
|
|
60
|
+
textTracks: List<TextTrack>
|
|
61
|
+
) {
|
|
62
|
+
val tracksJson = toJson(audioTracks, textTracks)
|
|
63
|
+
Log.d(LOG_TAG, "bridgeAndroidToJavaScript_MediaTrackEvent $tracksJson")
|
|
64
|
+
val mediaEventString = "javascript:((function dispatchEvent(){var evt = document.createEvent('Events');evt.initEvent('$mediaEventPrefix$mediaEvent',true,true);evt.tracks='$tracksJson';document.dispatchEvent(evt);})())"
|
|
65
|
+
Log.v(LOG_TAG, "bridgeAndroidToJavaScript_MediaTrackEvent $mediaEventString")
|
|
66
|
+
executeJavaScript(mediaEventString)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
fun bridgeAndroidToJavaScript_MediaAdEvent(
|
|
70
|
+
mediaEvent: String,
|
|
71
|
+
adBreak: AdBreak?,
|
|
72
|
+
ad: Ad?
|
|
73
|
+
) {
|
|
74
|
+
val serializer = DefaultSourceSerializer()
|
|
75
|
+
val adBreakJson = adBreak?.let { serializer.toPersistentMap(it).toString() } ?: ""
|
|
76
|
+
val adJson = ad?.let { serializer.toPersistentMap(it).toString() } ?: ""
|
|
77
|
+
|
|
78
|
+
val mediaEventString = "javascript:((function dispatchEvent(){var evt = document.createEvent('Events');evt.initEvent('$mediaEventPrefix$mediaEvent',true,true);evt.adbreak='$adBreakJson';evt.ad='$adJson';document.dispatchEvent(evt);})())"
|
|
79
|
+
Log.v(LOG_TAG, "bridgeAndroidToJavaScript_MediaAdEvent $mediaEventString")
|
|
80
|
+
executeJavaScript(mediaEventString)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
fun bridgeAndroidToJavaScript_MediaAdBreaksEvent(
|
|
84
|
+
mediaEvent: String,
|
|
85
|
+
timeline: List<TimelineEvent>
|
|
86
|
+
) {
|
|
87
|
+
val serializer = DefaultSourceSerializer()
|
|
88
|
+
val adsJson = JSONArray(timeline.map { serializer.toPersistentMap(it) }).toString()
|
|
89
|
+
|
|
90
|
+
val mediaEventString = "javascript:((function dispatchEvent(){var evt = document.createEvent('Events');evt.initEvent('$mediaEventPrefix$mediaEvent',true,true);evt.ads='$adsJson';document.dispatchEvent(evt);})())"
|
|
91
|
+
Log.v(LOG_TAG, "bridgeAndroidToJavaScript_MediaAdEvent $mediaEventString")
|
|
92
|
+
executeJavaScript(mediaEventString)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
fun bridgeAndroidToJavaScript_IAPValidationError(message: String) {
|
|
96
|
+
Log.d(LOG_TAG, "bridgeAndroidToJavaScript_IAPValidationError")
|
|
97
|
+
executeJavaScript("javascript:((function dispatchEvent(){var evt = document.createEvent('Events');evt.initEvent('${iapEventPrefix}iapError',true,true);evt.message='$message';document.dispatchEvent(evt);})())")
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
fun bridgeAndroidToJavaScript_IAPValidationSuccess(
|
|
101
|
+
userId: String,
|
|
102
|
+
receipt: JSONObject,
|
|
103
|
+
sku: String
|
|
104
|
+
) {
|
|
105
|
+
Log.d(
|
|
106
|
+
LOG_TAG,
|
|
107
|
+
"bridgeAndroidToJavaScript_IAPValidationSuccess sku=$sku receipt=$receipt"
|
|
108
|
+
)
|
|
109
|
+
executeJavaScript("javascript:((function dispatchEvent(){var evt = document.createEvent('Events');evt.initEvent('${iapEventPrefix}iapSuccess',true,true);evt.userId='$userId';evt.receipt='$receipt';evt.sku='$sku';document.dispatchEvent(evt);})())")
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
fun bridgeIAPGetProductDataSuccess(okSkus: String, badSkus: String) {
|
|
113
|
+
Log.d(LOG_TAG, "bridgeIAPGetProductDataSuccess ok=$okSkus bad=$badSkus")
|
|
114
|
+
executeJavaScript("javascript:((function dispatchEvent(){var evt = document.createEvent('Events');evt.initEvent('${iapEventPrefix}onInAppProductDetailSuccess',true,true);evt.okSkus=$okSkus;evt.badSkus=$badSkus;document.dispatchEvent(evt);})())")
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
fun bridgeIAPGetProductDataFail(reason: String) {
|
|
118
|
+
Log.d(LOG_TAG, "bridgeIAPGetProductDataFail")
|
|
119
|
+
executeJavaScript("javascript:((function dispatchEvent(){var evt = document.createEvent('Events');evt.initEvent('${iapEventPrefix}onInAppProductDetailError',true,true);evt.message='$reason';document.dispatchEvent(evt);})())")
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
package com.twentyfouri.tvbridge.configuration
|
|
2
|
+
|
|
3
|
+
import com.twentyfouri.tvbridge.BuildConfig
|
|
4
|
+
|
|
5
|
+
class BridgeConfig {
|
|
6
|
+
var baseUrl: String = BuildConfig.APP_URL
|
|
7
|
+
var userAgent: UserAgent = UserAgent()
|
|
8
|
+
var drm: Drm = Drm()
|
|
9
|
+
var isEnabledTouchSound: Boolean = false
|
|
10
|
+
var playerAppName: String? = null
|
|
11
|
+
var keyEventPrefix: String = ""
|
|
12
|
+
var mediaEventPrefix: String = ""
|
|
13
|
+
var iapEventPrefix: String = ""
|
|
14
|
+
var customizableUrl: Boolean = BuildConfig.DEBUG
|
|
15
|
+
var startWithHighVideoQuality: Boolean = false
|
|
16
|
+
var bitmovinLicense: String = BuildConfig.BITMOVIN_LICENSE
|
|
17
|
+
var bitmovinAnalytics: String = BuildConfig.BITMOVIN_ANALYTICS
|
|
18
|
+
var npawAccount: String = BuildConfig.NPAW_ACCOUNT_CODE
|
|
19
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
package com.twentyfouri.tvbridge.configuration
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import com.google.gson.Gson
|
|
5
|
+
import java.io.InputStreamReader
|
|
6
|
+
|
|
7
|
+
object ConfigProvider {
|
|
8
|
+
fun load(context: Context, callback: ConfigCallback) {
|
|
9
|
+
val resId = context.resources.getIdentifier("configuration", "raw", context.packageName)
|
|
10
|
+
if (resId == 0) {
|
|
11
|
+
callback.onConfigError("Configuration is missing @raw/configuration")
|
|
12
|
+
return
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
val inputStream = context.resources.openRawResource(resId)
|
|
16
|
+
try {
|
|
17
|
+
val config = Gson().fromJson(InputStreamReader(inputStream), BridgeConfig::class.java)
|
|
18
|
+
callback.onConfigLoaded(config)
|
|
19
|
+
} finally {
|
|
20
|
+
inputStream.close()
|
|
21
|
+
}
|
|
22
|
+
} catch (e: Exception) {
|
|
23
|
+
e.printStackTrace()
|
|
24
|
+
callback.onConfigError("Failed to read the input stream")
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
package com.twentyfouri.tvbridge.global
|
|
2
|
+
|
|
3
|
+
import android.app.Activity
|
|
4
|
+
import android.app.Application
|
|
5
|
+
import android.os.Bundle
|
|
6
|
+
import android.util.Log
|
|
7
|
+
import android.view.View
|
|
8
|
+
import com.twentyfouri.tvbridge.configuration.BridgeConfig
|
|
9
|
+
import com.twentyfouri.tvbridge.configuration.ConfigCallback
|
|
10
|
+
import com.twentyfouri.tvbridge.configuration.ConfigProvider.load
|
|
11
|
+
import com.twentyfouri.tvbridge.global.di.ApplicationComponent
|
|
12
|
+
import com.twentyfouri.tvbridge.global.di.ApplicationModule
|
|
13
|
+
import com.twentyfouri.tvbridge.global.di.DaggerApplicationComponent
|
|
14
|
+
import com.twentyfouri.tvbridge.global.utils.SimpleActivityLifecycleCallback
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Created by David on 30/12/15.
|
|
18
|
+
*/
|
|
19
|
+
class BaseApplication : Application() {
|
|
20
|
+
|
|
21
|
+
private var bridgeConfig: BridgeConfig = BridgeConfig()
|
|
22
|
+
|
|
23
|
+
var component: ApplicationComponent? = null
|
|
24
|
+
get() {
|
|
25
|
+
if (field == null) {
|
|
26
|
+
field = DaggerApplicationComponent.builder()
|
|
27
|
+
.applicationModule(ApplicationModule(this, bridgeConfig))
|
|
28
|
+
.build()
|
|
29
|
+
}
|
|
30
|
+
return field
|
|
31
|
+
}
|
|
32
|
+
private set
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
override fun onCreate() {
|
|
36
|
+
super.onCreate()
|
|
37
|
+
|
|
38
|
+
// No projects have google_services.json, so we cannot actually enable Crashlytics
|
|
39
|
+
// FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(true);
|
|
40
|
+
registerActivityLifecycleCallbacks(object : SimpleActivityLifecycleCallback() {
|
|
41
|
+
override fun onActivityCreated(activity: Activity, bundle: Bundle?) {
|
|
42
|
+
val decorView = activity.window.decorView
|
|
43
|
+
// Hide the status bar.
|
|
44
|
+
decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
|
|
45
|
+
// Remember that you should never show the action bar if the
|
|
46
|
+
// status bar is hidden, so hide that too if necessary.
|
|
47
|
+
hideSystemUI(decorView)
|
|
48
|
+
activity.actionBar?.hide()
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
load(this, object : ConfigCallback {
|
|
52
|
+
override fun onConfigLoaded(config: BridgeConfig?) {
|
|
53
|
+
bridgeConfig = config ?: BridgeConfig()
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
override fun onConfigError(error: String?) {
|
|
57
|
+
Log.e("BaseApplication", error ?: return)
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private fun hideSystemUI(decorView: View) {
|
|
63
|
+
// Set the IMMERSIVE flag.
|
|
64
|
+
// Set the content to appear under the system bars so that the content
|
|
65
|
+
// doesn't resize when the system bars hide and show.
|
|
66
|
+
decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
|
67
|
+
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
|
68
|
+
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
|
69
|
+
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
|
|
70
|
+
or View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
|
|
71
|
+
or View.SYSTEM_UI_FLAG_IMMERSIVE)
|
|
72
|
+
}
|
|
73
|
+
}
|