Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android Add hybrid app hooks #62

Merged
merged 1 commit into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,15 @@ internal class AirshipListener(

override fun onNotificationPosted(notificationInfo: NotificationInfo) {
eventEmitter.addEvent(PushReceivedEvent(notificationInfo, isAppForegrounded))
AirshipPluginForwardListeners.notificationListener?.onNotificationPosted(notificationInfo)
}

override fun onNotificationOpened(notificationInfo: NotificationInfo): Boolean {
eventEmitter.addEvent(
NotificationResponseEvent(notificationInfo, null)
)
return false

return AirshipPluginForwardListeners.notificationListener?.onNotificationOpened(notificationInfo) ?: false
}

override fun onNotificationForegroundAction(
Expand All @@ -87,7 +89,7 @@ internal class AirshipListener(
eventEmitter.addEvent(
NotificationResponseEvent(notificationInfo, notificationActionButtonInfo)
)
return false
return AirshipPluginForwardListeners.notificationListener?.onNotificationForegroundAction(notificationInfo, notificationActionButtonInfo) ?: false
}

override fun onNotificationBackgroundAction(
Expand All @@ -97,12 +99,18 @@ internal class AirshipListener(
eventEmitter.addEvent(
NotificationResponseEvent(notificationInfo, notificationActionButtonInfo)
)
AirshipPluginForwardListeners.notificationListener?.onNotificationBackgroundAction(notificationInfo, notificationActionButtonInfo)
}

override fun onNotificationDismissed(notificationInfo: NotificationInfo) {}
override fun onNotificationDismissed(notificationInfo: NotificationInfo) {
AirshipPluginForwardListeners.notificationListener?.onNotificationDismissed(notificationInfo)
}

override fun onDeepLink(deepLink: String): Boolean {
eventEmitter.addEvent(DeepLinkEvent(deepLink))
if (AirshipPluginForwardListeners.deepLinkListener?.onDeepLink(deepLink) != true) {
eventEmitter.addEvent(DeepLinkEvent(deepLink))
}

return true
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* Copyright Urban Airship and Contributors */

package com.urbanairship.android.framework.proxy

import com.urbanairship.actions.DeepLinkListener
import com.urbanairship.push.NotificationListener

/**
* Optional forward listeners for the plugin.
*/
public object AirshipPluginForwardListeners {
/**
* Deep link listener
*/
public var deepLinkListener: DeepLinkListener? = null

/**
* Notification Listener
*/
public var notificationListener: NotificationListener? = null
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package com.urbanairship.android.framework.proxy

import android.content.Context
import com.urbanairship.AirshipConfigOptions
import com.urbanairship.UAirship

/**
Expand All @@ -19,4 +20,19 @@ public interface AirshipPluginExtender {
* @param airship The airship instance.
*/
public fun onAirshipReady(context: Context, airship: UAirship)

/**
* Used to extend the AirshipConfig. The configBuilder will have the default config applied from the properties file if available,
* any config defined by the module.
* @param context The application context.
* @param configBuilder The config builder
* @return The config builder.
*/
public fun extendConfig(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of making this a breaking change we could add a new interface that the pluginExtender could optionally implement. That makes it a little harder to use though

context: Context,
configBuilder: AirshipConfigOptions.Builder
): AirshipConfigOptions.Builder {
return configBuilder
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import kotlinx.coroutines.runBlocking
*/
public abstract class BaseAutopilot : Autopilot() {

private var extenderProvider: ExtenderProvider = ExtenderProvider()
private var configOptions: AirshipConfigOptions? = null
private var firstReady: Boolean = false

Expand Down Expand Up @@ -103,7 +104,8 @@ public abstract class BaseAutopilot : Autopilot() {

onReady(context, airship)

createExtender(context)?.onAirshipReady(context, airship)
extenderProvider.get(context)?.onAirshipReady(context, airship)
extenderProvider.reset()
}

protected abstract fun onReady(context: Context, airship: UAirship)
Expand Down Expand Up @@ -134,11 +136,13 @@ public abstract class BaseAutopilot : Autopilot() {
firstReady = true
}

val builder = createConfigBuilder(context)
var builder = createConfigBuilder(context)
AirshipProxy.shared(context).proxyStore.airshipConfig?.let {
builder.applyProxyConfig(context, it)
}

builder = extenderProvider.get(context)?.extendConfig(context, builder) ?: builder

val configOptions = builder.build()

return try {
Expand Down Expand Up @@ -168,33 +172,6 @@ public abstract class BaseAutopilot : Autopilot() {
}

public abstract fun onMigrateData(context: Context, proxyStore: ProxyStore)

private fun createExtender(context: Context): AirshipPluginExtender? {
val ai: ApplicationInfo
try {
ai = context.packageManager.getApplicationInfo(context.packageName, PackageManager.GET_META_DATA)

if (ai.metaData == null) {
return null
}
} catch (e: PackageManager.NameNotFoundException) {
return null
}

val classname = ai.metaData.getString(EXTENDER_MANIFEST_KEY) ?: return null

try {
val extenderClass = Class.forName(classname)
return extenderClass.getDeclaredConstructor().newInstance() as AirshipPluginExtender
} catch (e: Exception) {
ProxyLogger.error(e, "Unable to create extender: $classname")
}
return null
}

private companion object {
const val EXTENDER_MANIFEST_KEY = "com.urbanairship.plugin.extender"
}
}

public fun AirshipConfigOptions.Builder.applyProxyConfig(context: Context, proxyConfig: ProxyConfig) {
Expand Down Expand Up @@ -245,4 +222,48 @@ public fun AirshipConfigOptions.Builder.applyProxyConfig(context: Context, proxy
}
}

private class ExtenderProvider {
private var extender: AirshipPluginExtender? = null
private var created: Boolean = false

fun get(context: Context): AirshipPluginExtender? {
if (!created) {
extender = createExtender(context)
}
return extender
}

fun reset() {
created = false
extender = null
}

private fun createExtender(context: Context): AirshipPluginExtender? {
val ai: ApplicationInfo
try {
ai = context.packageManager.getApplicationInfo(context.packageName, PackageManager.GET_META_DATA)

if (ai.metaData == null) {
return null
}
} catch (e: PackageManager.NameNotFoundException) {
return null
}

val classname = ai.metaData.getString(EXTENDER_MANIFEST_KEY) ?: return null

try {
val extenderClass = Class.forName(classname)
return extenderClass.getDeclaredConstructor().newInstance() as AirshipPluginExtender
} catch (e: Exception) {
ProxyLogger.error(e, "Unable to create extender: $classname")
}
return null
}

private companion object {
const val EXTENDER_MANIFEST_KEY = "com.urbanairship.plugin.extender"
}
}


Loading