diff --git a/code/aep_ui_utils/.gitignore b/code/aep_ui_utils/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/code/aep_ui_utils/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/code/aep_ui_utils/build.gradle.kts b/code/aep_ui_utils/build.gradle.kts new file mode 100644 index 00000000..56beca2a --- /dev/null +++ b/code/aep_ui_utils/build.gradle.kts @@ -0,0 +1,30 @@ +plugins { + id("aep-library") +} + +val mavenCoreVersion: String by project +val aepUIUtilsModuleName: String by project +val aepUIUtilsVersion: String by project +val aepUIUtilsMavenRepoName: String by project +val aepUIUtilsMavenRepoDescription: String by project + + +aepLibrary { + namespace = "com.adobe.marketing.mobile.aep_ui_utils" + moduleName = aepUIUtilsModuleName + moduleVersion = aepUIUtilsVersion + enableSpotless = true + enableCheckStyle = true + enableDokkaDoc = true + + publishing { + mavenRepoName = aepUIUtilsMavenRepoName + mavenRepoDescription = aepUIUtilsMavenRepoDescription + gitRepoName = "aepsdk-ui-android" + addCoreDependency(mavenCoreVersion) + } +} + +dependencies { + implementation("com.adobe.marketing.mobile:core:$mavenCoreVersion") +} diff --git a/code/aep_ui_utils/consumer-rules.pro b/code/aep_ui_utils/consumer-rules.pro new file mode 100644 index 00000000..e69de29b diff --git a/code/aep_ui_utils/proguard-rules.pro b/code/aep_ui_utils/proguard-rules.pro new file mode 100644 index 00000000..481bb434 --- /dev/null +++ b/code/aep_ui_utils/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/code/aep_ui_utils/src/main/AndroidManifest.xml b/code/aep_ui_utils/src/main/AndroidManifest.xml new file mode 100644 index 00000000..69fc4129 --- /dev/null +++ b/code/aep_ui_utils/src/main/AndroidManifest.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/code/aep_ui_utils/src/main/java/com/adobe/marketing/mobile/utils/AEPUIImageConfig.kt b/code/aep_ui_utils/src/main/java/com/adobe/marketing/mobile/utils/AEPUIImageConfig.kt new file mode 100644 index 00000000..19876143 --- /dev/null +++ b/code/aep_ui_utils/src/main/java/com/adobe/marketing/mobile/utils/AEPUIImageConfig.kt @@ -0,0 +1,50 @@ +/* + Copyright 2024 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ + +package com.adobe.marketing.mobile.utils + +import android.graphics.Matrix +import com.adobe.marketing.mobile.utils.AEPUIImageConstants.DEFAULT_BITMAP_QUALITY +import com.adobe.marketing.mobile.utils.AEPUIImageConstants.DEFAULT_DOWNLOAD_TIMEOUT_SECS + +class AEPUIImageConfig private constructor(builder: Builder) { + val urlList: List + val downloadTimeoutInSeconds: Int + val bitmapQuality: Int + val bitmapWidth: Float + val bitmapHeight: Float + val scaleToFit: Matrix.ScaleToFit + + init { + this.urlList = builder.urlList + this.downloadTimeoutInSeconds = builder.downloadTimeoutInSeconds + this.bitmapQuality = builder.bitmapQuality + this.bitmapWidth = builder.bitmapWidth + this.bitmapHeight = builder.bitmapHeight + this.scaleToFit = builder.scaleToFit + } + + class Builder(val bitmapWidth: Float, val bitmapHeight: Float) { + var urlList: List = listOf() + var downloadTimeoutInSeconds: Int = DEFAULT_DOWNLOAD_TIMEOUT_SECS + var bitmapQuality: Int = DEFAULT_BITMAP_QUALITY + var scaleToFit: Matrix.ScaleToFit = Matrix.ScaleToFit.CENTER + + fun urlList(urlList: List) = apply { this.urlList = urlList } + fun downloadTimeoutInSeconds(downloadTimeoutInSeconds: Int) = + apply { this.downloadTimeoutInSeconds = downloadTimeoutInSeconds } + + fun bitmapQuality(bitmapQuality: Int) = apply { this.bitmapQuality = bitmapQuality } + fun scaleToFit(scaleToFit: Matrix.ScaleToFit) = apply { this.scaleToFit = scaleToFit } + + fun build() = AEPUIImageConfig(this) + } +} diff --git a/code/aep_ui_utils/src/main/java/com/adobe/marketing/mobile/utils/AEPUIImageConstants.kt b/code/aep_ui_utils/src/main/java/com/adobe/marketing/mobile/utils/AEPUIImageConstants.kt new file mode 100644 index 00000000..45c21ea7 --- /dev/null +++ b/code/aep_ui_utils/src/main/java/com/adobe/marketing/mobile/utils/AEPUIImageConstants.kt @@ -0,0 +1,23 @@ +/* + Copyright 2024 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ + +package com.adobe.marketing.mobile.utils + +import java.util.concurrent.TimeUnit + +object AEPUIImageConstants { + const val DEFAULT_BITMAP_QUALITY = 100 + const val DEFAULT_DOWNLOAD_TIMEOUT_SECS = 10 + const val AEP_UI_UTIL_LOG_TAG = "AEPUIUtils" + const val CACHE_BASE_DIR = "uiCacheDir" + const val PUSH_IMAGE_CACHE = "uiImageCache" + val IMAGE_CACHE_EXPIRY_IN_MILLISECONDS: Long = TimeUnit.DAYS.toMillis(3) // 3 days +} diff --git a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/PushTemplateImageUtils.kt b/code/aep_ui_utils/src/main/java/com/adobe/marketing/mobile/utils/AEPUIImageUtils.kt similarity index 80% rename from code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/PushTemplateImageUtils.kt rename to code/aep_ui_utils/src/main/java/com/adobe/marketing/mobile/utils/AEPUIImageUtils.kt index 8144e654..de3d9d57 100644 --- a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/PushTemplateImageUtils.kt +++ b/code/aep_ui_utils/src/main/java/com/adobe/marketing/mobile/utils/AEPUIImageUtils.kt @@ -9,14 +9,12 @@ governing permissions and limitations under the License. */ -package com.adobe.marketing.mobile.notificationbuilder.internal +package com.adobe.marketing.mobile.utils import android.graphics.Bitmap import android.graphics.BitmapFactory import android.graphics.Matrix import android.graphics.RectF -import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants -import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.LOG_TAG import com.adobe.marketing.mobile.services.HttpConnecting import com.adobe.marketing.mobile.services.HttpMethod import com.adobe.marketing.mobile.services.Log @@ -27,6 +25,10 @@ import com.adobe.marketing.mobile.services.caching.CacheEntry import com.adobe.marketing.mobile.services.caching.CacheExpiry import com.adobe.marketing.mobile.services.caching.CacheService import com.adobe.marketing.mobile.util.UrlUtils +import com.adobe.marketing.mobile.utils.AEPUIImageConstants.AEP_UI_UTIL_LOG_TAG +import com.adobe.marketing.mobile.utils.AEPUIImageConstants.CACHE_BASE_DIR +import com.adobe.marketing.mobile.utils.AEPUIImageConstants.IMAGE_CACHE_EXPIRY_IN_MILLISECONDS +import com.adobe.marketing.mobile.utils.AEPUIImageConstants.PUSH_IMAGE_CACHE import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.io.File @@ -42,10 +44,8 @@ import java.util.concurrent.atomic.AtomicInteger * Utility functions to assist in downloading and caching images for push template notifications. */ -internal object PushTemplateImageUtils { - private const val SELF_TAG = "PushTemplateImageUtil" - private const val FULL_BITMAP_QUALITY = 100 - private const val DOWNLOAD_TIMEOUT_SECS = 10 +object AEPUIImageUtils { + private const val SELF_TAG = "AEPUIImageUtils" /** * Downloads and caches images provided in the [urlList]. Prior to downloading, the image url @@ -59,10 +59,11 @@ internal object PushTemplateImageUtils { * @param urlList [String] containing an image asset url * @return [Int] number of images that were found in cache or successfully downloaded */ - internal fun cacheImages( - urlList: List + fun cacheImages( + config: AEPUIImageConfig ): Int { val assetCacheLocation = getAssetCacheLocation() + val urlList = config.urlList if (urlList.isEmpty() || assetCacheLocation.isNullOrEmpty()) { return 0 } @@ -80,7 +81,7 @@ internal object PushTemplateImageUtils { val cacheResult = cacheService[assetCacheLocation, url] if (cacheResult != null) { Log.trace( - LOG_TAG, + AEP_UI_UTIL_LOG_TAG, SELF_TAG, "Found cached image for $url" ) @@ -89,16 +90,24 @@ internal object PushTemplateImageUtils { continue } - downloadImage(url) { connection -> + downloadImage(url, config.downloadTimeoutInSeconds) { connection -> if (!latchAborted.get()) { val image = handleDownloadResponse(url, connection) // scale down the bitmap to 300dp x 200dp as we don't want to use a full // size image due to memory constraints image?.let { - val pushImage = scaleBitmap(it) + val scaledImage = scaleBitmap( + it, + config.bitmapWidth, + config.bitmapHeight, + config.scaleToFit + ) // write bitmap to cache try { - bitmapToInputStream(pushImage).use { bitmapInputStream -> + bitmapToInputStream( + scaledImage, + config.bitmapQuality + ).use { bitmapInputStream -> cacheBitmapInputStream( cacheService, bitmapInputStream, @@ -108,7 +117,7 @@ internal object PushTemplateImageUtils { downloadedImageCount.incrementAndGet() } catch (exception: IOException) { Log.warning( - LOG_TAG, + AEP_UI_UTIL_LOG_TAG, SELF_TAG, "Exception occurred creating an input stream from a bitmap for {$url}: ${exception.localizedMessage}." ) @@ -120,15 +129,15 @@ internal object PushTemplateImageUtils { } } try { - if (latch.await(DOWNLOAD_TIMEOUT_SECS.toLong(), TimeUnit.SECONDS)) { + if (latch.await(config.downloadTimeoutInSeconds.toLong(), TimeUnit.SECONDS)) { Log.trace( - LOG_TAG, + AEP_UI_UTIL_LOG_TAG, SELF_TAG, "All image downloads have completed." ) } else { Log.warning( - LOG_TAG, + AEP_UI_UTIL_LOG_TAG, SELF_TAG, "Timed out waiting for image downloads to complete." ) @@ -136,7 +145,7 @@ internal object PushTemplateImageUtils { } } catch (e: InterruptedException) { Log.warning( - LOG_TAG, + AEP_UI_UTIL_LOG_TAG, SELF_TAG, "Interrupted while waiting for image downloads to complete: ${e.localizedMessage}" ) @@ -154,6 +163,7 @@ internal object PushTemplateImageUtils { */ private fun downloadImage( url: String, + downloadTimeoutInSeconds: Int, completionCallback: (HttpConnecting?) -> Unit ) { val networkRequest = NetworkRequest( @@ -161,8 +171,8 @@ internal object PushTemplateImageUtils { HttpMethod.GET, null, null, - DOWNLOAD_TIMEOUT_SECS, - DOWNLOAD_TIMEOUT_SECS + downloadTimeoutInSeconds, + downloadTimeoutInSeconds ) val networkCallback = NetworkCallback { connection: HttpConnecting? -> @@ -180,24 +190,24 @@ internal object PushTemplateImageUtils { * @param url [String] containing the image url to retrieve from cache * @return [Bitmap] containing the image retrieved from cache, or `null` if no image is found */ - internal fun getCachedImage(url: String?): Bitmap? { + fun getCachedImage(url: String?): Bitmap? { val assetCacheLocation = getAssetCacheLocation() if (url == null || !UrlUtils.isValidUrl(url) || assetCacheLocation.isNullOrEmpty()) { return null } val cacheResult = ServiceProvider.getInstance().cacheService[assetCacheLocation, url] if (cacheResult == null) { - Log.warning(LOG_TAG, SELF_TAG, "Image not found in cache for $url") + Log.warning(AEP_UI_UTIL_LOG_TAG, SELF_TAG, "Image not found in cache for $url") return null } - Log.trace(LOG_TAG, SELF_TAG, "Found cached image for $url") + Log.trace(AEP_UI_UTIL_LOG_TAG, SELF_TAG, "Found cached image for $url") return BitmapFactory.decodeStream(cacheResult.data) } private fun handleDownloadResponse(url: String?, connection: HttpConnecting?): Bitmap? { if (connection == null) { Log.warning( - LOG_TAG, + AEP_UI_UTIL_LOG_TAG, SELF_TAG, "Failed to download push notification image from url ($url), received a null connection." ) @@ -205,7 +215,7 @@ internal object PushTemplateImageUtils { } if ((connection.responseCode != HttpURLConnection.HTTP_OK)) { Log.debug( - LOG_TAG, + AEP_UI_UTIL_LOG_TAG, SELF_TAG, "Failed to download push notification image from url ($url). Response code was: ${connection.responseCode}." ) @@ -214,7 +224,7 @@ internal object PushTemplateImageUtils { val bitmap = BitmapFactory.decodeStream(connection.inputStream) bitmap?.let { Log.trace( - LOG_TAG, + AEP_UI_UTIL_LOG_TAG, SELF_TAG, "Downloaded push notification image from url ($url)" ) @@ -228,9 +238,9 @@ internal object PushTemplateImageUtils { * @param bitmap [Bitmap] to be converted into an [InputStream] * @return an `InputStream` created from the provided bitmap */ - private fun bitmapToInputStream(bitmap: Bitmap): InputStream { + private fun bitmapToInputStream(bitmap: Bitmap, bitmapQuality: Int): InputStream { ByteArrayOutputStream().use { - bitmap.compress(Bitmap.CompressFormat.PNG, FULL_BITMAP_QUALITY, it) + bitmap.compress(Bitmap.CompressFormat.PNG, bitmapQuality, it) val bitmapData = it.toByteArray() return ByteArrayInputStream(bitmapData) } @@ -249,7 +259,7 @@ internal object PushTemplateImageUtils { imageUrl: String ) { Log.trace( - LOG_TAG, + AEP_UI_UTIL_LOG_TAG, SELF_TAG, "Caching image downloaded from $imageUrl." ) @@ -257,9 +267,7 @@ internal object PushTemplateImageUtils { // cache push notification images for 3 days val cacheEntry = CacheEntry( bitmapInputStream, - CacheExpiry.after( - PushTemplateConstants.DefaultValues.PUSH_NOTIFICATION_IMAGE_CACHE_EXPIRY_IN_MILLISECONDS - ), + CacheExpiry.after(IMAGE_CACHE_EXPIRY_IN_MILLISECONDS), null ) cacheService[it, imageUrl] = cacheEntry @@ -274,17 +282,22 @@ internal object PushTemplateImageUtils { * @param downloadedBitmap [Bitmap] to be scaled * @return [Bitmap] containing the scaled image */ - private fun scaleBitmap(downloadedBitmap: Bitmap): Bitmap { + private fun scaleBitmap( + downloadedBitmap: Bitmap, + bitmapWidth: Float, + bitmapHeight: Float, + scaleToFit: Matrix.ScaleToFit + ): Bitmap { val matrix = Matrix() matrix.setRectToRect( RectF(0f, 0f, downloadedBitmap.width.toFloat(), downloadedBitmap.height.toFloat()), RectF( 0f, 0f, - PushTemplateConstants.DefaultValues.CAROUSEL_MAX_BITMAP_WIDTH.toFloat(), - PushTemplateConstants.DefaultValues.CAROUSEL_MAX_BITMAP_HEIGHT.toFloat() + bitmapWidth, + bitmapHeight ), - Matrix.ScaleToFit.CENTER + scaleToFit ) return Bitmap.createBitmap( downloadedBitmap, @@ -302,7 +315,7 @@ internal object PushTemplateImageUtils { * * @return [String] containing the asset cache location to use for storing downloaded push template images. */ - internal fun getAssetCacheLocation(): String? { + fun getAssetCacheLocation(): String? { val deviceInfoService = ServiceProvider.getInstance().deviceInfoService ?: return null val applicationCacheDir = deviceInfoService.applicationCacheDir @@ -310,9 +323,9 @@ internal object PushTemplateImageUtils { ( applicationCacheDir .toString() + File.separator + - PushTemplateConstants.CACHE_BASE_DIR + CACHE_BASE_DIR ) + File.separator + - PushTemplateConstants.PUSH_IMAGE_CACHE + PUSH_IMAGE_CACHE ) } } diff --git a/code/aep_ui_utils/src/test/java/com/adobe/marketing/mobile/utils/AEPUIImageConfigTest.kt b/code/aep_ui_utils/src/test/java/com/adobe/marketing/mobile/utils/AEPUIImageConfigTest.kt new file mode 100644 index 00000000..657633ae --- /dev/null +++ b/code/aep_ui_utils/src/test/java/com/adobe/marketing/mobile/utils/AEPUIImageConfigTest.kt @@ -0,0 +1,65 @@ +/* + Copyright 2024 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ + +package com.adobe.marketing.mobile.utils + +import android.graphics.Matrix +import com.adobe.marketing.mobile.utils.AEPUIImageConstants.DEFAULT_BITMAP_QUALITY +import com.adobe.marketing.mobile.utils.AEPUIImageConstants.DEFAULT_DOWNLOAD_TIMEOUT_SECS +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Test + +class AEPUIImageConfigTest { + @Test + fun `builder sets values correctly`() { + val urlList = listOf("https://example.com/image1.png", "https://example.com/image2.png") + val downloadTimeoutInSeconds = 10 + val bitmapQuality = 80 + val bitmapWidth = 300f + val bitmapHeight = 200f + val scaleToFit = Matrix.ScaleToFit.CENTER + + val config = AEPUIImageConfig.Builder(bitmapWidth, bitmapHeight) + .urlList(urlList) + .downloadTimeoutInSeconds(downloadTimeoutInSeconds) + .bitmapQuality(bitmapQuality) + .scaleToFit(scaleToFit) + .build() + + assertEquals(urlList, config.urlList) + assertEquals(downloadTimeoutInSeconds, config.downloadTimeoutInSeconds) + assertEquals(bitmapQuality, config.bitmapQuality) + assertEquals(bitmapWidth, config.bitmapWidth, 0.0f) + assertEquals(bitmapHeight, config.bitmapHeight, 0.0f) + assertEquals(scaleToFit, config.scaleToFit) + } + + @Test + fun `builder uses default values when not set`() { + val bitmapWidth = 300f + val bitmapHeight = 200f + + val config = AEPUIImageConfig.Builder(bitmapWidth, bitmapHeight).build() + + assertTrue(config.urlList.isEmpty()) + assertEquals(DEFAULT_DOWNLOAD_TIMEOUT_SECS, config.downloadTimeoutInSeconds) + assertEquals(DEFAULT_BITMAP_QUALITY, config.bitmapQuality) + assertEquals(Matrix.ScaleToFit.CENTER, config.scaleToFit) + } + + @Test + fun `builder handles null urlList correctly`() { + val urlList = listOf(null, "https://example.com/image2.png") + val config = AEPUIImageConfig.Builder(300f, 200f).urlList(urlList).build() + assertEquals(urlList, config.urlList) + } +} diff --git a/code/gradle.properties b/code/gradle.properties index 869da451..27d6045d 100644 --- a/code/gradle.properties +++ b/code/gradle.properties @@ -22,6 +22,12 @@ notificationbuilderVersion=3.0.1 notificationbuilderMavenRepoName=AdobeMobileNotificationBuilderSdk notificationbuilderMavenRepoDescription=Android Notification Builder library for Adobe Mobile Marketing +#AEP UI Utils +aepUIUtilsModuleName = aep_ui_utils +aepUIUtilsVersion=1.0.0 +aepUIUtilsMavenRepoName = AdobeMobileAEPUIUtilsSdk +aepUIUtilsMavenRepoDescription = Android AEP UI Utils library for Adobe Mobile Marketing + mavenCoreVersion=3.0.0 diff --git a/code/notificationbuilder/build.gradle.kts b/code/notificationbuilder/build.gradle.kts index 60943c91..96ab5cbc 100644 --- a/code/notificationbuilder/build.gradle.kts +++ b/code/notificationbuilder/build.gradle.kts @@ -38,6 +38,7 @@ aepLibrary { dependencies { implementation("com.adobe.marketing.mobile:core:$mavenCoreVersion") + implementation(project(":aep_ui_utils")) testImplementation("org.robolectric:robolectric:4.7") testImplementation("io.mockk:mockk:1.13.11") } diff --git a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/PushTemplateConstants.kt b/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/PushTemplateConstants.kt index b08f24d5..8e7c87a4 100644 --- a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/PushTemplateConstants.kt +++ b/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/PushTemplateConstants.kt @@ -11,15 +11,11 @@ package com.adobe.marketing.mobile.notificationbuilder -import java.util.concurrent.TimeUnit - /** * This object holds all constant values for handling out-of-the-box push template notifications */ object PushTemplateConstants { internal const val LOG_TAG = "PushTemplates" - internal const val CACHE_BASE_DIR = "pushtemplates" - internal const val PUSH_IMAGE_CACHE = "pushimagecache" internal const val DEFAULT_DELETE_ICON_NAME = "cross" @@ -70,11 +66,6 @@ object PushTemplateConstants { internal const val PRODUCT_CATALOG_VERTICAL_LAYOUT = "vertical" internal const val ICON_TEMPLATE_MIN_IMAGE_COUNT = 3 internal const val ICON_TEMPLATE_MAX_IMAGE_COUNT = 5 - - // TODO: revisit this value. should cache time be configurable rather than have a static - // value? - internal val PUSH_NOTIFICATION_IMAGE_CACHE_EXPIRY_IN_MILLISECONDS: Long = - TimeUnit.DAYS.toMillis(3) // 3 days } internal object MethodNames { diff --git a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/RemindLaterHandler.kt b/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/RemindLaterHandler.kt index a82fd8a8..bfe64c29 100644 --- a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/RemindLaterHandler.kt +++ b/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/RemindLaterHandler.kt @@ -49,9 +49,11 @@ object RemindLaterHandler { val intentExtras = remindLaterIntent.extras ?: throw NotificationConstructionFailedException("Intent extras are null, cannot schedule notification for later.") val remindLaterTimestamp = - intentExtras.getString(PushTemplateConstants.PushPayloadKeys.REMIND_LATER_TIMESTAMP)?.toLongOrNull() ?: 0 + intentExtras.getString(PushTemplateConstants.PushPayloadKeys.REMIND_LATER_TIMESTAMP) + ?.toLongOrNull() ?: 0 val remindLaterDuration = - intentExtras.getString(PushTemplateConstants.PushPayloadKeys.REMIND_LATER_DURATION)?.toLongOrNull() ?: 0 + intentExtras.getString(PushTemplateConstants.PushPayloadKeys.REMIND_LATER_DURATION) + ?.toLongOrNull() ?: 0 // calculate difference in fire date from the current date if timestamp is provided val secondsUntilFireDate: Long = if (remindLaterDuration > 0) remindLaterDuration @@ -65,7 +67,11 @@ object RemindLaterHandler { tag?.let { notificationManager.cancel(tag.hashCode()) } throw IllegalArgumentException("Remind later timestamp or duration is less than or equal to current timestamp, cannot schedule notification for later.") } - Log.trace(PushTemplateConstants.LOG_TAG, SELF_TAG, "Remind later pressed, will reschedule the notification to be displayed $secondsUntilFireDate seconds from now") + Log.trace( + PushTemplateConstants.LOG_TAG, + SELF_TAG, + "Remind later pressed, will reschedule the notification to be displayed $secondsUntilFireDate seconds from now" + ) // calculate the trigger time val triggerTimeInSeconds: Long = if (remindLaterDuration > 0) remindLaterDuration + TimeUtils.getUnixTimeInSeconds() @@ -81,7 +87,8 @@ object RemindLaterHandler { tag?.let { notificationManager.cancel(tag.hashCode()) } return } - val scheduledIntent = Intent(PushTemplateConstants.IntentActions.SCHEDULED_NOTIFICATION_BROADCAST) + val scheduledIntent = + Intent(PushTemplateConstants.IntentActions.SCHEDULED_NOTIFICATION_BROADCAST) scheduledIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) scheduledIntent.putExtras(intentExtras) PendingIntentUtils.scheduleNotification(context, scheduledIntent, broadcastReceiverClass, triggerTimeInSeconds) diff --git a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/AutoCarouselNotificationBuilder.kt b/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/AutoCarouselNotificationBuilder.kt index 2b6aabf1..ab390fa4 100644 --- a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/AutoCarouselNotificationBuilder.kt +++ b/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/AutoCarouselNotificationBuilder.kt @@ -20,14 +20,17 @@ import android.widget.RemoteViews import androidx.annotation.VisibleForTesting import androidx.core.app.NotificationCompat import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants +import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.DefaultValues.CAROUSEL_MAX_BITMAP_HEIGHT +import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.DefaultValues.CAROUSEL_MAX_BITMAP_WIDTH import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.LOG_TAG import com.adobe.marketing.mobile.notificationbuilder.R -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils import com.adobe.marketing.mobile.notificationbuilder.internal.extensions.createNotificationChannelIfRequired import com.adobe.marketing.mobile.notificationbuilder.internal.extensions.setRemoteViewClickAction import com.adobe.marketing.mobile.notificationbuilder.internal.templates.AutoCarouselPushTemplate import com.adobe.marketing.mobile.notificationbuilder.internal.templates.CarouselPushTemplate import com.adobe.marketing.mobile.services.Log +import com.adobe.marketing.mobile.utils.AEPUIImageConfig +import com.adobe.marketing.mobile.utils.AEPUIImageUtils /** * Object responsible for constructing a [NotificationCompat.Builder] object containing a auto carousel push template notification. @@ -48,9 +51,14 @@ internal object AutoCarouselNotificationBuilder { val expandedLayout = RemoteViews(packageName, R.layout.push_template_auto_carousel) // load images into the carousel - val downloadedImageCount = PushTemplateImageUtils.cacheImages( - pushTemplate.carouselItems.map { it.imageUri } + val config = AEPUIImageConfig.Builder( + CAROUSEL_MAX_BITMAP_WIDTH.toFloat(), + CAROUSEL_MAX_BITMAP_HEIGHT.toFloat() ) + .urlList(pushTemplate.carouselItems.map { it.imageUri }) + .build() + + val downloadedImageCount = AEPUIImageUtils.cacheImages(config) // fallback to a basic push template notification builder if less than 3 images were able to be downloaded if (downloadedImageCount < PushTemplateConstants.DefaultValues.CAROUSEL_MINIMUM_IMAGE_COUNT) { @@ -115,7 +123,7 @@ internal object AutoCarouselNotificationBuilder { val downloadedImageUris = mutableListOf() for (item: CarouselPushTemplate.CarouselItem in items) { val imageUri: String = item.imageUri - val pushImage: Bitmap? = PushTemplateImageUtils.getCachedImage(imageUri) + val pushImage: Bitmap? = AEPUIImageUtils.getCachedImage(imageUri) if (pushImage == null) { Log.trace( LOG_TAG, diff --git a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ManualCarouselNotificationBuilder.kt b/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ManualCarouselNotificationBuilder.kt index 0c0b3b16..878b51bf 100644 --- a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ManualCarouselNotificationBuilder.kt +++ b/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ManualCarouselNotificationBuilder.kt @@ -23,15 +23,18 @@ import androidx.annotation.VisibleForTesting import androidx.core.app.NotificationCompat import com.adobe.marketing.mobile.notificationbuilder.NotificationConstructionFailedException import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants +import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.DefaultValues.CAROUSEL_MAX_BITMAP_HEIGHT +import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.DefaultValues.CAROUSEL_MAX_BITMAP_WIDTH import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.LOG_TAG import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.PushPayloadKeys import com.adobe.marketing.mobile.notificationbuilder.R -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils import com.adobe.marketing.mobile.notificationbuilder.internal.extensions.createNotificationChannelIfRequired import com.adobe.marketing.mobile.notificationbuilder.internal.extensions.setRemoteViewClickAction import com.adobe.marketing.mobile.notificationbuilder.internal.templates.CarouselPushTemplate import com.adobe.marketing.mobile.notificationbuilder.internal.templates.ManualCarouselPushTemplate import com.adobe.marketing.mobile.services.Log +import com.adobe.marketing.mobile.utils.AEPUIImageConfig +import com.adobe.marketing.mobile.utils.AEPUIImageUtils /** * Object responsible for constructing a [NotificationCompat.Builder] object containing a manual or filmstrip carousel push template notification. @@ -49,13 +52,18 @@ internal object ManualCarouselNotificationBuilder { Log.trace(LOG_TAG, SELF_TAG, "Building a manual carousel template push notification.") // download carousel images - val downloadedImagesCount = PushTemplateImageUtils.cacheImages( - pushTemplate.carouselItems.map { it.imageUri } + val config = AEPUIImageConfig.Builder( + CAROUSEL_MAX_BITMAP_WIDTH.toFloat(), + CAROUSEL_MAX_BITMAP_HEIGHT.toFloat() ) + .urlList(pushTemplate.carouselItems.map { it.imageUri }) + .build() + + val downloadedImageCount = AEPUIImageUtils.cacheImages(config) // fallback to a basic push template notification builder if less than 3 images were able // to be downloaded - if (downloadedImagesCount < PushTemplateConstants.DefaultValues.CAROUSEL_MINIMUM_IMAGE_COUNT) { + if (downloadedImageCount < PushTemplateConstants.DefaultValues.CAROUSEL_MINIMUM_IMAGE_COUNT) { Log.warning(LOG_TAG, SELF_TAG, "Less than 3 images are available for the manual carousel push template, falling back to a basic push template.") return BasicNotificationBuilder.fallbackToBasicNotification( context, @@ -137,7 +145,8 @@ internal object ManualCarouselNotificationBuilder { val validCarouselItems = mutableListOf() for (item: CarouselPushTemplate.CarouselItem in items) { val imageUri: String = item.imageUri - val pushImage: Bitmap? = PushTemplateImageUtils.getCachedImage(imageUri) + val pushImage: Bitmap? = + AEPUIImageUtils.getCachedImage(imageUri) if (pushImage == null) { Log.warning( LOG_TAG, @@ -279,7 +288,8 @@ internal object ManualCarouselNotificationBuilder { ) { for (item: CarouselPushTemplate.CarouselItem in items) { val imageUri = item.imageUri - val pushImage: Bitmap? = PushTemplateImageUtils.getCachedImage(imageUri) + val pushImage: Bitmap? = + AEPUIImageUtils.getCachedImage(imageUri) if (pushImage == null) { Log.warning( LOG_TAG, @@ -346,7 +356,7 @@ internal object ManualCarouselNotificationBuilder { ) // set the downloaded bitmaps in the filmstrip image views - val assetCacheLocation = PushTemplateImageUtils.getAssetCacheLocation() + val assetCacheLocation = AEPUIImageUtils.getAssetCacheLocation() if (assetCacheLocation.isNullOrEmpty()) { Log.warning( LOG_TAG, @@ -356,21 +366,21 @@ internal object ManualCarouselNotificationBuilder { return } - val newLeftImage = PushTemplateImageUtils.getCachedImage( + val newLeftImage = AEPUIImageUtils.getCachedImage( validCarouselItems[newIndices.first].imageUri ) expandedLayout.setImageViewBitmap( R.id.manual_carousel_filmstrip_left, newLeftImage ) - val newCenterImage = PushTemplateImageUtils.getCachedImage( + val newCenterImage = AEPUIImageUtils.getCachedImage( validCarouselItems[newIndices.second].imageUri ) expandedLayout.setImageViewBitmap( R.id.manual_carousel_filmstrip_center, newCenterImage ) - val newRightImage = PushTemplateImageUtils.getCachedImage( + val newRightImage = AEPUIImageUtils.getCachedImage( validCarouselItems[newIndices.third].imageUri ) expandedLayout.setImageViewBitmap( diff --git a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ProductCatalogNotificationBuilder.kt b/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ProductCatalogNotificationBuilder.kt index b03eebdc..9093dc5a 100644 --- a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ProductCatalogNotificationBuilder.kt +++ b/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ProductCatalogNotificationBuilder.kt @@ -20,14 +20,17 @@ import android.widget.RemoteViews import androidx.core.app.NotificationCompat import com.adobe.marketing.mobile.notificationbuilder.NotificationConstructionFailedException import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants +import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.DefaultValues.CAROUSEL_MAX_BITMAP_HEIGHT +import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.DefaultValues.CAROUSEL_MAX_BITMAP_WIDTH import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.LOG_TAG import com.adobe.marketing.mobile.notificationbuilder.R import com.adobe.marketing.mobile.notificationbuilder.internal.PendingIntentUtils -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils import com.adobe.marketing.mobile.notificationbuilder.internal.extensions.createNotificationChannelIfRequired import com.adobe.marketing.mobile.notificationbuilder.internal.extensions.setElementColor import com.adobe.marketing.mobile.notificationbuilder.internal.templates.ProductCatalogPushTemplate import com.adobe.marketing.mobile.services.Log +import com.adobe.marketing.mobile.utils.AEPUIImageConfig +import com.adobe.marketing.mobile.utils.AEPUIImageUtils /** * Object responsible for constructing a [NotificationCompat.Builder] object containing a product catalog template notification. @@ -51,7 +54,15 @@ internal object ProductCatalogNotificationBuilder { // fast fail if we can't download a catalog item image val catalogImageUris = pushTemplate.catalogItems.map { it.img } - downloadedImageCount = PushTemplateImageUtils.cacheImages(catalogImageUris) + val config = AEPUIImageConfig.Builder( + CAROUSEL_MAX_BITMAP_WIDTH.toFloat(), + CAROUSEL_MAX_BITMAP_HEIGHT.toFloat() + ) + .urlList(catalogImageUris) + .build() + + downloadedImageCount = AEPUIImageUtils.cacheImages(config) + if (downloadedImageCount != catalogImageUris.size) { Log.error( LOG_TAG, @@ -146,7 +157,7 @@ internal object ProductCatalogNotificationBuilder { ) val pushImage = - PushTemplateImageUtils.getCachedImage(pushTemplate.catalogItems[pushTemplate.currentIndex].img) + AEPUIImageUtils.getCachedImage(pushTemplate.catalogItems[pushTemplate.currentIndex].img) expandedLayout.setImageViewBitmap(R.id.product_image, pushImage) expandedLayout.setOnClickPendingIntent( R.id.product_image, @@ -190,7 +201,7 @@ internal object ProductCatalogNotificationBuilder { R.id.product_thumbnail_3 ) for (index in catalogItems.indices) { - val thumbImage = PushTemplateImageUtils.getCachedImage(catalogItems[index].img) + val thumbImage = AEPUIImageUtils.getCachedImage(catalogItems[index].img) if (thumbImage == null) { Log.warning( LOG_TAG, diff --git a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ProductRatingNotificationBuilder.kt b/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ProductRatingNotificationBuilder.kt index ceff33da..03b4589c 100644 --- a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ProductRatingNotificationBuilder.kt +++ b/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ProductRatingNotificationBuilder.kt @@ -22,15 +22,18 @@ import android.widget.RemoteViews import androidx.core.app.NotificationCompat import com.adobe.marketing.mobile.notificationbuilder.NotificationConstructionFailedException import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants +import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.DefaultValues.CAROUSEL_MAX_BITMAP_HEIGHT +import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.DefaultValues.CAROUSEL_MAX_BITMAP_WIDTH import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.LOG_TAG import com.adobe.marketing.mobile.notificationbuilder.R -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils import com.adobe.marketing.mobile.notificationbuilder.internal.extensions.createNotificationChannelIfRequired import com.adobe.marketing.mobile.notificationbuilder.internal.extensions.setNotificationTitleTextColor import com.adobe.marketing.mobile.notificationbuilder.internal.extensions.setRemoteViewClickAction import com.adobe.marketing.mobile.notificationbuilder.internal.extensions.setRemoteViewImage import com.adobe.marketing.mobile.notificationbuilder.internal.templates.ProductRatingPushTemplate import com.adobe.marketing.mobile.services.Log +import com.adobe.marketing.mobile.utils.AEPUIImageConfig +import com.adobe.marketing.mobile.utils.AEPUIImageUtils internal object ProductRatingNotificationBuilder { private const val SELF_TAG = "ProductRatingNotificationBuilder" @@ -71,7 +74,14 @@ internal object ProductRatingNotificationBuilder { // set the image on the notification val imageUri = pushTemplate.imageUrl - val downloadedImageCount = PushTemplateImageUtils.cacheImages(listOf(imageUri)) + val config = AEPUIImageConfig.Builder( + CAROUSEL_MAX_BITMAP_WIDTH.toFloat(), + CAROUSEL_MAX_BITMAP_HEIGHT.toFloat() + ) + .urlList(listOf(imageUri)) + .build() + + val downloadedImageCount = AEPUIImageUtils.cacheImages(config) if (downloadedImageCount == 0) { Log.trace( @@ -83,7 +93,7 @@ internal object ProductRatingNotificationBuilder { } else { expandedLayout.setImageViewBitmap( R.id.expanded_template_image, - PushTemplateImageUtils.getCachedImage(imageUri) + AEPUIImageUtils.getCachedImage(imageUri) ) } @@ -108,7 +118,10 @@ internal object ProductRatingNotificationBuilder { // add pending intent for confirm click // sticky is set to false as the notification will be dismissed after confirm click val ratingConfirmedIntentExtras = Bundle(pushTemplate.data.getBundle()) // copy the bundle - ratingConfirmedIntentExtras.putString(PushTemplateConstants.PushPayloadKeys.STICKY, "false") + ratingConfirmedIntentExtras.putString( + PushTemplateConstants.PushPayloadKeys.STICKY, + "false" + ) val selectedRatingAction = pushTemplate.ratingActionList[pushTemplate.ratingSelected] expandedLayout.setRemoteViewClickAction( context, @@ -190,7 +203,10 @@ internal object ProductRatingNotificationBuilder { } Log.trace(LOG_TAG, SELF_TAG, "Creating a rating click pending intent from a push template object.") - val ratingButtonClickIntent = AEPPushNotificationBuilder.createIntent(PushTemplateConstants.IntentActions.RATING_ICON_CLICKED, pushTemplate) + val ratingButtonClickIntent = AEPPushNotificationBuilder.createIntent( + PushTemplateConstants.IntentActions.RATING_ICON_CLICKED, + pushTemplate + ) broadcastReceiverClass.let { ratingButtonClickIntent.setClass(context.applicationContext, broadcastReceiverClass) } diff --git a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/TimerNotificationBuilder.kt b/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/TimerNotificationBuilder.kt index 9845ba90..ca725382 100644 --- a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/TimerNotificationBuilder.kt +++ b/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/TimerNotificationBuilder.kt @@ -173,7 +173,10 @@ internal object TimerNotificationBuilder { * @return the intent for the timer expiry */ private fun createIntent(template: TimerPushTemplate): Intent { - val intent = AEPPushNotificationBuilder.createIntent(PushTemplateConstants.IntentActions.TIMER_EXPIRED, template) + val intent = AEPPushNotificationBuilder.createIntent( + PushTemplateConstants.IntentActions.TIMER_EXPIRED, + template + ) // remove timer to prevent countdown from being recreated intent.removeExtra(TimerKeys.TIMER_DURATION) diff --git a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ZeroBezelNotificationBuilder.kt b/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ZeroBezelNotificationBuilder.kt index e790c970..25bace37 100644 --- a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ZeroBezelNotificationBuilder.kt +++ b/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ZeroBezelNotificationBuilder.kt @@ -18,12 +18,15 @@ import android.view.View import android.widget.RemoteViews import androidx.core.app.NotificationCompat import com.adobe.marketing.mobile.notificationbuilder.NotificationConstructionFailedException +import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.DefaultValues.CAROUSEL_MAX_BITMAP_HEIGHT +import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.DefaultValues.CAROUSEL_MAX_BITMAP_WIDTH import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.LOG_TAG import com.adobe.marketing.mobile.notificationbuilder.R -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils import com.adobe.marketing.mobile.notificationbuilder.internal.extensions.createNotificationChannelIfRequired import com.adobe.marketing.mobile.notificationbuilder.internal.templates.ZeroBezelPushTemplate import com.adobe.marketing.mobile.services.Log +import com.adobe.marketing.mobile.utils.AEPUIImageConfig +import com.adobe.marketing.mobile.utils.AEPUIImageUtils internal object ZeroBezelNotificationBuilder { private const val SELF_TAG = "ZeroBezelNotificationBuilder" @@ -40,14 +43,20 @@ internal object ZeroBezelNotificationBuilder { val expandedLayout = RemoteViews(packageName, R.layout.push_template_zero_bezel_expanded) // download and cache the image used in the notification - val downloadedImageCount = - PushTemplateImageUtils.cacheImages(listOf(pushTemplate.imageUrl)) + val config = AEPUIImageConfig.Builder( + CAROUSEL_MAX_BITMAP_WIDTH.toFloat(), + CAROUSEL_MAX_BITMAP_HEIGHT.toFloat() + ) + .urlList(listOf(pushTemplate.imageUrl)) + .build() + + val downloadedImageCount = AEPUIImageUtils.cacheImages(config) // Check if the image was downloaded if (downloadedImageCount > 0) { // set the image on the notification if it was downloaded val pushImage = - PushTemplateImageUtils.getCachedImage(pushTemplate.imageUrl) + AEPUIImageUtils.getCachedImage(pushTemplate.imageUrl) expandedLayout.setImageViewBitmap(R.id.expanded_template_image, pushImage) // only set image on the collapsed view if the style is "img" diff --git a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/extensions/NotificationCompatBuilderExtensions.kt b/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/extensions/NotificationCompatBuilderExtensions.kt index 3d82a06d..5db1a057 100644 --- a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/extensions/NotificationCompatBuilderExtensions.kt +++ b/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/extensions/NotificationCompatBuilderExtensions.kt @@ -21,11 +21,14 @@ import android.os.Bundle import androidx.core.app.NotificationCompat import com.adobe.marketing.mobile.MobileCore import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants +import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.DefaultValues.CAROUSEL_MAX_BITMAP_HEIGHT +import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.DefaultValues.CAROUSEL_MAX_BITMAP_WIDTH import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.LOG_TAG import com.adobe.marketing.mobile.notificationbuilder.internal.PendingIntentUtils -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils import com.adobe.marketing.mobile.notificationbuilder.internal.templates.BasicPushTemplate import com.adobe.marketing.mobile.services.Log +import com.adobe.marketing.mobile.utils.AEPUIImageConfig +import com.adobe.marketing.mobile.utils.AEPUIImageUtils import java.util.Random private const val SELF_TAG = "RemoteViewExtensions" @@ -156,16 +159,21 @@ internal fun NotificationCompat.Builder.setLargeIcon( ): NotificationCompat.Builder { // Quick bail out if there is no image url if (imageUrl.isNullOrEmpty()) return this - val downloadedIconCount: Int = PushTemplateImageUtils.cacheImages( - listOf(imageUrl) + val config = AEPUIImageConfig.Builder( + CAROUSEL_MAX_BITMAP_WIDTH.toFloat(), + CAROUSEL_MAX_BITMAP_HEIGHT.toFloat() ) + .urlList(listOf(imageUrl)) + .build() + + val downloadedIconCount = AEPUIImageUtils.cacheImages(config) // Bail out if the download fails if (downloadedIconCount == 0) { return this } - val bitmap = PushTemplateImageUtils.getCachedImage(imageUrl) + val bitmap = AEPUIImageUtils.getCachedImage(imageUrl) setLargeIcon(bitmap) val bigPictureStyle = NotificationCompat.BigPictureStyle() bigPictureStyle.bigPicture(bitmap) diff --git a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/extensions/RemoteViewsExtensions.kt b/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/extensions/RemoteViewsExtensions.kt index 61520901..cc45086b 100644 --- a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/extensions/RemoteViewsExtensions.kt +++ b/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/extensions/RemoteViewsExtensions.kt @@ -19,12 +19,15 @@ import android.os.Bundle import android.view.View import android.widget.RemoteViews import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants +import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.DefaultValues.CAROUSEL_MAX_BITMAP_HEIGHT +import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.DefaultValues.CAROUSEL_MAX_BITMAP_WIDTH import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.LOG_TAG import com.adobe.marketing.mobile.notificationbuilder.internal.PendingIntentUtils -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils import com.adobe.marketing.mobile.services.Log import com.adobe.marketing.mobile.services.ServiceProvider import com.adobe.marketing.mobile.util.UrlUtils +import com.adobe.marketing.mobile.utils.AEPUIImageConfig +import com.adobe.marketing.mobile.utils.AEPUIImageUtils private const val SELF_TAG = "RemoteViewExtensions" @@ -222,7 +225,15 @@ internal fun RemoteViews.setRemoteImage( if (!UrlUtils.isValidUrl(imageUrl)) { return false } - val downloadedIconCount = PushTemplateImageUtils.cacheImages(listOf(imageUrl)) + val config = AEPUIImageConfig.Builder( + CAROUSEL_MAX_BITMAP_WIDTH.toFloat(), + CAROUSEL_MAX_BITMAP_HEIGHT.toFloat() + ) + .urlList(listOf(imageUrl)) + .build() + + val downloadedIconCount = AEPUIImageUtils.cacheImages(config) + if (downloadedIconCount == 0) { Log.warning( LOG_TAG, @@ -234,7 +245,7 @@ internal fun RemoteViews.setRemoteImage( } setImageViewBitmap( containerViewId, - PushTemplateImageUtils.getCachedImage(imageUrl) + AEPUIImageUtils.getCachedImage(imageUrl) ) return true } diff --git a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/templates/ProductRatingPushTemplate.kt b/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/templates/ProductRatingPushTemplate.kt index a88a1b0b..550231fc 100644 --- a/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/templates/ProductRatingPushTemplate.kt +++ b/code/notificationbuilder/src/main/java/com/adobe/marketing/mobile/notificationbuilder/internal/templates/ProductRatingPushTemplate.kt @@ -34,7 +34,11 @@ internal class ProductRatingPushTemplate(data: NotificationData) : AEPPushTempla fun from(jsonObject: JSONObject): RatingAction? { return try { var uri: String? = null - val type = PushTemplateConstants.ActionType.valueOf(jsonObject.getString(PushTemplateConstants.RatingAction.TYPE)) + val type = PushTemplateConstants.ActionType.valueOf( + jsonObject.getString( + PushTemplateConstants.RatingAction.TYPE + ) + ) if (type == PushTemplateConstants.ActionType.WEBURL || type == PushTemplateConstants.ActionType.DEEPLINK) { uri = jsonObject.getString(PushTemplateConstants.RatingAction.URI) } diff --git a/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/NotificationBuilderTests.kt b/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/NotificationBuilderTests.kt index 08a672e7..f558432b 100644 --- a/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/NotificationBuilderTests.kt +++ b/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/NotificationBuilderTests.kt @@ -20,7 +20,6 @@ import android.content.Context import android.content.Intent import androidx.core.app.NotificationManagerCompat import com.adobe.marketing.mobile.notificationbuilder.internal.PendingIntentUtils -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateType import com.adobe.marketing.mobile.notificationbuilder.internal.builders.AutoCarouselNotificationBuilder import com.adobe.marketing.mobile.notificationbuilder.internal.builders.BasicNotificationBuilder @@ -38,6 +37,8 @@ import com.adobe.marketing.mobile.notificationbuilder.internal.templates.MockPro import com.adobe.marketing.mobile.notificationbuilder.internal.templates.MockTimerTemplateDataProvider import com.adobe.marketing.mobile.services.AppContextService import com.adobe.marketing.mobile.services.ServiceProvider +import com.adobe.marketing.mobile.utils.AEPUIImageConfig +import com.adobe.marketing.mobile.utils.AEPUIImageUtils import io.mockk.every import io.mockk.mockk import io.mockk.mockkClass @@ -76,7 +77,7 @@ class NotificationBuilderTests { trackerActivityClass = mockkClass(Activity::class, relaxed = true).javaClass broadcastReceiverClass = mockkClass(BroadcastReceiver::class, relaxed = true).javaClass mockkObject(PendingIntentUtils) - mockkObject(PushTemplateImageUtils) + mockkObject(AEPUIImageUtils) } @After @@ -250,7 +251,7 @@ class NotificationBuilderTests { @Test fun `verify private createNotificationBuilder calls ProductRatingNotificationBuilder construct`() { - every { PushTemplateImageUtils.cacheImages(any()) } answers { 1 } + every { AEPUIImageUtils.cacheImages(any()) } answers { 1 } val mapData = MockAEPPushTemplateDataProvider.getMockedAEPDataMapWithAllKeys() mapData[PushTemplateConstants.PushPayloadKeys.TEMPLATE_TYPE] = PushTemplateType.PRODUCT_RATING.value mapData[PushTemplateConstants.PushPayloadKeys.RATING_UNSELECTED_ICON] = "https://i.imgur.com/unselected.png" @@ -262,8 +263,8 @@ class NotificationBuilderTests { @Test fun `verify private createNotificationBuilder calls ProductCatalogNotificationBuilder construct`() { - every { PushTemplateImageUtils.cacheImages(any()) } answers { 3 } - every { PushTemplateImageUtils.getCachedImage(any()) } answers { mockk() } + every { AEPUIImageUtils.cacheImages(any()) } answers { 3 } + every { AEPUIImageUtils.getCachedImage(any()) } answers { mockk() } val mapData = MockProductCatalogTemplateDataProvider.getMockedMapWithProductCatalogData() mapData[PushTemplateConstants.PushPayloadKeys.TEMPLATE_TYPE] = PushTemplateType.PRODUCT_CATALOG.value NotificationBuilder.constructNotificationBuilder(mapData, trackerActivityClass, broadcastReceiverClass) @@ -272,8 +273,8 @@ class NotificationBuilderTests { @Test fun `verify private createNotificationBuilder calls MultiIconNotificationBuilder construct`() { - every { PushTemplateImageUtils.cacheImages(any()) } answers { 3 } - every { PushTemplateImageUtils.getCachedImage(any()) } answers { mockk() } + every { AEPUIImageUtils.cacheImages(any()) } answers { 3 } + every { AEPUIImageUtils.getCachedImage(any()) } answers { mockk() } val mapData = MockAEPPushTemplateDataProvider.getMockedAEPDataMapWithAllKeys() mapData[PushTemplateConstants.PushPayloadKeys.TEMPLATE_TYPE] = PushTemplateType.MULTI_ICON.value mapData[PushTemplateConstants.PushPayloadKeys.MULTI_ICON_ITEMS] = "[{\"img\":\"https://sneakerland.com/products/assets/shoe1.png\",\"uri\":\"myapp://chooseShoeType/shoe1\",\"type\":\"DEEPLINK\"},{\"img\":\"https://sneakerland.com/products/assets/shoe2.png\",\"uri\":\"myapp://chooseShoeType/shoe2\",\"type\":\"DEEPLINK\"},{\"img\":\"https://sneakerland.com/products/assets/shoe3.png\",\"uri\":\"myapp://chooseShoeType/shoe3\",\"type\":\"DEEPLINK\"},{\"img\":\"https://sneakerland.com/products/assets/shoe4.png\",\"uri\":\"myapp://chooseShoeType/shoe4\",\"type\":\"DEEPLINK\"},{\"img\":\"https://sneakerland.com/products/assets/shoe5.png\",\"uri\":\"myapp://chooseShoeType/shoe5\",\"type\":\"DEEPLINK\"}]" diff --git a/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/AutoCarouselNotificationBuilderTest.kt b/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/AutoCarouselNotificationBuilderTest.kt index 25c6e0ae..663e6833 100644 --- a/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/AutoCarouselNotificationBuilderTest.kt +++ b/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/AutoCarouselNotificationBuilderTest.kt @@ -17,12 +17,13 @@ import android.content.Context import android.graphics.Bitmap import android.widget.RemoteViews import com.adobe.marketing.mobile.notificationbuilder.internal.PendingIntentUtils -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils.cacheImages -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils.getCachedImage import com.adobe.marketing.mobile.notificationbuilder.internal.extensions.setRemoteViewClickAction import com.adobe.marketing.mobile.notificationbuilder.internal.templates.AutoCarouselPushTemplate import com.adobe.marketing.mobile.notificationbuilder.internal.templates.provideMockedAutoCarousalTemplate +import com.adobe.marketing.mobile.utils.AEPUIImageConfig +import com.adobe.marketing.mobile.utils.AEPUIImageUtils +import com.adobe.marketing.mobile.utils.AEPUIImageUtils.cacheImages +import com.adobe.marketing.mobile.utils.AEPUIImageUtils.getCachedImage import io.mockk.Runs import io.mockk.every import io.mockk.just @@ -61,7 +62,7 @@ class AutoCarouselNotificationBuilderTest { autoCarouselPushTemplate = provideMockedAutoCarousalTemplate(false) mockkObject(BasicNotificationBuilder) mockkObject(PendingIntentUtils) - mockkObject(PushTemplateImageUtils) + mockkObject(AEPUIImageUtils) mockkConstructor(RemoteViews::class) } @@ -83,7 +84,7 @@ class AutoCarouselNotificationBuilderTest { @Test fun `construct returns BasicNotificationBuilder if less than 3 images were downloaded`() { - every { cacheImages(any()) } answers { 2 } + every { cacheImages(any()) } answers { 2 } AutoCarouselNotificationBuilder.construct( context, autoCarouselPushTemplate, @@ -102,7 +103,7 @@ class AutoCarouselNotificationBuilderTest { @Test fun `construct does not fallback to BasicNotificationBuilder if greater than or equal to 3 images were downloaded`() { - every { cacheImages(any()) } answers { 3 } + every { cacheImages(any()) } answers { 3 } AutoCarouselNotificationBuilder.construct( context, autoCarouselPushTemplate, diff --git a/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/BasicNotificationBuilderTest.kt b/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/BasicNotificationBuilderTest.kt index e2a3414a..96366abb 100644 --- a/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/BasicNotificationBuilderTest.kt +++ b/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/BasicNotificationBuilderTest.kt @@ -19,7 +19,6 @@ import android.widget.RemoteViews import androidx.core.app.NotificationCompat import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants import com.adobe.marketing.mobile.notificationbuilder.R -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils import com.adobe.marketing.mobile.notificationbuilder.internal.extensions.setRemoteViewImage import com.adobe.marketing.mobile.notificationbuilder.internal.templates.BasicPushTemplate import com.adobe.marketing.mobile.notificationbuilder.internal.templates.MOCKED_CHANNEL_ID @@ -33,6 +32,7 @@ import com.adobe.marketing.mobile.notificationbuilder.internal.templates.MockAEP import com.adobe.marketing.mobile.notificationbuilder.internal.templates.provideMockedBasicPushTemplateWithAllKeys import com.adobe.marketing.mobile.notificationbuilder.internal.templates.provideMockedBasicPushTemplateWithRequiredData import com.adobe.marketing.mobile.notificationbuilder.internal.util.MapData +import com.adobe.marketing.mobile.utils.AEPUIImageUtils import io.mockk.every import io.mockk.mockkConstructor import io.mockk.mockkObject @@ -72,7 +72,7 @@ class BasicNotificationBuilderTest { mockkConstructor(RemoteViews::class) mockkStatic(RemoteViews::setRemoteViewImage) - mockkObject(PushTemplateImageUtils) + mockkObject(AEPUIImageUtils) } @After diff --git a/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ManualCarouselNotificationBuilderTest.kt b/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ManualCarouselNotificationBuilderTest.kt index a2b6f909..84f71755 100644 --- a/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ManualCarouselNotificationBuilderTest.kt +++ b/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ManualCarouselNotificationBuilderTest.kt @@ -19,10 +19,6 @@ import android.graphics.Bitmap import android.widget.RemoteViews import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants import com.adobe.marketing.mobile.notificationbuilder.internal.PendingIntentUtils -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils.cacheImages -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils.getAssetCacheLocation -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils.getCachedImage import com.adobe.marketing.mobile.notificationbuilder.internal.builders.ManualCarouselNotificationBuilder.downloadCarouselItems import com.adobe.marketing.mobile.notificationbuilder.internal.builders.ManualCarouselNotificationBuilder.getCarouselIndices import com.adobe.marketing.mobile.notificationbuilder.internal.builders.ManualCarouselNotificationBuilder.populateFilmstripCarouselImages @@ -34,6 +30,11 @@ import com.adobe.marketing.mobile.notificationbuilder.internal.templates.ManualC import com.adobe.marketing.mobile.notificationbuilder.internal.templates.MockCarousalTemplateDataProvider import com.adobe.marketing.mobile.notificationbuilder.internal.templates.provideMockedManualCarousalTemplate import com.adobe.marketing.mobile.notificationbuilder.internal.util.IntentData +import com.adobe.marketing.mobile.utils.AEPUIImageConfig +import com.adobe.marketing.mobile.utils.AEPUIImageUtils +import com.adobe.marketing.mobile.utils.AEPUIImageUtils.cacheImages +import com.adobe.marketing.mobile.utils.AEPUIImageUtils.getAssetCacheLocation +import com.adobe.marketing.mobile.utils.AEPUIImageUtils.getCachedImage import io.mockk.Runs import io.mockk.every import io.mockk.just @@ -70,7 +71,7 @@ class ManualCarouselNotificationBuilderTest { pushTemplate = provideMockedManualCarousalTemplate(false) trackerActivityClass = mockkClass(Activity::class, relaxed = true).javaClass broadcastReceiverClass = mockkClass(BroadcastReceiver::class, relaxed = true).javaClass - mockkObject(PushTemplateImageUtils) + mockkObject(AEPUIImageUtils) mockkObject(BasicNotificationBuilder) mockkObject(PendingIntentUtils) mockkConstructor(RemoteViews::class) @@ -95,7 +96,7 @@ class ManualCarouselNotificationBuilderTest { @Test fun `construct returns BasicNotificationBuilder if download image count is less than 3`() { - every { cacheImages(any()) } answers { 2 } + every { cacheImages(any()) } answers { 2 } ManualCarouselNotificationBuilder.construct( context, pushTemplate, @@ -114,7 +115,7 @@ class ManualCarouselNotificationBuilderTest { @Test fun `construct returns ManualCarouselNotificationBuilder if download image count is equal to 3`() { - every { cacheImages(any()) } answers { 3 } + every { cacheImages(any()) } answers { 3 } ManualCarouselNotificationBuilder.construct( context, pushTemplate, @@ -133,7 +134,7 @@ class ManualCarouselNotificationBuilderTest { @Test fun `construct returns ManualCarouselNotificationBuilder if download image count is greater than 3`() { - every { cacheImages(any()) } answers { 5 } + every { cacheImages(any()) } answers { 5 } ManualCarouselNotificationBuilder.construct( context, pushTemplate, @@ -153,7 +154,7 @@ class ManualCarouselNotificationBuilderTest { @Test fun `construct ManualCarouselNotificationBuilder shouldn't be called if downloadCarouselItems failed to download some of the images`() { var callCount = 0 - every { cacheImages(any()) } answers { 5 } + every { cacheImages(any()) } answers { 5 } every { getCachedImage(any()) } answers { if (callCount++ % 2 == 0) mockkClass(Bitmap::class) else null } verify(exactly = 0) { ManualCarouselNotificationBuilder.construct( @@ -224,7 +225,7 @@ class ManualCarouselNotificationBuilderTest { @Test fun `test to verify notification with action name MANUAL_CAROUSEL_LEFT_CLICKED is having correct center image index`() { - every { cacheImages(any()) } answers { 5 } + every { cacheImages(any()) } answers { 5 } every { getCachedImage(any()) } answers { mockkClass(Bitmap::class) } val mockBundle = MockCarousalTemplateDataProvider.getMockedBundleWithManualCarouselData() val data = IntentData(mockBundle, PushTemplateConstants.IntentActions.MANUAL_CAROUSEL_LEFT_CLICKED) @@ -240,7 +241,7 @@ class ManualCarouselNotificationBuilderTest { @Test fun `test to verify notification with action name MANUAL_CAROUSEL_RIGHT_CLICKED is having correct center image index`() { - every { cacheImages(any()) } answers { 5 } + every { cacheImages(any()) } answers { 5 } every { getCachedImage(any()) } answers { mockkClass(Bitmap::class) } val mockBundle = MockCarousalTemplateDataProvider.getMockedBundleWithManualCarouselData() val data = IntentData(mockBundle, PushTemplateConstants.IntentActions.MANUAL_CAROUSEL_RIGHT_CLICKED) @@ -256,7 +257,7 @@ class ManualCarouselNotificationBuilderTest { @Test fun `test to verify notification with action name FILMSTRIP_LEFT_CLICKED is having correct center image index`() { - every { cacheImages(any()) } answers { 5 } + every { cacheImages(any()) } answers { 5 } every { getCachedImage(any()) } answers { mockkClass(Bitmap::class) } val mockBundle = MockCarousalTemplateDataProvider.getMockedBundleWithManualCarouselData() mockBundle.putString(PushTemplateConstants.PushPayloadKeys.CAROUSEL_LAYOUT, PushTemplateConstants.DefaultValues.FILMSTRIP_CAROUSEL_MODE) @@ -274,7 +275,7 @@ class ManualCarouselNotificationBuilderTest { @Test fun `test to verify notification with action name FILMSTRIP_RIGHT_CLICKED is having correct center image index`() { - every { cacheImages(any()) } answers { 5 } + every { cacheImages(any()) } answers { 5 } every { getCachedImage(any()) } answers { mockkClass(Bitmap::class) } val mockBundle = MockCarousalTemplateDataProvider.getMockedBundleWithManualCarouselData() mockBundle.putString(PushTemplateConstants.PushPayloadKeys.CAROUSEL_LAYOUT, PushTemplateConstants.DefaultValues.FILMSTRIP_CAROUSEL_MODE) diff --git a/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ProductCatalogNotificationBuilderTest.kt b/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ProductCatalogNotificationBuilderTest.kt index 9e0bc29f..8e64bee2 100644 --- a/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ProductCatalogNotificationBuilderTest.kt +++ b/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ProductCatalogNotificationBuilderTest.kt @@ -20,14 +20,15 @@ import com.adobe.marketing.mobile.notificationbuilder.NotificationConstructionFa import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants.DefaultValues.PRODUCT_CATALOG_VERTICAL_LAYOUT import com.adobe.marketing.mobile.notificationbuilder.R -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils.cacheImages -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils.getCachedImage import com.adobe.marketing.mobile.notificationbuilder.internal.templates.MockProductCatalogTemplateDataProvider.getMockedMapWithProductCatalogData import com.adobe.marketing.mobile.notificationbuilder.internal.templates.ProductCatalogPushTemplate import com.adobe.marketing.mobile.notificationbuilder.internal.templates.provideMockedProductCatalogTemplate import com.adobe.marketing.mobile.notificationbuilder.internal.templates.replaceValueInMap import com.adobe.marketing.mobile.notificationbuilder.internal.util.MapData +import com.adobe.marketing.mobile.utils.AEPUIImageConfig +import com.adobe.marketing.mobile.utils.AEPUIImageUtils +import com.adobe.marketing.mobile.utils.AEPUIImageUtils.cacheImages +import com.adobe.marketing.mobile.utils.AEPUIImageUtils.getCachedImage import io.mockk.every import io.mockk.mockkClass import io.mockk.mockkObject @@ -59,7 +60,7 @@ class ProductCatalogNotificationBuilderTest { context = RuntimeEnvironment.getApplication() trackerActivityClass = mockkClass(Activity::class, relaxed = true).javaClass broadcastReceiverClass = mockkClass(BroadcastReceiver::class, relaxed = true).javaClass - mockkObject(PushTemplateImageUtils) + mockkObject(AEPUIImageUtils) } @After @@ -101,7 +102,7 @@ class ProductCatalogNotificationBuilderTest { val cachedItem = mockkClass(Bitmap::class) // product catalog template requires 3 catalog items - every { cacheImages(any()) } answers { 4 } + every { cacheImages(any()) } answers { 4 } every { getCachedImage(any()) } answers { cachedItem } ProductCatalogNotificationBuilder.construct(context, pushTemplate, trackerActivityClass, broadcastReceiverClass) } @@ -127,7 +128,7 @@ class ProductCatalogNotificationBuilderTest { val cachedItem = mockkClass(Bitmap::class) // product catalog template requires 3 catalog items - every { cacheImages(any()) } answers { 2 } + every { cacheImages(any()) } answers { 2 } every { getCachedImage(any()) } answers { cachedItem } ProductCatalogNotificationBuilder.construct(context, pushTemplate, trackerActivityClass, broadcastReceiverClass) } @@ -140,7 +141,7 @@ class ProductCatalogNotificationBuilderTest { val cachedItem = mockkClass(Bitmap::class) // product catalog template requires 3 catalog items - every { cacheImages(any()) } answers { 3 } + every { cacheImages(any()) } answers { 3 } every { getCachedImage(any()) } answers { cachedItem } val notificationBuilder = ProductCatalogNotificationBuilder.construct(context, pushTemplate, trackerActivityClass, broadcastReceiverClass) @@ -156,7 +157,7 @@ class ProductCatalogNotificationBuilderTest { val cachedItem = mockkClass(Bitmap::class) // product catalog template requires 3 catalog items - every { cacheImages(any()) } answers { 3 } + every { cacheImages(any()) } answers { 3 } every { getCachedImage(any()) } answers { cachedItem } val notificationBuilder = ProductCatalogNotificationBuilder.construct(context, pushTemplate, trackerActivityClass, broadcastReceiverClass) @@ -170,7 +171,7 @@ class ProductCatalogNotificationBuilderTest { val cachedItem = mockkClass(Bitmap::class) // product catalog template requires 3 catalog items - every { cacheImages(any()) } answers { 3 } + every { cacheImages(any()) } answers { 3 } every { getCachedImage(any()) } answers { cachedItem } val notificationBuilder = ProductCatalogNotificationBuilder.construct(context, pushTemplate, trackerActivityClass, null) @@ -180,7 +181,7 @@ class ProductCatalogNotificationBuilderTest { @Test fun `construct should throw NotificationConstructionFailedException if catalog thumbnail is not found`() { val pushTemplate = provideMockedProductCatalogTemplate() - every { cacheImages(any()) } answers { 3 } + every { cacheImages(any()) } answers { 3 } assertFailsWith( exceptionClass = NotificationConstructionFailedException::class, @@ -199,7 +200,7 @@ class ProductCatalogNotificationBuilderTest { val cachedItem = mockkClass(Bitmap::class) // product catalog template requires 3 catalog items - every { cacheImages(any()) } answers { 3 } + every { cacheImages(any()) } answers { 3 } every { getCachedImage(any()) } answers { cachedItem } val notificationBuilder = ProductCatalogNotificationBuilder.construct(context, pushTemplate, trackerActivityClass, broadcastReceiverClass) diff --git a/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ProductRatingNotificationBuilderTest.kt b/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ProductRatingNotificationBuilderTest.kt index 0cf9da7e..b6714eb2 100644 --- a/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ProductRatingNotificationBuilderTest.kt +++ b/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ProductRatingNotificationBuilderTest.kt @@ -21,15 +21,16 @@ import androidx.core.app.NotificationCompat import com.adobe.marketing.mobile.notificationbuilder.NotificationConstructionFailedException import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants import com.adobe.marketing.mobile.notificationbuilder.R -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils.cacheImages -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils.getCachedImage import com.adobe.marketing.mobile.notificationbuilder.internal.extensions.setRemoteViewClickAction import com.adobe.marketing.mobile.notificationbuilder.internal.extensions.setRemoteViewImage import com.adobe.marketing.mobile.notificationbuilder.internal.templates.MockProductRatingTemplateDataProvider.getMockedDataMapForRatingTemplate import com.adobe.marketing.mobile.notificationbuilder.internal.templates.ProductRatingPushTemplate import com.adobe.marketing.mobile.notificationbuilder.internal.templates.provideMockedProductRatingTemplate import com.adobe.marketing.mobile.notificationbuilder.internal.util.MapData +import com.adobe.marketing.mobile.utils.AEPUIImageConfig +import com.adobe.marketing.mobile.utils.AEPUIImageUtils +import com.adobe.marketing.mobile.utils.AEPUIImageUtils.cacheImages +import com.adobe.marketing.mobile.utils.AEPUIImageUtils.getCachedImage import io.mockk.Runs import io.mockk.every import io.mockk.just @@ -64,7 +65,7 @@ class ProductRatingNotificationBuilderTest { mockkConstructor(RemoteViews::class) mockkStatic(RemoteViews::setRemoteViewImage) mockkStatic(RemoteViews::setRemoteViewClickAction) - mockkObject(PushTemplateImageUtils) + mockkObject(AEPUIImageUtils) } @After @@ -87,7 +88,7 @@ class ProductRatingNotificationBuilderTest { @Test fun `construct should set visibility of expanded layout image view as GONE if no images are downloaded`() { - every { cacheImages(any()) } answers { 0 } + every { cacheImages(any()) } answers { 0 } every { any().setRemoteViewImage(any(), any()) } returns true every { anyConstructed().setViewVisibility(any(), View.GONE) } just Runs @@ -101,7 +102,7 @@ class ProductRatingNotificationBuilderTest { fun `construct should set image for expanded layout if image is downloaded successfully`() { val cachedItem = mockkClass(Bitmap::class) - every { cacheImages(any()) } answers { 1 } + every { cacheImages(any()) } answers { 1 } every { getCachedImage(any()) } answers { cachedItem } every { any().setRemoteViewImage(any(), any()) } returns true every { anyConstructed().setViewVisibility(any(), View.GONE) } just Runs diff --git a/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/TimerNotificationBuilderTests.kt b/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/TimerNotificationBuilderTests.kt index 6df12b2e..cad1fe2a 100644 --- a/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/TimerNotificationBuilderTests.kt +++ b/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/TimerNotificationBuilderTests.kt @@ -21,7 +21,6 @@ import android.service.notification.StatusBarNotification import android.widget.RemoteViews import com.adobe.marketing.mobile.notificationbuilder.NotificationConstructionFailedException import com.adobe.marketing.mobile.notificationbuilder.internal.PendingIntentUtils -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils import com.adobe.marketing.mobile.notificationbuilder.internal.extensions.setRemoteViewImage import com.adobe.marketing.mobile.notificationbuilder.internal.extensions.setTimerTextColor import com.adobe.marketing.mobile.notificationbuilder.internal.templates.MOCKED_ALT_BODY @@ -35,6 +34,7 @@ import com.adobe.marketing.mobile.notificationbuilder.internal.templates.MOCKED_ import com.adobe.marketing.mobile.notificationbuilder.internal.templates.MOCKED_TITLE import com.adobe.marketing.mobile.notificationbuilder.internal.templates.TimerPushTemplate import com.adobe.marketing.mobile.notificationbuilder.internal.templates.provideMockedTimerTemplate +import com.adobe.marketing.mobile.utils.AEPUIImageUtils import io.mockk.Runs import io.mockk.every import io.mockk.just @@ -76,7 +76,7 @@ class TimerNotificationBuilderTests { pushTemplate = provideMockedTimerTemplate(false, true) trackerActivityClass = mockkClass(Activity::class, relaxed = true).javaClass broadcastReceiverClass = mockkClass(BroadcastReceiver::class, relaxed = true).javaClass - mockkObject(PushTemplateImageUtils) + mockkObject(AEPUIImageUtils) mockkObject(PendingIntentUtils) mockkConstructor(RemoteViews::class) mockkStatic(RemoteViews::setTimerTextColor) diff --git a/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ZeroBezelNotificationBuilderTest.kt b/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ZeroBezelNotificationBuilderTest.kt index 66f2796e..3c257ea4 100644 --- a/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ZeroBezelNotificationBuilderTest.kt +++ b/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/builders/ZeroBezelNotificationBuilderTest.kt @@ -19,14 +19,15 @@ import android.os.Bundle import android.view.View import android.widget.RemoteViews import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils.cacheImages -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils.getCachedImage import com.adobe.marketing.mobile.notificationbuilder.internal.templates.MockAEPPushTemplateDataProvider import com.adobe.marketing.mobile.notificationbuilder.internal.templates.ZeroBezelPushTemplate import com.adobe.marketing.mobile.notificationbuilder.internal.templates.replaceValueInMap import com.adobe.marketing.mobile.notificationbuilder.internal.util.IntentData import com.adobe.marketing.mobile.notificationbuilder.internal.util.MapData +import com.adobe.marketing.mobile.utils.AEPUIImageConfig +import com.adobe.marketing.mobile.utils.AEPUIImageUtils +import com.adobe.marketing.mobile.utils.AEPUIImageUtils.cacheImages +import com.adobe.marketing.mobile.utils.AEPUIImageUtils.getCachedImage import io.mockk.Runs import io.mockk.every import io.mockk.just @@ -60,7 +61,7 @@ class ZeroBezelNotificationBuilderTest { fun setup() { context = RuntimeEnvironment.getApplication() dataMap = MockAEPPushTemplateDataProvider.getMockedAEPDataMapWithAllKeys() - mockkObject(PushTemplateImageUtils) + mockkObject(AEPUIImageUtils) mockkConstructor(RemoteViews::class) mockBitmap = mockk(relaxed = true) trackerActivityClass = DummyActivity::class.java @@ -76,7 +77,7 @@ class ZeroBezelNotificationBuilderTest { @Test fun `verify construct with image downloaded and collapsedStyle is img`() { val pushTemplate = ZeroBezelPushTemplate(MapData(dataMap)) - every { cacheImages(any()) } answers { 2 } + every { cacheImages(any()) } answers { 2 } every { anyConstructed().setImageViewBitmap(any(), mockBitmap) } just Runs val notification = ZeroBezelNotificationBuilder.construct( @@ -87,7 +88,7 @@ class ZeroBezelNotificationBuilderTest { assertEquals(pushTemplate.channelId, notification.channelId) verifyNotificationDataFields(notification, pushTemplate) - verify { cacheImages(listOf(pushTemplate.imageUrl)) } + verify { cacheImages(any()) } verify { getCachedImage(pushTemplate.imageUrl) } verify { anyConstructed().setImageViewBitmap(any(), mockBitmap) } } @@ -102,7 +103,7 @@ class ZeroBezelNotificationBuilderTest { ) val pushTemplate = ZeroBezelPushTemplate(MapData(dataMap)) - every { cacheImages(any()) } answers { 2 } + every { cacheImages(any()) } answers { 2 } every { anyConstructed().setImageViewBitmap(any(), mockBitmap) } just Runs every { anyConstructed().setViewVisibility(any(), View.GONE) } just Runs @@ -114,7 +115,7 @@ class ZeroBezelNotificationBuilderTest { assertEquals(pushTemplate.channelId, notification.channelId) verifyNotificationDataFields(notification, pushTemplate) - verify { cacheImages(listOf(pushTemplate.imageUrl)) } + verify { cacheImages(any()) } verify { getCachedImage(pushTemplate.imageUrl) } verify { anyConstructed().setImageViewBitmap(any(), mockBitmap) } verify { anyConstructed().setViewVisibility(any(), View.GONE) } @@ -124,7 +125,7 @@ class ZeroBezelNotificationBuilderTest { fun `verify construct with no image downloaded`() { val pushTemplate = ZeroBezelPushTemplate(MapData(dataMap)) - every { cacheImages(listOf(pushTemplate.imageUrl)) } returns 0 + every { cacheImages(any()) } returns 0 every { anyConstructed().setViewVisibility(any(), View.GONE) } just Runs val notification = ZeroBezelNotificationBuilder.construct( @@ -135,14 +136,14 @@ class ZeroBezelNotificationBuilderTest { assertEquals(pushTemplate.channelId, notification.channelId) verifyNotificationDataFields(notification, pushTemplate) - verify { cacheImages(listOf(pushTemplate.imageUrl)) } + verify { cacheImages(any()) } verify { anyConstructed().setViewVisibility(any(), View.GONE) } } @Test fun `verify construct with image downloaded and collapsedStyle is img for IntentData`() { val pushTemplate = ZeroBezelPushTemplate(IntentData(mockBundle, null)) - every { cacheImages(any()) } answers { 2 } + every { cacheImages(any()) } answers { 2 } every { anyConstructed().setImageViewBitmap(any(), mockBitmap) } just Runs val notification = ZeroBezelNotificationBuilder.construct( @@ -156,7 +157,7 @@ class ZeroBezelNotificationBuilderTest { notification.channelId ) verifyNotificationDataFields(notification, pushTemplate) - verify { cacheImages(listOf(pushTemplate.imageUrl)) } + verify { cacheImages(any()) } verify { getCachedImage(pushTemplate.imageUrl) } verify { anyConstructed().setImageViewBitmap(any(), mockBitmap) } } @@ -169,7 +170,7 @@ class ZeroBezelNotificationBuilderTest { ) val pushTemplate = ZeroBezelPushTemplate(IntentData(mockBundle, null)) - every { cacheImages(any()) } answers { 2 } + every { cacheImages(any()) } answers { 2 } every { anyConstructed().setImageViewBitmap(any(), mockBitmap) } just Runs every { anyConstructed().setViewVisibility(any(), View.GONE) } just Runs @@ -184,7 +185,7 @@ class ZeroBezelNotificationBuilderTest { notification.channelId ) verifyNotificationDataFields(notification, pushTemplate) - verify { cacheImages(listOf(pushTemplate.imageUrl)) } + verify { cacheImages(any()) } verify { getCachedImage(pushTemplate.imageUrl) } verify { anyConstructed().setImageViewBitmap(any(), mockBitmap) } verify { anyConstructed().setViewVisibility(any(), View.GONE) } @@ -193,7 +194,7 @@ class ZeroBezelNotificationBuilderTest { @Test fun `verify construct with no image downloaded for IntentData`() { val pushTemplate = ZeroBezelPushTemplate(IntentData(mockBundle, null)) - every { cacheImages(listOf(pushTemplate.imageUrl)) } returns 0 + every { cacheImages(any()) } returns 0 every { anyConstructed().setViewVisibility(any(), View.GONE) } just Runs val notification = ZeroBezelNotificationBuilder.construct( @@ -207,7 +208,7 @@ class ZeroBezelNotificationBuilderTest { notification.channelId ) verifyNotificationDataFields(notification, pushTemplate) - verify { cacheImages(listOf(pushTemplate.imageUrl)) } + verify { cacheImages(any()) } verify { anyConstructed().setViewVisibility(any(), View.GONE) } } diff --git a/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/extensions/NotificationCompatBuilderExtensionsTest.kt b/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/extensions/NotificationCompatBuilderExtensionsTest.kt index 82a5cb15..e4975851 100644 --- a/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/extensions/NotificationCompatBuilderExtensionsTest.kt +++ b/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/extensions/NotificationCompatBuilderExtensionsTest.kt @@ -22,9 +22,10 @@ import android.os.Bundle import androidx.core.app.NotificationCompat import com.adobe.marketing.mobile.MobileCore import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils import com.adobe.marketing.mobile.notificationbuilder.internal.builders.DummyActivity import com.adobe.marketing.mobile.notificationbuilder.internal.templates.BasicPushTemplate +import com.adobe.marketing.mobile.utils.AEPUIImageConfig +import com.adobe.marketing.mobile.utils.AEPUIImageUtils import io.mockk.every import io.mockk.mockk import io.mockk.mockkObject @@ -59,7 +60,7 @@ class NotificationCompatBuilderExtensionsTest { mockContext = mockk(relaxed = true) mockkStatic(Context::getIconWithResourceName) mockkStatic(MobileCore::class) - mockkObject(PushTemplateImageUtils) + mockkObject(AEPUIImageUtils) mockBitmap = mockk(relaxed = true) trackerActivityClass = DummyActivity::class.java } @@ -197,8 +198,8 @@ class NotificationCompatBuilderExtensionsTest { @Test fun `setLargeIcon with valid imageUrl`() { - every { PushTemplateImageUtils.cacheImages(listOf("valid_image_url")) } returns 1 - every { PushTemplateImageUtils.getCachedImage("valid_image_url") } returns mockBitmap + every { AEPUIImageUtils.cacheImages(any()) } returns 1 + every { AEPUIImageUtils.getCachedImage("valid_image_url") } returns mockBitmap val spyBuilder = spyk(NotificationCompat.Builder(mockContext, "mockChannelId")) @@ -210,7 +211,7 @@ class NotificationCompatBuilderExtensionsTest { @Test fun `setLargeIcon with imageUrl that cannot be downloaded`() { - every { PushTemplateImageUtils.cacheImages(listOf("invalid_image_url")) } returns 0 + every { AEPUIImageUtils.cacheImages(any()) } returns 0 val spyBuilder = spyk(NotificationCompat.Builder(mockContext, "mockChannelId")) diff --git a/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/extensions/RemoteViewsExtensionsTest.kt b/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/extensions/RemoteViewsExtensionsTest.kt index c836e527..ac8deee1 100644 --- a/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/extensions/RemoteViewsExtensionsTest.kt +++ b/code/notificationbuilder/src/test/java/com/adobe/marketing/mobile/notificationbuilder/internal/extensions/RemoteViewsExtensionsTest.kt @@ -21,10 +21,11 @@ import android.os.Bundle import android.view.View import android.widget.RemoteViews import com.adobe.marketing.mobile.notificationbuilder.PushTemplateConstants -import com.adobe.marketing.mobile.notificationbuilder.internal.PushTemplateImageUtils import com.adobe.marketing.mobile.notificationbuilder.internal.builders.DummyActivity import com.adobe.marketing.mobile.services.Logging import com.adobe.marketing.mobile.services.ServiceProvider +import com.adobe.marketing.mobile.utils.AEPUIImageConfig +import com.adobe.marketing.mobile.utils.AEPUIImageUtils import io.mockk.Runs import io.mockk.every import io.mockk.just @@ -59,7 +60,7 @@ class RemoteViewsExtensionsTest { @Before fun setup() { remoteViews = mockk(relaxed = true) - mockkObject(PushTemplateImageUtils) + mockkObject(AEPUIImageUtils) mockBitmap = mockk(relaxed = true) trackerActivityClass = DummyActivity::class.java } @@ -182,8 +183,8 @@ class RemoteViewsExtensionsTest { @Test fun `setRemoteViewImage applies image when valid URL provided`() { val imageUrl = "http://example.com/image.png" - every { PushTemplateImageUtils.cacheImages(listOf(imageUrl)) } returns 1 - every { PushTemplateImageUtils.getCachedImage(imageUrl) } returns mockBitmap + every { AEPUIImageUtils.cacheImages(any()) } returns 1 + every { AEPUIImageUtils.getCachedImage(imageUrl) } returns mockBitmap val result = remoteViews.setRemoteViewImage(imageUrl, 1) @@ -236,7 +237,7 @@ class RemoteViewsExtensionsTest { fun `setRemoteViewImage does not apply image when URL is invalid`() { val imageUrl = "invalid_url" every { remoteViews.setViewVisibility(any(), any()) } just Runs - every { PushTemplateImageUtils.cacheImages(listOf(imageUrl)) } returns 0 + every { AEPUIImageUtils.cacheImages(any()) } returns 0 val result = remoteViews.setRemoteViewImage(imageUrl, 1) @@ -250,7 +251,7 @@ class RemoteViewsExtensionsTest { fun `setRemoteViewImage does not apply image URL could not be downloaded`() { val imageUrl = "http://example.com/image.png" every { remoteViews.setViewVisibility(any(), any()) } just Runs - every { PushTemplateImageUtils.cacheImages(listOf(imageUrl)) } returns 0 + every { AEPUIImageUtils.cacheImages(any()) } returns 0 val result = remoteViews.setRemoteViewImage(imageUrl, 1) diff --git a/code/settings.gradle.kts b/code/settings.gradle.kts index 5c9ab072..f277d600 100755 --- a/code/settings.gradle.kts +++ b/code/settings.gradle.kts @@ -32,5 +32,6 @@ dependencyResolutionManagement { rootProject.name = "aepsdk-ui-android" include ( ":notificationbuilder", - ":testapp" -) \ No newline at end of file + ":testapp", + ":aep_ui_utils" +) diff --git a/code/testapp/build.gradle.kts b/code/testapp/build.gradle.kts index d914e552..0a64d8a2 100644 --- a/code/testapp/build.gradle.kts +++ b/code/testapp/build.gradle.kts @@ -72,6 +72,7 @@ dependencies { implementation("com.google.code.gson:gson:2.10") implementation(project(":notificationbuilder")) + implementation(project(":aep_ui_utils")) implementation("com.adobe.marketing.mobile:core:3.0.0") implementation("com.adobe.marketing.mobile:campaignclassic:3.0.0") implementation("androidx.appcompat:appcompat:1.6.1")