@takeoffmedia/react-native-penthera 0.1.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.
Files changed (96) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +203 -0
  3. package/android/build.gradle +105 -0
  4. package/android/gradle.properties +5 -0
  5. package/android/src/main/AndroidManifest.xml +51 -0
  6. package/android/src/main/java/com/takeoffmediareactnativepenthera/AssetQueueObserver.kt +148 -0
  7. package/android/src/main/java/com/takeoffmediareactnativepenthera/EventEmitter.kt +53 -0
  8. package/android/src/main/java/com/takeoffmediareactnativepenthera/PentheraModule.kt +104 -0
  9. package/android/src/main/java/com/takeoffmediareactnativepenthera/PentheraPackage.kt +16 -0
  10. package/android/src/main/java/com/takeoffmediareactnativepenthera/YourPlayerActivity.kt +14 -0
  11. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/DemoLicenseManager.kt +50 -0
  12. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/OfflineVideoEngine.kt +227 -0
  13. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/PentheraContentProvider.kt +17 -0
  14. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/ServiceStarter.kt +65 -0
  15. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/data/Drm.kt +6 -0
  16. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/data/Item.kt +34 -0
  17. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/notification/NotificationFactory.kt +279 -0
  18. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/notification/NotificationType.kt +10 -0
  19. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/notification/ServiceForegroundNotificationProvider.kt +98 -0
  20. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/util/Util.kt +22 -0
  21. package/android/src/main/res/drawable/ic_launcher_background.xml +170 -0
  22. package/android/src/main/res/drawable/small_logo.png +0 -0
  23. package/android/src/main/res/values/colors.xml +6 -0
  24. package/android/src/main/res/values/strings.xml +61 -0
  25. package/android/src/main/res/values/styles.xml +10 -0
  26. package/android/src/main/res/xml/network_security_config.xml +9 -0
  27. package/ios/Catalog.swift +30 -0
  28. package/ios/EventEmitter.swift +53 -0
  29. package/ios/Penthera-Bridging-Header.h +3 -0
  30. package/ios/Penthera.m +40 -0
  31. package/ios/Penthera.swift +384 -0
  32. package/ios/Penthera.xcodeproj/project.pbxproj +283 -0
  33. package/ios/Util.swift +16 -0
  34. package/ios/drm/FairPlayDrmSetup.swift +107 -0
  35. package/ios/drm/FairPlayLicenseProcessingDelegate.swift +42 -0
  36. package/lib/commonjs/data/data.json +58 -0
  37. package/lib/commonjs/hooks/index.js +13 -0
  38. package/lib/commonjs/hooks/index.js.map +1 -0
  39. package/lib/commonjs/hooks/usePenthera.js +146 -0
  40. package/lib/commonjs/hooks/usePenthera.js.map +1 -0
  41. package/lib/commonjs/index.js +36 -0
  42. package/lib/commonjs/index.js.map +1 -0
  43. package/lib/commonjs/interface/HomeTypes.js +6 -0
  44. package/lib/commonjs/interface/HomeTypes.js.map +1 -0
  45. package/lib/commonjs/interface/Idata.js +2 -0
  46. package/lib/commonjs/interface/Idata.js.map +1 -0
  47. package/lib/commonjs/interface/PentheraTypes.js +2 -0
  48. package/lib/commonjs/interface/PentheraTypes.js.map +1 -0
  49. package/lib/commonjs/nativeModules/index.js +48 -0
  50. package/lib/commonjs/nativeModules/index.js.map +1 -0
  51. package/lib/commonjs/utils/Penthera.js +19 -0
  52. package/lib/commonjs/utils/Penthera.js.map +1 -0
  53. package/lib/module/data/data.json +58 -0
  54. package/lib/module/hooks/index.js +2 -0
  55. package/lib/module/hooks/index.js.map +1 -0
  56. package/lib/module/hooks/usePenthera.js +139 -0
  57. package/lib/module/hooks/usePenthera.js.map +1 -0
  58. package/lib/module/index.js +5 -0
  59. package/lib/module/index.js.map +1 -0
  60. package/lib/module/interface/HomeTypes.js +2 -0
  61. package/lib/module/interface/HomeTypes.js.map +1 -0
  62. package/lib/module/interface/Idata.js +2 -0
  63. package/lib/module/interface/Idata.js.map +1 -0
  64. package/lib/module/interface/PentheraTypes.js +2 -0
  65. package/lib/module/interface/PentheraTypes.js.map +1 -0
  66. package/lib/module/nativeModules/index.js +35 -0
  67. package/lib/module/nativeModules/index.js.map +1 -0
  68. package/lib/module/utils/Penthera.js +12 -0
  69. package/lib/module/utils/Penthera.js.map +1 -0
  70. package/lib/typescript/hooks/index.d.ts +2 -0
  71. package/lib/typescript/hooks/index.d.ts.map +1 -0
  72. package/lib/typescript/hooks/usePenthera.d.ts +19 -0
  73. package/lib/typescript/hooks/usePenthera.d.ts.map +1 -0
  74. package/lib/typescript/index.d.ts +4 -0
  75. package/lib/typescript/index.d.ts.map +1 -0
  76. package/lib/typescript/interface/HomeTypes.d.ts +15 -0
  77. package/lib/typescript/interface/HomeTypes.d.ts.map +1 -0
  78. package/lib/typescript/interface/Idata.d.ts +30 -0
  79. package/lib/typescript/interface/Idata.d.ts.map +1 -0
  80. package/lib/typescript/interface/PentheraTypes.d.ts +104 -0
  81. package/lib/typescript/interface/PentheraTypes.d.ts.map +1 -0
  82. package/lib/typescript/nativeModules/index.d.ts +9 -0
  83. package/lib/typescript/nativeModules/index.d.ts.map +1 -0
  84. package/lib/typescript/utils/Penthera.d.ts +11 -0
  85. package/lib/typescript/utils/Penthera.d.ts.map +1 -0
  86. package/package.json +166 -0
  87. package/src/data/data.json +58 -0
  88. package/src/hooks/index.ts +1 -0
  89. package/src/hooks/usePenthera.ts +160 -0
  90. package/src/index.tsx +5 -0
  91. package/src/interface/HomeTypes.ts +16 -0
  92. package/src/interface/Idata.ts +34 -0
  93. package/src/interface/PentheraTypes.ts +104 -0
  94. package/src/nativeModules/index.ts +58 -0
  95. package/src/utils/Penthera.ts +10 -0
  96. package/takeoffmedia-react-native-penthera.podspec +36 -0
@@ -0,0 +1,279 @@
1
+ package com.takeoffmediareactnativepenthera.virtuoso.notification
2
+
3
+ import android.app.Notification
4
+ import android.app.NotificationChannel
5
+ import android.app.NotificationManager
6
+ import android.app.PendingIntent
7
+ import android.content.ComponentName
8
+ import android.content.Context
9
+ import android.content.Intent
10
+ import android.content.pm.PackageManager
11
+ import android.os.Build
12
+ import android.util.Log
13
+ import androidx.core.app.NotificationCompat
14
+ import com.google.gson.Gson
15
+ import com.penthera.virtuososdk.Common
16
+ import com.penthera.virtuososdk.client.IAsset
17
+ import com.penthera.virtuososdk.client.IEvent
18
+ import com.takeoffmediareactnativepenthera.PentheraModule
19
+ import com.takeoffmediareactnativepenthera.R
20
+ import com.takeoffmediareactnativepenthera.virtuoso.data.Item
21
+
22
+ class NotificationFactory(private val applicationName: String) {
23
+
24
+ companion object {
25
+ fun channelId() = "Penthera example"
26
+ fun channelName() = "Penthera example channel"
27
+ fun channelDescription() = "Penthera example description"
28
+
29
+ private val TAG = NotificationFactory::class.java.simpleName
30
+ private var notificationChannel : NotificationChannel? = null
31
+ private var compatNotificationBuilder: NotificationCompat.Builder? = null
32
+ }
33
+
34
+
35
+ /** Internal list of types of notifications in this factory */
36
+ private val PROGRESS_NOTIFICATION = 0
37
+ private val COMPLETED_NOTIFICATION = 1
38
+ private val STOPPED_NOTIFICATION = 2
39
+ private val PAUSED_NOTIFICATION = 3
40
+ private val RESTART_NOTIFICATION = 4
41
+ private val FAILED_NOTIFICATION = 5
42
+
43
+ /**
44
+ * This defines a default intent for the app which can be used if none is provided in the request
45
+ */
46
+ private fun defaultNotificationIntent(context: Context) : Intent {
47
+
48
+ val notificationIntent = Intent(context, PentheraModule::class.java)
49
+ notificationIntent.action = "foregroundservice.action.ForegroundServiceNotificationAction"
50
+ notificationIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
51
+ return notificationIntent
52
+ }
53
+
54
+ fun getNotification(context: Context, intent: Intent?): Notification? {
55
+ // A default intent is used if no intent is delivered in the request.
56
+ val notificationIntent = intent ?: defaultNotificationIntent(context)
57
+
58
+ val clientReference: String?
59
+
60
+ // Get package name for use in modifying actions
61
+ try {
62
+ val ai = context.packageManager.getApplicationInfo(context.packageName, PackageManager.GET_META_DATA)
63
+ val b = ai.metaData
64
+
65
+ clientReference = b.getString(Common.CLIENT_PACKAGE)
66
+
67
+ } catch (e: Exception) {
68
+ throw RuntimeException("cannot retrieve client", e)
69
+ }
70
+
71
+ val action = notificationIntent.action
72
+ if (clientReference == null || action == null) {
73
+ return null
74
+ }
75
+
76
+ // If the intent action contains the NOTIFICATION_EVENT_TAG, then this is a log event broadcast sent from
77
+ // the SDK analytics system. For debugging, we might want to post status bar notifications, but in general,
78
+ // these events are used to push SDK analytics events into a custom/3rd party analytics platform, and shouldn't
79
+ // be sent to the status bar. For the purposes of this demo, we'll log them and return null, which prevents the
80
+ // status bar notice from being shown.
81
+ if (action.contains(com.penthera.common.Common.Notifications.NOTIFICATION_EVENT_TAG)) {
82
+
83
+ val event: IEvent? = notificationIntent.getParcelableExtra(com.penthera.common.Common.Notifications.EXTRA_NOTIFICATION_EVENT)
84
+
85
+ Log.d(TAG, "Got event named(" + event?.name() + ") asset(" + event?.assetId() + " data(" + event?.numericData() + ")")
86
+ return null
87
+ }
88
+
89
+ val notificationType : Int
90
+ var file: IAsset? = null
91
+
92
+ if (action == Common.START_VIRTUOSO_SERVICE) {
93
+ notificationType = RESTART_NOTIFICATION
94
+ } else {
95
+ var hasInfo = false
96
+ val extras = notificationIntent.extras
97
+ var info = Common.Notifications.DownloadStopReason.NO_ERROR
98
+
99
+ if (extras != null) {
100
+ if (extras.containsKey(Common.Notifications.EXTRA_NOTIFICATION_DOWNLOAD_STOP_REASON)) {
101
+ hasInfo = true
102
+ info = extras.getInt(Common.Notifications.EXTRA_NOTIFICATION_DOWNLOAD_STOP_REASON)
103
+ }
104
+ file = extras.getParcelable(Common.Notifications.EXTRA_NOTIFICATION_FILE)
105
+ }
106
+
107
+ when(action.replace(clientReference, "")){
108
+
109
+ Common.Notifications.INTENT_NOTIFICATION_DOWNLOAD_COMPLETE -> {
110
+ if (file != null) {
111
+ Log.d(TAG, "DOWNLOAD COMPLETE NOTIFICATION FOR " + file?.uuid + " stat: " + if (hasInfo) info else "unknown")
112
+ } else {
113
+ Log.d(TAG, "DOWNLOAD COMPLETE NOTIFICATION FOR UNKNOWN" + " stat: " + if (hasInfo) info else "unknown")
114
+ }
115
+ notificationType = COMPLETED_NOTIFICATION
116
+ }
117
+ Common.Notifications.INTENT_NOTIFICATION_DOWNLOAD_START ->{
118
+ if(file != null) {
119
+ Log.d(TAG, "DOWNLOAD START NOTIFICATION FOR " + file?.uuid + " stat: " + if (hasInfo) info else "unknown")
120
+ } else {
121
+ Log.d(TAG, "DOWNLOAD START NOTIFICATION FOR UNKNOWN" + " stat: " + if (hasInfo) info else "unknown")
122
+ }
123
+ notificationType = PROGRESS_NOTIFICATION
124
+ }
125
+
126
+ Common.Notifications.INTENT_NOTIFICATION_DOWNLOAD_STOPPED-> {
127
+ if (file != null) {
128
+ Log.d(TAG, "DOWNLOAD STOP NOTIFICATION FOR " + file.uuid + " stat: " + if (hasInfo) info else "unknown")
129
+ } else {
130
+ Log.d(TAG, "DOWNLOAD STOP NOTIFICATION FOR UNKNOWN" + " stat: " + if (hasInfo) info else "unknown")
131
+ }
132
+ notificationType = STOPPED_NOTIFICATION
133
+ }
134
+
135
+ Common.Notifications.INTENT_NOTIFICATION_DOWNLOADS_PAUSED -> {
136
+ if (file != null) {
137
+ Log.d(TAG, "DOWNLOAD PAUSED NOTIFICATION FOR " + file.uuid + " stat: " + if (hasInfo) info else "unknown")
138
+ } else {
139
+ Log.d(TAG, "DOWNLOAD PAUSED NOTIFICATION FOR UNKNOWN" + " stat: " + if (hasInfo) info else "unknown")
140
+ }
141
+ notificationType = PAUSED_NOTIFICATION
142
+ }
143
+
144
+ Common.Notifications.INTENT_NOTIFICATION_DOWNLOAD_UPDATE -> {
145
+ if (file != null) {
146
+ Log.d(TAG, "DOWNLOAD UPDATE NOTIFICATION FOR " + file?.uuid + " stat: " + if (hasInfo) info else "unknown")
147
+ } else {
148
+ Log.d(TAG, "DOWNLOAD UPDATE NOTIFICATION FOR UNKNOWN" + " stat: " + if (hasInfo) info else "unknown")
149
+ }
150
+ notificationType = PROGRESS_NOTIFICATION
151
+ }
152
+
153
+ Common.Notifications.INTENT_NOTIFICATION_MANIFEST_PARSE_FAILED-> {
154
+ notificationType = FAILED_NOTIFICATION
155
+ Log.d(TAG, "EXCEPTIONAL CIRCUMSTANCE NOTIFICATION for asset failed to be queued while in background")
156
+ }
157
+
158
+ else ->{
159
+ notificationType = RESTART_NOTIFICATION
160
+ Log.d(TAG, "UNHANDLED NOTIFICATION ACTION $action")
161
+ }
162
+ }
163
+
164
+ }
165
+
166
+ var notification: Notification? = null
167
+ if (notificationType > -1) {
168
+ notification = createNotification(notificationType, context, file)
169
+ }
170
+
171
+ return notification
172
+ }
173
+
174
+ /**
175
+ * Create the notification for the specified type.
176
+ * @param type The notification type.
177
+ * @param context The context to be used
178
+ * @param asset the asset (may be null)
179
+ * @return the notification.
180
+ */
181
+ private fun createNotification(type: Int, context: Context, asset: IAsset?): Notification? {
182
+ var title = "$applicationName: "
183
+ var contentText = ""
184
+ var progress = -1
185
+
186
+ val item = Gson().fromJson(asset?.metadata, Item::class.java)
187
+
188
+ when (type) {
189
+ PROGRESS_NOTIFICATION -> {
190
+ progress = getDownloadProgress(asset)
191
+ title += item.title
192
+ contentText += progress.toString() + "%" + " : " + String.format(" ( %1$,.0f)", asset?.currentSize)
193
+ }
194
+
195
+ COMPLETED_NOTIFICATION -> {
196
+ progress = 100
197
+ title += asset?.metadata + " complete."
198
+ }
199
+
200
+ STOPPED_NOTIFICATION -> title += "stopped downloads."
201
+
202
+ PAUSED_NOTIFICATION -> title += "paused downloads."
203
+
204
+ RESTART_NOTIFICATION -> title += "is starting up..."
205
+
206
+ FAILED_NOTIFICATION -> title += " asset could not be queued"
207
+ }
208
+
209
+ val pendingIntent = PendingIntent.getActivity(context, 0, createIntent(context), PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_CANCEL_CURRENT)
210
+
211
+ if(compatNotificationBuilder == null) {
212
+ synchronized(this) {
213
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
214
+
215
+ notificationChannel = NotificationChannel(channelId(), channelName(), NotificationManager.IMPORTANCE_LOW)
216
+ notificationChannel?.apply {
217
+ description = channelDescription()
218
+ enableLights(false)
219
+ enableVibration(false)
220
+ }
221
+ val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
222
+ manager.createNotificationChannel(notificationChannel!!)
223
+ compatNotificationBuilder = NotificationCompat.Builder(context, channelId())
224
+
225
+ } else {
226
+ @Suppress("DEPRECATION")
227
+ compatNotificationBuilder = NotificationCompat.Builder(context)
228
+ compatNotificationBuilder?.setOnlyAlertOnce(true)
229
+
230
+ }
231
+ }
232
+
233
+ }
234
+
235
+ return compatNotificationBuilder!!.apply {
236
+ setSmallIcon(R.drawable.small_logo)
237
+ setContentTitle(title)
238
+ setContentIntent(pendingIntent)
239
+ color = context.resources.getColor(android.R.color.holo_blue_bright)
240
+ setContentText(contentText)
241
+ if(progress >= 0)setProgress(100, progress, false)
242
+ setWhen(System.currentTimeMillis())
243
+ setOngoing(true)
244
+ }.build()
245
+
246
+ }
247
+
248
+ /**
249
+ * calculates the progress of the current download.
250
+ * @param asset the current asset downloading
251
+ * @return progress
252
+ */
253
+ private fun getDownloadProgress(asset: IAsset?): Int {
254
+ var ret = 0.0
255
+ asset?.let{
256
+ var fractionComplete = it.fractionComplete
257
+ fractionComplete *= 100
258
+ if (fractionComplete > 99.0) {
259
+ fractionComplete = 99.0
260
+ }
261
+ ret = fractionComplete
262
+ }
263
+
264
+ return ret.toInt()
265
+ }
266
+
267
+
268
+ /**
269
+ * create an intent for opening the application when the user clicks on the notification.
270
+ * @param aContext used to get the package name
271
+ * @return the intent
272
+ */
273
+ private fun createIntent(aContext: Context): Intent {
274
+ return Intent(aContext.packageName + ".DEMO_NOTIFICATION").apply{
275
+ component = ComponentName(aContext.packageName, PentheraModule::class.java.name)
276
+ flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_FROM_BACKGROUND
277
+ }
278
+ }
279
+ }
@@ -0,0 +1,10 @@
1
+ package com.takeoffmediareactnativepenthera.virtuoso.notification
2
+
3
+ enum class NotificationType(value: Int) {
4
+ PROGRESS_NOTIFICATION(0),
5
+ COMPLETED_NOTIFICATION(1),
6
+ STOPPED_NOTIFICATION(2),
7
+ PAUSED_NOTIFICATION(3),
8
+ RESTART_NOTIFICATION(4),
9
+ FAILED_NOTIFICATION(5)
10
+ }
@@ -0,0 +1,98 @@
1
+ package com.takeoffmediareactnativepenthera.virtuoso.notification
2
+
3
+ import android.app.Notification
4
+ import android.app.NotificationChannel
5
+ import android.app.NotificationManager
6
+ import android.content.Context
7
+ import android.content.Intent
8
+ import android.os.Build
9
+ import android.util.Log
10
+ import com.penthera.common.Common.Notifications.NOTIFICATION_EVENT_TAG
11
+ import com.penthera.virtuososdk.client.IAsset
12
+ import com.penthera.virtuososdk.client.IForegroundNotificationProvider
13
+
14
+ /**
15
+ * This implements the IForegroundNotificationProvider interface, which enables notifications to be built
16
+ * within the service process so they do not need to cross the process boundary. Notifications created in the service starter
17
+ * would be passed in an intent over the process boundary into the service process, and this introduces limitations due to the
18
+ * size of object that can be passed over that boundary. This object is instantiated within the service process instead,
19
+ * so no limitations exist on the way the notifications are used, but the process should be considered. Any resources which
20
+ * are required to generate the notification will need to be loaded within this process as they cannot be shared with the process
21
+ * which contains the UI.
22
+ *
23
+ * This example uses the same Factory class to generate notifications. Please remember this is a
24
+ * separate instance of the NotificationFactory, running within a different process than the traditional one in ServiceStarter.
25
+ */
26
+ class ServiceForegroundNotificationProvider : IForegroundNotificationProvider{
27
+
28
+ private var context: Context? = null
29
+ private var notificationChannel: NotificationChannel? = null
30
+ private var channelId: String? = null
31
+ private var currentNotification: Notification? = null
32
+
33
+
34
+ /**
35
+ * This method provides a place where you can setup any necessary resources when the provider is instantiated.
36
+ * This is called directly after construction.
37
+ * @param context A context from the service which can be used for access to Android resources.
38
+ */
39
+ override fun prepareNotificationProvider(context: Context?) {
40
+ this.context = context
41
+ }
42
+
43
+ /**
44
+ * This method allows the client to select for which intents the service will request a new notification.
45
+ * @param context A context object
46
+ * @param reasonIntent The updated intent from the service
47
+ * @return true if the notification should be updated, false otherwise.
48
+ */
49
+ override fun shouldUpdateForegroundServiceNotificationOnIntent(context: Context?, reasonIntent: Intent?): Boolean {
50
+
51
+ if(context != null) {
52
+ reasonIntent?.let {
53
+ val action = it.action
54
+ Log.d("ForegroundNotification", "got action: $action")
55
+ action?.let{// Do not update progress for events
56
+ return !action.contains(NOTIFICATION_EVENT_TAG)
57
+ }
58
+ }
59
+ }
60
+ return false
61
+ }
62
+
63
+ /**
64
+ * This method provides the notification provider with a copy of the original launch notification which was
65
+ * passed to the service upon startup via the ServiceStarter. This can be used to retrieve the channel details and
66
+ * notification ID, which enables the manipulation of the same notification on each request.
67
+ * @param notification The existing notification
68
+ */
69
+ override fun setExistingNotificationForReuse(notification: Notification?) {
70
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
71
+ val channelId = notification?.channelId
72
+ if (currentNotification != null && notificationChannel != null && currentNotification?.channelId == channelId) {
73
+ return
74
+ }
75
+ val manager = context?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
76
+ notificationChannel = manager.getNotificationChannel(channelId)
77
+ this.channelId = channelId
78
+ currentNotification = notification
79
+ } else {
80
+ currentNotification = notification
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Return a new notification, given the file and intent. Always return a notification.
86
+ * @param context A context to use in processing
87
+ * @param file The asset for which the notification is being created
88
+ * @param reasonIntent The intent for which the notification is being created
89
+ * @return The notification
90
+ */
91
+ override fun getForegroundServiceNotification(context: Context?, file: IAsset?, reasonIntent: Intent?): Notification {
92
+ if (reasonIntent == null) return currentNotification!!
93
+
94
+ currentNotification = NotificationFactory("PentheraExample").getNotification(context!!, reasonIntent )
95
+
96
+ return currentNotification!!
97
+ }
98
+ }
@@ -0,0 +1,22 @@
1
+ package com.takeoffmediareactnativepenthera.virtuoso.util
2
+
3
+ import android.os.Build
4
+ import java.util.*
5
+
6
+
7
+ object Util {
8
+
9
+ fun getDeviceName(): String? {
10
+ val manufacturer = Build.MANUFACTURER
11
+ val model = Build.MODEL
12
+ return if (model.lowercase(Locale.getDefault())
13
+ .startsWith(manufacturer.lowercase(Locale.getDefault()))
14
+ ) {
15
+ (model)
16
+ } else {
17
+ (manufacturer).toString() + " " + model
18
+ }
19
+ }
20
+
21
+
22
+ }
@@ -0,0 +1,170 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <vector xmlns:android="http://schemas.android.com/apk/res/android"
3
+ android:width="108dp"
4
+ android:height="108dp"
5
+ android:viewportWidth="108"
6
+ android:viewportHeight="108">
7
+ <path
8
+ android:fillColor="#3DDC84"
9
+ android:pathData="M0,0h108v108h-108z" />
10
+ <path
11
+ android:fillColor="#00000000"
12
+ android:pathData="M9,0L9,108"
13
+ android:strokeWidth="0.8"
14
+ android:strokeColor="#33FFFFFF" />
15
+ <path
16
+ android:fillColor="#00000000"
17
+ android:pathData="M19,0L19,108"
18
+ android:strokeWidth="0.8"
19
+ android:strokeColor="#33FFFFFF" />
20
+ <path
21
+ android:fillColor="#00000000"
22
+ android:pathData="M29,0L29,108"
23
+ android:strokeWidth="0.8"
24
+ android:strokeColor="#33FFFFFF" />
25
+ <path
26
+ android:fillColor="#00000000"
27
+ android:pathData="M39,0L39,108"
28
+ android:strokeWidth="0.8"
29
+ android:strokeColor="#33FFFFFF" />
30
+ <path
31
+ android:fillColor="#00000000"
32
+ android:pathData="M49,0L49,108"
33
+ android:strokeWidth="0.8"
34
+ android:strokeColor="#33FFFFFF" />
35
+ <path
36
+ android:fillColor="#00000000"
37
+ android:pathData="M59,0L59,108"
38
+ android:strokeWidth="0.8"
39
+ android:strokeColor="#33FFFFFF" />
40
+ <path
41
+ android:fillColor="#00000000"
42
+ android:pathData="M69,0L69,108"
43
+ android:strokeWidth="0.8"
44
+ android:strokeColor="#33FFFFFF" />
45
+ <path
46
+ android:fillColor="#00000000"
47
+ android:pathData="M79,0L79,108"
48
+ android:strokeWidth="0.8"
49
+ android:strokeColor="#33FFFFFF" />
50
+ <path
51
+ android:fillColor="#00000000"
52
+ android:pathData="M89,0L89,108"
53
+ android:strokeWidth="0.8"
54
+ android:strokeColor="#33FFFFFF" />
55
+ <path
56
+ android:fillColor="#00000000"
57
+ android:pathData="M99,0L99,108"
58
+ android:strokeWidth="0.8"
59
+ android:strokeColor="#33FFFFFF" />
60
+ <path
61
+ android:fillColor="#00000000"
62
+ android:pathData="M0,9L108,9"
63
+ android:strokeWidth="0.8"
64
+ android:strokeColor="#33FFFFFF" />
65
+ <path
66
+ android:fillColor="#00000000"
67
+ android:pathData="M0,19L108,19"
68
+ android:strokeWidth="0.8"
69
+ android:strokeColor="#33FFFFFF" />
70
+ <path
71
+ android:fillColor="#00000000"
72
+ android:pathData="M0,29L108,29"
73
+ android:strokeWidth="0.8"
74
+ android:strokeColor="#33FFFFFF" />
75
+ <path
76
+ android:fillColor="#00000000"
77
+ android:pathData="M0,39L108,39"
78
+ android:strokeWidth="0.8"
79
+ android:strokeColor="#33FFFFFF" />
80
+ <path
81
+ android:fillColor="#00000000"
82
+ android:pathData="M0,49L108,49"
83
+ android:strokeWidth="0.8"
84
+ android:strokeColor="#33FFFFFF" />
85
+ <path
86
+ android:fillColor="#00000000"
87
+ android:pathData="M0,59L108,59"
88
+ android:strokeWidth="0.8"
89
+ android:strokeColor="#33FFFFFF" />
90
+ <path
91
+ android:fillColor="#00000000"
92
+ android:pathData="M0,69L108,69"
93
+ android:strokeWidth="0.8"
94
+ android:strokeColor="#33FFFFFF" />
95
+ <path
96
+ android:fillColor="#00000000"
97
+ android:pathData="M0,79L108,79"
98
+ android:strokeWidth="0.8"
99
+ android:strokeColor="#33FFFFFF" />
100
+ <path
101
+ android:fillColor="#00000000"
102
+ android:pathData="M0,89L108,89"
103
+ android:strokeWidth="0.8"
104
+ android:strokeColor="#33FFFFFF" />
105
+ <path
106
+ android:fillColor="#00000000"
107
+ android:pathData="M0,99L108,99"
108
+ android:strokeWidth="0.8"
109
+ android:strokeColor="#33FFFFFF" />
110
+ <path
111
+ android:fillColor="#00000000"
112
+ android:pathData="M19,29L89,29"
113
+ android:strokeWidth="0.8"
114
+ android:strokeColor="#33FFFFFF" />
115
+ <path
116
+ android:fillColor="#00000000"
117
+ android:pathData="M19,39L89,39"
118
+ android:strokeWidth="0.8"
119
+ android:strokeColor="#33FFFFFF" />
120
+ <path
121
+ android:fillColor="#00000000"
122
+ android:pathData="M19,49L89,49"
123
+ android:strokeWidth="0.8"
124
+ android:strokeColor="#33FFFFFF" />
125
+ <path
126
+ android:fillColor="#00000000"
127
+ android:pathData="M19,59L89,59"
128
+ android:strokeWidth="0.8"
129
+ android:strokeColor="#33FFFFFF" />
130
+ <path
131
+ android:fillColor="#00000000"
132
+ android:pathData="M19,69L89,69"
133
+ android:strokeWidth="0.8"
134
+ android:strokeColor="#33FFFFFF" />
135
+ <path
136
+ android:fillColor="#00000000"
137
+ android:pathData="M19,79L89,79"
138
+ android:strokeWidth="0.8"
139
+ android:strokeColor="#33FFFFFF" />
140
+ <path
141
+ android:fillColor="#00000000"
142
+ android:pathData="M29,19L29,89"
143
+ android:strokeWidth="0.8"
144
+ android:strokeColor="#33FFFFFF" />
145
+ <path
146
+ android:fillColor="#00000000"
147
+ android:pathData="M39,19L39,89"
148
+ android:strokeWidth="0.8"
149
+ android:strokeColor="#33FFFFFF" />
150
+ <path
151
+ android:fillColor="#00000000"
152
+ android:pathData="M49,19L49,89"
153
+ android:strokeWidth="0.8"
154
+ android:strokeColor="#33FFFFFF" />
155
+ <path
156
+ android:fillColor="#00000000"
157
+ android:pathData="M59,19L59,89"
158
+ android:strokeWidth="0.8"
159
+ android:strokeColor="#33FFFFFF" />
160
+ <path
161
+ android:fillColor="#00000000"
162
+ android:pathData="M69,19L69,89"
163
+ android:strokeWidth="0.8"
164
+ android:strokeColor="#33FFFFFF" />
165
+ <path
166
+ android:fillColor="#00000000"
167
+ android:pathData="M79,19L79,89"
168
+ android:strokeWidth="0.8"
169
+ android:strokeColor="#33FFFFFF" />
170
+ </vector>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <resources>
3
+ <color name="colorPrimary">#6200EE</color>
4
+ <color name="colorPrimaryDark">#3700B3</color>
5
+ <color name="colorAccent">#03DAC5</color>
6
+ </resources>
@@ -0,0 +1,61 @@
1
+ <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
2
+ <string name="app_name">Penthera Example</string>
3
+
4
+ <string name="status_queued">Queued</string>
5
+ <string name="status_downloading">Downloading</string>
6
+ <string name="status_downloaded">Downloaded</string>
7
+ <string name="status_pending">Queued</string>
8
+ <string name="status_expired">Expired</string>
9
+
10
+ <string name="asset_status_pending">pending</string>
11
+ <string name="asset_status_downloading">downloading</string>
12
+ <string name="asset_status_complete">complete</string>
13
+ <string name="asset_status_expired">expired</string>
14
+ <string name="asset_status_denied_mad">DENIED : MAD</string>
15
+ <string name="asset_status_denied_mda">DENIED : MDA</string>
16
+ <string name="asset_status_denied_ext">DENIED : EXT</string>
17
+ <string name="asset_status_denied_mpd">DENIED : MPD</string>
18
+ <string name="asset_status_denied_copies">DENIED : COPIES</string>
19
+ <string name="asset_status_await_permission">AWAITING PERMISSION</string>
20
+
21
+ <string name="asset_status">File %1$s with %2$d errors, current state: %3$s</string>
22
+
23
+ <!-- Drm key fetch messages -->
24
+ <string name="license_fetch_success">Fetched license for asset id: %1$s</string>
25
+ <string name="license_fetch_failure">License fetch failed for asset id: %1$s</string>
26
+
27
+ <!-- Drm error messages -->
28
+ <string name="error_drm_unknown">An unknown DRM error occurred</string>
29
+
30
+ <string name="error_drm_not_supported">Protected content not supported on API levels below 18</string>
31
+
32
+ <string name="error_drm_unsupported_scheme">This device does not support the required DRM scheme</string>
33
+
34
+ <!-- Playback error messages -->
35
+
36
+ <string name="error_cannot_play">Cannot play asset</string>
37
+
38
+ <string name="error_invalid_url">Cannot play asset - playlist issue</string>
39
+
40
+ <string name="unexpected_intent_action">Unexpected intent action: <xliff:g id="action">%1$s</xliff:g></string>
41
+
42
+ <!-- Exoplayer error message strings, taken directly from Exoplayer demo -->
43
+
44
+ <string name="error_generic">Playback failed</string>
45
+
46
+ <string name="error_querying_decoders">Unable to query device decoders</string>
47
+
48
+ <string name="error_no_decoder">This device does not provide a decoder for <xliff:g id="mime_type">%1$s</xliff:g></string>
49
+
50
+ <string name="error_no_secure_decoder">This device does not provide a secure decoder for <xliff:g id="mime_type">%1$s</xliff:g></string>
51
+
52
+ <string name="error_instantiating_decoder">Unable to instantiate decoder <xliff:g id="decoder_name">%1$s</xliff:g></string>
53
+
54
+ <string name="error_unsupported_video">Media includes video tracks, but none are playable by this device</string>
55
+
56
+ <string name="error_unsupported_audio">Media includes audio tracks, but none are playable by this device</string>
57
+
58
+ <string name="storage_permission_denied">Permission to access storage was denied</string>
59
+
60
+
61
+ </resources>
@@ -0,0 +1,10 @@
1
+ <resources>
2
+ <!-- Base application theme. -->
3
+ <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
4
+ <!-- Customize your theme here. -->
5
+ <item name="colorPrimary">@color/colorPrimary</item>
6
+ <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
7
+ <item name="colorAccent">@color/colorAccent</item>
8
+ </style>
9
+
10
+ </resources>
@@ -0,0 +1,9 @@
1
+ <network-security-config>
2
+ <base-config cleartextTrafficPermitted="true">
3
+ <!-- Trust user added CAs in release -->
4
+ <trust-anchors>
5
+ <certificates src="user" />
6
+ <certificates src="system" />
7
+ </trust-anchors>
8
+ </base-config>
9
+ </network-security-config>