diff --git a/Examples/OneSignalDemo/app/build.gradle b/Examples/OneSignalDemo/app/build.gradle index 6d3b7f9d51..74ab7338c3 100644 --- a/Examples/OneSignalDemo/app/build.gradle +++ b/Examples/OneSignalDemo/app/build.gradle @@ -75,7 +75,6 @@ dependencies { implementation 'androidx.multidex:multidex:2.0.1' implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.appcompat:appcompat:1.5.1' - implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.vectordrawable:vectordrawable:1.1.0' implementation 'com.google.android.material:material:1.7.0' diff --git a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/notification/OneSignalNotificationSender.java b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/notification/OneSignalNotificationSender.java index 3d00056b88..96c870c13a 100644 --- a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/notification/OneSignalNotificationSender.java +++ b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/notification/OneSignalNotificationSender.java @@ -52,42 +52,40 @@ public static void sendDeviceNotification(final Notification notification) { "'android_accent_color': 'FFE9444E'," + "'android_sound': 'nil'}"); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - HttpURLConnection con = (HttpURLConnection) new URL("https://onesignal.com/api/v1/notifications").openConnection(); + HttpURLConnection con = (HttpURLConnection) new URL("https://onesignal.com/api/v1/notifications").openConnection(); - con.setUseCaches(false); - con.setConnectTimeout(30000); - con.setReadTimeout(30000); - con.setRequestProperty("Accept", "application/vnd.onesignal.v1+json"); - con.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); - con.setRequestMethod("POST"); - con.setDoOutput(true); - con.setDoInput(true); + con.setUseCaches(false); + con.setConnectTimeout(30000); + con.setReadTimeout(30000); + con.setRequestProperty("Accept", "application/vnd.onesignal.v1+json"); + con.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); + con.setRequestMethod("POST"); + con.setDoOutput(true); + con.setDoInput(true); - byte[] outputBytes = notificationContent.toString().getBytes(StandardCharsets.UTF_8); - con.setFixedLengthStreamingMode(outputBytes.length); - con.getOutputStream().write(outputBytes); + byte[] outputBytes = notificationContent.toString().getBytes(StandardCharsets.UTF_8); + con.setFixedLengthStreamingMode(outputBytes.length); + con.getOutputStream().write(outputBytes); - int httpResponse = con.getResponseCode(); + int httpResponse = con.getResponseCode(); - if(httpResponse == HttpURLConnection.HTTP_ACCEPTED || httpResponse == HttpURLConnection.HTTP_OK) { - InputStream inputStream = con.getInputStream(); - Scanner scanner = new Scanner(inputStream, "UTF-8"); - String responseStr = ""; - if (scanner.useDelimiter("\\A").hasNext()) - responseStr = scanner.next(); - scanner.close(); - Log.d(Tag.LOG_TAG, "Success sending notification: " + responseStr); - } - else { - InputStream inputStream = con.getErrorStream(); - Scanner scanner = new Scanner(inputStream, "UTF-8"); - String responseStr = ""; - if (scanner.useDelimiter("\\A").hasNext()) - responseStr = scanner.next(); - scanner.close(); - Log.d(Tag.LOG_TAG, "Failure sending notification: " + responseStr); - } + if(httpResponse == HttpURLConnection.HTTP_ACCEPTED || httpResponse == HttpURLConnection.HTTP_OK) { + InputStream inputStream = con.getInputStream(); + Scanner scanner = new Scanner(inputStream, "UTF-8"); + String responseStr = ""; + if (scanner.useDelimiter("\\A").hasNext()) + responseStr = scanner.next(); + scanner.close(); + Log.d(Tag.LOG_TAG, "Success sending notification: " + responseStr); + } + else { + InputStream inputStream = con.getErrorStream(); + Scanner scanner = new Scanner(inputStream, "UTF-8"); + String responseStr = ""; + if (scanner.useDelimiter("\\A").hasNext()) + responseStr = scanner.next(); + scanner.close(); + Log.d(Tag.LOG_TAG, "Failure sending notification: " + responseStr); } } catch (Exception e) { e.printStackTrace(); diff --git a/OneSignalSDK/onesignal/core/build.gradle b/OneSignalSDK/onesignal/core/build.gradle index ee4183f6ec..6dd200a429 100644 --- a/OneSignalSDK/onesignal/core/build.gradle +++ b/OneSignalSDK/onesignal/core/build.gradle @@ -68,12 +68,6 @@ dependencies { compileOnly('com.amazon.device:amazon-appstore-sdk:[3.0.1, 3.0.99]') - api('androidx.legacy:legacy-support-v4') { - version { - require '[1.0.0, 1.0.99]' - prefer '1.0.0' - } - } api('androidx.appcompat:appcompat') { version { require '[1.0.0, 1.3.99]' diff --git a/OneSignalSDK/onesignal/core/src/main/AndroidManifest.xml b/OneSignalSDK/onesignal/core/src/main/AndroidManifest.xml index f765cdd684..69421766c8 100644 --- a/OneSignalSDK/onesignal/core/src/main/AndroidManifest.xml +++ b/OneSignalSDK/onesignal/core/src/main/AndroidManifest.xml @@ -5,11 +5,6 @@ - - 22) { - context.getColor(id) - } else { - context.resources.getColor( - id, - ) - } - } - } - - internal interface RequestPermissionsRequestCodeValidator { - fun validateRequestPermissionsRequestCode(requestCode: Int) - } - - internal object ActivityCompat { - fun requestPermissions( - activity: Activity, - permissions: Array, - requestCode: Int, - ) { - // OneSignal SDK code already checks that device is Android M, omit else code from the support library. - ActivityCompatApi23.requestPermissions(activity, permissions, requestCode) - } - - fun shouldShowRequestPermissionRationale( - activity: Activity?, - permission: String?, - ): Boolean { - return ActivityCompatApi23.shouldShowRequestPermissionRationale(activity, permission) - } - } - - @TargetApi(23) - internal object ActivityCompatApi23 { - fun requestPermissions( - activity: Activity, - permissions: Array?, - requestCode: Int, - ) { - if (activity is RequestPermissionsRequestCodeValidator) { - (activity as RequestPermissionsRequestCodeValidator).validateRequestPermissionsRequestCode( - requestCode, - ) - } - activity.requestPermissions(permissions!!, requestCode) - } - - fun shouldShowRequestPermissionRationale( - activity: Activity?, - permission: String?, - ): Boolean { - return androidx.core.app.ActivityCompat.shouldShowRequestPermissionRationale( - activity!!, - permission!!, - ) - } - } -} diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/common/AndroidUtils.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/common/AndroidUtils.kt index 6a827fadbd..69ad3c7aaf 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/common/AndroidUtils.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/common/AndroidUtils.kt @@ -12,9 +12,8 @@ import android.os.Bundle import android.os.Looper import android.text.TextUtils import androidx.annotation.Keep -import androidx.core.app.JobIntentService import androidx.core.app.NotificationManagerCompat -import androidx.legacy.content.WakefulBroadcastReceiver +import androidx.core.content.ContextCompat import com.onesignal.core.internal.application.IApplicationService import com.onesignal.debug.internal.logging.Logging import java.util.Random @@ -42,14 +41,6 @@ object AndroidUtils { return hasToken && insetsAttached } - fun sleep(ms: Int) { - try { - Thread.sleep(ms.toLong()) - } catch (e: InterruptedException) { - e.printStackTrace() - } - } - fun hasConfigChangeFlag( activity: Activity, configChangeFlag: Int, @@ -147,25 +138,8 @@ object AndroidUtils { } catch (e: PackageManager.NameNotFoundException) { e.printStackTrace() } - return Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1 - } - - fun hasJobIntentService(): Boolean { - return try { - // noinspection ConstantConditions - JobIntentService::class.java != null - } catch (e: Throwable) { - false - } - } - - fun hasWakefulBroadcastReceiver(): Boolean { - return try { - // noinspection ConstantConditions - WakefulBroadcastReceiver::class.java != null - } catch (e: Throwable) { - false - } + // Default to minSDK version if we can't find the target version + return Build.VERSION_CODES.LOLLIPOP } fun hasNotificationManagerCompat(): Boolean { @@ -248,7 +222,7 @@ object AndroidUtils { true } else { val permissionGrant = - AndroidSupportV4Compat.ContextCompat.checkSelfPermission( + ContextCompat.checkSelfPermission( applicationService.appContext, permission, ) diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/common/ViewUtils.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/common/ViewUtils.kt index eb1b18e6c1..0a3867fbf4 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/common/ViewUtils.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/common/ViewUtils.kt @@ -21,12 +21,8 @@ object ViewUtils { fun getWindowHeight(activity: Activity): Int { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { getWindowHeightAPI23Plus(activity) - } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - getWindowHeightLollipop( - activity, - ) } else { - getDisplaySizeY(activity) + getWindowHeightLollipop(activity) } } diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/activities/PermissionsActivity.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/activities/PermissionsActivity.kt index 52d9bbb16a..1404edb945 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/activities/PermissionsActivity.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/activities/PermissionsActivity.kt @@ -6,8 +6,8 @@ import android.content.pm.PackageManager import android.os.Build import android.os.Bundle import android.os.Handler +import androidx.core.app.ActivityCompat import com.onesignal.OneSignal -import com.onesignal.common.AndroidSupportV4Compat import com.onesignal.core.R import com.onesignal.core.internal.permissions.impl.RequestPermissionService import com.onesignal.core.internal.preferences.IPreferencesService @@ -18,7 +18,6 @@ class PermissionsActivity : Activity() { private var requestPermissionService: RequestPermissionService? = null private var preferenceService: IPreferencesService? = null private var permissionRequestType: String? = null - private var androidPermissionString: String? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -49,9 +48,9 @@ class PermissionsActivity : Activity() { reregisterCallbackHandlers(extras) permissionRequestType = extras!!.getString(INTENT_EXTRA_PERMISSION_TYPE) - androidPermissionString = extras.getString(INTENT_EXTRA_ANDROID_PERMISSION_STRING) + val androidPermissionString = extras.getString(INTENT_EXTRA_ANDROID_PERMISSION_STRING) - requestPermission(androidPermissionString) + requestPermission(androidPermissionString!!) } // Required if the app was killed while this prompt was showing @@ -67,15 +66,15 @@ class PermissionsActivity : Activity() { } } - private fun requestPermission(androidPermissionString: String?) { + private fun requestPermission(androidPermissionString: String) { if (!requestPermissionService!!.waiting) { requestPermissionService!!.waiting = true requestPermissionService!!.shouldShowRequestPermissionRationaleBeforeRequest = - AndroidSupportV4Compat.ActivityCompat.shouldShowRequestPermissionRationale( + ActivityCompat.shouldShowRequestPermissionRationale( this@PermissionsActivity, androidPermissionString, ) - AndroidSupportV4Compat.ActivityCompat.requestPermissions( + ActivityCompat.requestPermissions( this, arrayOf(androidPermissionString), ONESIGNAL_PERMISSION_REQUEST_CODE, @@ -83,6 +82,7 @@ class PermissionsActivity : Activity() { } } + // NOTE: This code assumes only one permission was prompted for override fun onRequestPermissionsResult( requestCode: Int, permissions: Array, @@ -98,6 +98,7 @@ class PermissionsActivity : Activity() { // We need to wait for other activity to show if (requestCode == ONESIGNAL_PERMISSION_REQUEST_CODE) { Handler().postDelayed({ + val permission = permissions[0] val granted = grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED val callback = @@ -107,11 +108,11 @@ class PermissionsActivity : Activity() { callback.onAccept() preferenceService!!.saveBool( PreferenceStores.ONESIGNAL, - "${PreferenceOneSignalKeys.PREFS_OS_USER_RESOLVED_PERMISSION_PREFIX}$androidPermissionString", + "${PreferenceOneSignalKeys.PREFS_OS_USER_RESOLVED_PERMISSION_PREFIX}$permission", true, ) } else { - callback.onReject(shouldShowSettings()) + callback.onReject(shouldShowSettings(permission)) } }, DELAY_TIME_CALLBACK_CALL.toLong()) } @@ -120,7 +121,7 @@ class PermissionsActivity : Activity() { overridePendingTransition(R.anim.onesignal_fade_in, R.anim.onesignal_fade_out) } - private fun shouldShowSettings(): Boolean { + private fun shouldShowSettings(permission: String): Boolean { if (!requestPermissionService!!.fallbackToSettings) { return false } @@ -131,14 +132,14 @@ class PermissionsActivity : Activity() { // look for the change from `true` -> `false`. When this happens we remember this // rejection, as the user will never be prompted again. if (requestPermissionService!!.shouldShowRequestPermissionRationaleBeforeRequest) { - if (!AndroidSupportV4Compat.ActivityCompat.shouldShowRequestPermissionRationale( + if (!ActivityCompat.shouldShowRequestPermissionRationale( this@PermissionsActivity, - androidPermissionString, + permission, ) ) { preferenceService!!.saveBool( PreferenceStores.ONESIGNAL, - "${PreferenceOneSignalKeys.PREFS_OS_USER_RESOLVED_PERMISSION_PREFIX}$androidPermissionString", + "${PreferenceOneSignalKeys.PREFS_OS_USER_RESOLVED_PERMISSION_PREFIX}$permission", true, ) return false @@ -147,7 +148,7 @@ class PermissionsActivity : Activity() { return preferenceService!!.getBool( PreferenceStores.ONESIGNAL, - "${PreferenceOneSignalKeys.PREFS_OS_USER_RESOLVED_PERMISSION_PREFIX}$androidPermissionString", + "${PreferenceOneSignalKeys.PREFS_OS_USER_RESOLVED_PERMISSION_PREFIX}$permission", false, )!! } diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/background/impl/BackgroundManager.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/background/impl/BackgroundManager.kt index a210056104..eddb183784 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/background/impl/BackgroundManager.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/background/impl/BackgroundManager.kt @@ -26,18 +26,12 @@ */ package com.onesignal.core.internal.background.impl -import android.annotation.SuppressLint -import android.app.AlarmManager -import android.app.PendingIntent import android.app.job.JobInfo import android.app.job.JobScheduler import android.content.ComponentName import android.content.Context -import android.content.Intent import android.content.pm.PackageManager -import android.os.Build -import androidx.annotation.RequiresApi -import com.onesignal.common.AndroidSupportV4Compat +import androidx.core.content.ContextCompat import com.onesignal.core.internal.application.IApplicationLifecycleHandler import com.onesignal.core.internal.application.IApplicationService import com.onesignal.core.internal.background.IBackgroundManager @@ -45,7 +39,6 @@ import com.onesignal.core.internal.background.IBackgroundService import com.onesignal.core.internal.startup.IStartableService import com.onesignal.core.internal.time.ITime import com.onesignal.core.services.SyncJobService -import com.onesignal.core.services.SyncService import com.onesignal.debug.internal.logging.Logging import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -71,9 +64,7 @@ internal class BackgroundManager( private var nextScheduledSyncTimeMs = 0L private var backgroundSyncJob: Job? = null - @SuppressLint("NewApi") // can suppress because we are only retrieving the class, not necessarily using it private val syncServiceJobClass: Class<*> = SyncJobService::class.java - private val syncServicePendingIntentClass: Class<*> = SyncService::class.java override fun start() { _applicationService.addApplicationLifecycleHandler(this) @@ -153,22 +144,17 @@ internal class BackgroundManager( private fun scheduleBackgroundSyncTask(delayMs: Long) { synchronized(lock) { - if (useJob()) { - scheduleSyncServiceAsJob(delayMs) - } else { - scheduleSyncServiceAsAlarm(delayMs) - } + scheduleSyncServiceAsJob(delayMs) } } private fun hasBootPermission(): Boolean { - return AndroidSupportV4Compat.ContextCompat.checkSelfPermission( + return ContextCompat.checkSelfPermission( _applicationService.appContext, "android.permission.RECEIVE_BOOT_COMPLETED", ) == PackageManager.PERMISSION_GRANTED } - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) private fun isJobIdRunning(): Boolean { val jobScheduler = _applicationService.appContext.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler for (jobInfo in jobScheduler.allPendingJobs) { @@ -179,7 +165,6 @@ internal class BackgroundManager( return false } - @RequiresApi(21) private fun scheduleSyncServiceAsJob(delayMs: Long) { Logging.debug("OSBackgroundSync scheduleSyncServiceAsJob:atTime: $delayMs") if (isJobIdRunning()) { @@ -209,44 +194,15 @@ internal class BackgroundManager( } } - private fun scheduleSyncServiceAsAlarm(delayMs: Long) { - Logging.verbose(this.javaClass.simpleName + " scheduleServiceSyncTask:atTime: " + delayMs) - val pendingIntent = syncServicePendingIntent() - val alarm = _applicationService.appContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager - val triggerAtMs = _time.currentTimeMillis + delayMs - alarm[AlarmManager.RTC_WAKEUP, triggerAtMs] = pendingIntent - } - private fun cancelBackgroundSyncTask() { Logging.debug(this.javaClass.simpleName + " cancel background sync") synchronized(lock) { - if (useJob()) { - val jobScheduler = _applicationService.appContext.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler - jobScheduler.cancel(SYNC_TASK_ID) - } else { - val alarmManager = _applicationService.appContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager - alarmManager.cancel(syncServicePendingIntent()) - } + val jobScheduler = _applicationService.appContext.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler + jobScheduler.cancel(SYNC_TASK_ID) } } - private fun syncServicePendingIntent(): PendingIntent { - // KEEP - PendingIntent.FLAG_UPDATE_CURRENT - // Some Samsung devices will throw the below exception otherwise. - // "java.lang.SecurityException: !@Too many alarms (500) registered" - return PendingIntent.getService( - _applicationService.appContext, - SYNC_TASK_ID, - Intent(_applicationService.appContext, syncServicePendingIntentClass), - PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE, - ) - } - - private fun useJob(): Boolean { - return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP - } - companion object { private const val SYNC_TASK_ID = 2071862118 } diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/device/IDeviceService.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/device/IDeviceService.kt index 7bbb02d0d0..0b8d2d3635 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/device/IDeviceService.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/device/IDeviceService.kt @@ -10,15 +10,17 @@ interface IDeviceService { val isGMSInstalledAndEnabled: Boolean val hasAllHMSLibrariesForPushKit: Boolean val hasFCMLibrary: Boolean - val androidSupportLibraryStatus: AndroidSupportLibraryStatus + val jetpackLibraryStatus: JetpackLibraryStatus - enum class AndroidSupportLibraryStatus { + enum class JetpackLibraryStatus { MISSING, OUTDATED, OK, } - enum class DeviceType(val value: Int) { + enum class DeviceType( + val value: Int, + ) { Fire(2), Android(1), Huawei(13), diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/device/impl/DeviceService.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/device/impl/DeviceService.kt index 07d9141824..fa592539de 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/device/impl/DeviceService.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/device/impl/DeviceService.kt @@ -1,7 +1,6 @@ package com.onesignal.core.internal.device.impl import android.content.pm.PackageManager -import android.os.Build import com.onesignal.common.AndroidUtils import com.onesignal.core.internal.application.IApplicationService import com.onesignal.core.internal.device.IDeviceService @@ -53,30 +52,14 @@ internal class DeviceService(private val _applicationService: IApplicationServic // Fallback to device_type 1 (Android) if there are no supported push channels on the device } - override val androidSupportLibraryStatus: IDeviceService.AndroidSupportLibraryStatus + override val jetpackLibraryStatus: IDeviceService.JetpackLibraryStatus get() { - val hasWakefulBroadcastReceiver: Boolean = AndroidUtils.hasWakefulBroadcastReceiver() val hasNotificationManagerCompat: Boolean = AndroidUtils.hasNotificationManagerCompat() - if (!hasWakefulBroadcastReceiver && !hasNotificationManagerCompat) { - return IDeviceService.AndroidSupportLibraryStatus.MISSING + if (!hasNotificationManagerCompat) { + return IDeviceService.JetpackLibraryStatus.MISSING } - if (!hasWakefulBroadcastReceiver || !hasNotificationManagerCompat) { - return IDeviceService.AndroidSupportLibraryStatus.OUTDATED - } - - // If running on Android O and targeting O we need version 26.0.0 for - // the new compat NotificationCompat.Builder constructor. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && - AndroidUtils.getTargetSdkVersion(_applicationService.appContext) >= Build.VERSION_CODES.O - ) { - // Class was added in 26.0.0-beta2 - if (!AndroidUtils.hasJobIntentService()) { - return IDeviceService.AndroidSupportLibraryStatus.OUTDATED - } - } - - return IDeviceService.AndroidSupportLibraryStatus.OK + return IDeviceService.JetpackLibraryStatus.OK } private fun supportsGooglePush(): Boolean { diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/services/SyncJobService.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/services/SyncJobService.kt index 70c4aa19d0..ef98e5388c 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/services/SyncJobService.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/services/SyncJobService.kt @@ -28,14 +28,11 @@ package com.onesignal.core.services import android.app.job.JobParameters import android.app.job.JobService -import android.os.Build -import androidx.annotation.RequiresApi import com.onesignal.OneSignal import com.onesignal.common.threading.suspendifyOnThread import com.onesignal.core.internal.background.IBackgroundManager import com.onesignal.debug.internal.logging.Logging -@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) class SyncJobService : JobService() { override fun onStartJob(jobParameters: JobParameters): Boolean { if (!OneSignal.initWithContext(this)) { diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/services/SyncService.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/services/SyncService.kt deleted file mode 100644 index c051f7d79f..0000000000 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/services/SyncService.kt +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Modified MIT License - * - * Copyright 2018 OneSignal - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * 1. The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * 2. All copies of substantial portions of the Software may only be used in connection - * with services provided by OneSignal. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.onesignal.core.services - -import android.app.Service -import android.content.Intent -import android.os.IBinder -import com.onesignal.OneSignal -import com.onesignal.common.threading.suspendifyOnThread -import com.onesignal.core.internal.background.IBackgroundManager -import com.onesignal.debug.internal.logging.Logging - -class SyncService : Service() { - override fun onStartCommand( - intent: Intent, - flags: Int, - startId: Int, - ): Int { - if (!OneSignal.initWithContext(this)) { - return START_STICKY - } - - var backgroundService = OneSignal.getService() - - suspendifyOnThread { - backgroundService.runBackgroundServices() - Logging.debug("LegacySyncRunnable:Stopped") - stopSelf() - } - - return START_STICKY - } - - // This Service does not support bindings - override fun onBind(intent: Intent): IBinder? { - return null - } -} diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/subscriptions/SubscriptionModel.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/subscriptions/SubscriptionModel.kt index aeebee27f2..c7bde3aae8 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/subscriptions/SubscriptionModel.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/subscriptions/SubscriptionModel.kt @@ -18,14 +18,14 @@ enum class SubscriptionStatus(val value: Int) { /** The subscription is not enabled because the app has disabled the subscription */ UNSUBSCRIBE(-2), - /** The subscription is not enabled due to a missing android support library */ - MISSING_ANDROID_SUPPORT_LIBRARY(-3), + /** The subscription is not enabled due to a missing Jetpack/AndroidX library */ + MISSING_JETPACK_LIBRARY(-3), /** The subscription is not enabled due to a missing firebase library */ MISSING_FIREBASE_FCM_LIBRARY(-4), - /** The subscription is not enabled due to an outdated android support library */ - OUTDATED_ANDROID_SUPPORT_LIBRARY(-5), + /** The subscription is not enabled due to an outdated Jetpack/AndroidX library */ + OUTDATED_JETPACK_LIBRARY(-5), /** The subscription is not enabled due to the FCM sender being invalid */ INVALID_FCM_SENDER_ID(-6), diff --git a/OneSignalSDK/onesignal/in-app-messages/src/main/java/com/onesignal/inAppMessages/internal/display/impl/WebViewManager.kt b/OneSignalSDK/onesignal/in-app-messages/src/main/java/com/onesignal/inAppMessages/internal/display/impl/WebViewManager.kt index 734bd9d7fd..e2054ac49d 100644 --- a/OneSignalSDK/onesignal/in-app-messages/src/main/java/com/onesignal/inAppMessages/internal/display/impl/WebViewManager.kt +++ b/OneSignalSDK/onesignal/in-app-messages/src/main/java/com/onesignal/inAppMessages/internal/display/impl/WebViewManager.kt @@ -1,7 +1,6 @@ package com.onesignal.inAppMessages.internal.display.impl import android.annotation.SuppressLint -import android.annotation.TargetApi import android.app.Activity import android.os.Build import android.view.View @@ -38,7 +37,6 @@ import java.util.Locale // 3. This calls showActivity which starts a new WebView // 4. WebViewActivity will call WebViewManager.instanceFromIam(...) to get this instance and // add it's prepared WebView add add it to the Activity. -@TargetApi(Build.VERSION_CODES.KITKAT) internal class WebViewManager( private val message: InAppMessage, private var activity: Activity, @@ -324,7 +322,6 @@ internal class WebViewManager( webView!!.fitsSystemWindows = false } } - blurryRenderingWebViewForKitKatWorkAround(webView!!) _lifecycle.messageWillDisplay(message) _applicationService.waitUntilActivityReady() @@ -332,19 +329,6 @@ internal class WebViewManager( webView!!.loadData(base64Message, "text/html; charset=utf-8", "base64") } - private fun blurryRenderingWebViewForKitKatWorkAround(webView: WebView) { - // Android 4.4 has a rendering bug that cause the whole WebView to by extremely blurry - // This is due to a bug with hardware rending so ensure it is disabled. - // Tested on other version of Android and it is specific to only Android 4.4 - // On both the emulator and real devices. - if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) { - webView.setLayerType( - View.LAYER_TYPE_SOFTWARE, - null, - ) - } - } - // This sets the WebView view port sizes to the max screen sizes so the initialize // max content height can be calculated. // A render complete or resize event will fire from JS to tell Java it's height and will then display @@ -444,8 +428,7 @@ internal class WebViewManager( // Allow Chrome Remote Debugging if OneSignal.LOG_LEVEL.DEBUG or higher private fun enableWebViewRemoteDebugging() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Logging.atLogLevel(LogLevel.DEBUG) - ) { + if (Logging.atLogLevel(LogLevel.DEBUG)) { WebView.setWebContentsDebuggingEnabled(true) } } diff --git a/OneSignalSDK/onesignal/in-app-messages/src/main/java/com/onesignal/inAppMessages/internal/preview/InAppMessagePreviewHandler.kt b/OneSignalSDK/onesignal/in-app-messages/src/main/java/com/onesignal/inAppMessages/internal/preview/InAppMessagePreviewHandler.kt index f0b45ddfbb..9898581ece 100644 --- a/OneSignalSDK/onesignal/in-app-messages/src/main/java/com/onesignal/inAppMessages/internal/preview/InAppMessagePreviewHandler.kt +++ b/OneSignalSDK/onesignal/in-app-messages/src/main/java/com/onesignal/inAppMessages/internal/preview/InAppMessagePreviewHandler.kt @@ -1,8 +1,6 @@ package com.onesignal.inAppMessages.internal.preview import android.app.Activity -import android.os.Build -import androidx.annotation.ChecksSdkIntAtLeast import com.onesignal.core.internal.application.IApplicationService import com.onesignal.core.internal.startup.IStartableService import com.onesignal.core.internal.time.ITime @@ -43,7 +41,7 @@ internal class InAppMessagePreviewHandler( if (!result) { _state.inAppMessageIdShowing = null } - } else if (shouldDisplayNotification()) { + } else { val generationJob = NotificationGenerationJob(jsonPayload, _time) _notificationDisplayer.displayNotification(generationJob) } @@ -87,8 +85,4 @@ internal class InAppMessagePreviewHandler( } } } - - // Validate that the current Android device is Android 4.4 or higher - @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.KITKAT) - private fun shouldDisplayNotification(): Boolean = Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2 } diff --git a/OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/common/NotificationHelper.kt b/OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/common/NotificationHelper.kt index 742c08c261..663e8d81c6 100644 --- a/OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/common/NotificationHelper.kt +++ b/OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/common/NotificationHelper.kt @@ -89,7 +89,6 @@ object NotificationHelper { return grouplessStatusBarNotifications } - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) fun isGroupSummary(notif: StatusBarNotification): Boolean { return notif.notification.flags and Notification.FLAG_GROUP_SUMMARY != 0 } diff --git a/OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/display/impl/NotificationDisplayBuilder.kt b/OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/display/impl/NotificationDisplayBuilder.kt index 72d92bb8a1..2029c91084 100644 --- a/OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/display/impl/NotificationDisplayBuilder.kt +++ b/OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/display/impl/NotificationDisplayBuilder.kt @@ -82,16 +82,8 @@ internal class NotificationDisplayBuilder( override fun getBaseOneSignalNotificationBuilder(notificationJob: NotificationGenerationJob): OneSignalNotificationBuilder { val fcmJson: JSONObject = notificationJob.jsonPayload!! val oneSignalNotificationBuilder = OneSignalNotificationBuilder() - val notificationBuilder: NotificationCompat.Builder - notificationBuilder = - try { - val channelId: String = - _notificationChannelManager.createNotificationChannel(notificationJob) - // Will throw if app is using 26.0.0-beta1 or older of the support library. - NotificationCompat.Builder(currentContext!!, channelId) - } catch (t: Throwable) { - NotificationCompat.Builder(currentContext!!) - } + val channelId = _notificationChannelManager.createNotificationChannel(notificationJob) + val notificationBuilder = NotificationCompat.Builder(currentContext, channelId) val message = fcmJson.optString("alert", null) notificationBuilder .setAutoCancel(true) diff --git a/OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/display/impl/NotificationDisplayer.kt b/OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/display/impl/NotificationDisplayer.kt index 5e6e8e4c91..fe24d9e765 100644 --- a/OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/display/impl/NotificationDisplayer.kt +++ b/OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/display/impl/NotificationDisplayer.kt @@ -13,7 +13,7 @@ import android.view.View import android.widget.RemoteViews import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat -import com.onesignal.common.AndroidSupportV4Compat +import androidx.core.content.ContextCompat import com.onesignal.common.AndroidUtils import com.onesignal.common.exceptions.MainThreadException import com.onesignal.common.safeString @@ -54,10 +54,6 @@ internal class NotificationDisplayer( return showNotification(notificationJob) } - suspend fun displayIAMPreviewNotification(notificationJob: NotificationGenerationJob): Boolean { - return showNotification(notificationJob) - } // Runtime check against showing the notification from the main thread - /** * For shadow test purpose */ @@ -157,16 +153,12 @@ internal class NotificationDisplayer( ) } - // NotificationManagerCompat does not auto omit the individual notification on the device when using - // stacked notifications on Android 4.2 and older // The benefits of calling notify for individual notifications in-addition to the summary above it is shows // each notification in a stack on Android Wear and each one is actionable just like the Gmail app does per email. // Note that on Android 7.0 this is the opposite. Only individual notifications will show and mBundle / group is // created by Android itself. - if (group == null || Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR1) { - _notificationDisplayBuilder.addXiaomiSettings(oneSignalNotificationBuilder, notification) - NotificationManagerCompat.from(currentContext!!).notify(notificationId, notification) - } + _notificationDisplayBuilder.addXiaomiSettings(oneSignalNotificationBuilder, notification) + NotificationManagerCompat.from(currentContext!!).notify(notificationId, notification) return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationHelper.areNotificationsEnabled(currentContext!!, notification.channelId) @@ -238,10 +230,8 @@ internal class NotificationDisplayer( fcmJson: JSONObject, notifBuilder: NotificationCompat.Builder?, ) { - // Not adding Background Images to API Versions < 16 or >= 31 - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN || - Build.VERSION.SDK_INT >= Build.VERSION_CODES.S - ) { + // Not adding Background Images to API Versions >= 31 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { Logging.verbose("Cannot use background images in notifications for device on version: " + Build.VERSION.SDK_INT) return } @@ -332,10 +322,7 @@ internal class NotificationDisplayer( if (colorId != 0) { customView.setTextColor( viewId, - AndroidSupportV4Compat.ContextCompat.getColor( - currentContext!!, - colorId, - ), + ContextCompat.getColor(currentContext, colorId), ) } } diff --git a/OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/pushtoken/PushTokenManager.kt b/OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/pushtoken/PushTokenManager.kt index 1e5b65c60e..33e66b4838 100644 --- a/OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/pushtoken/PushTokenManager.kt +++ b/OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/pushtoken/PushTokenManager.kt @@ -16,16 +16,16 @@ internal class PushTokenManager( var pushToken: String? = null override suspend fun retrievePushToken(): PushTokenResponse { - when (_deviceService.androidSupportLibraryStatus) { - IDeviceService.AndroidSupportLibraryStatus.MISSING -> { - Logging.fatal("Could not find the Android Support Library. Please make sure it has been correctly added to your project.") - pushTokenStatus = SubscriptionStatus.MISSING_ANDROID_SUPPORT_LIBRARY + when (_deviceService.jetpackLibraryStatus) { + IDeviceService.JetpackLibraryStatus.MISSING -> { + Logging.fatal("Could not find the Jetpack/AndroidX. Please make sure it has been correctly added to your project.") + pushTokenStatus = SubscriptionStatus.MISSING_JETPACK_LIBRARY } - IDeviceService.AndroidSupportLibraryStatus.OUTDATED -> { + IDeviceService.JetpackLibraryStatus.OUTDATED -> { Logging.fatal( - "The included Android Support Library is too old or incomplete. Please update to the 26.0.0 revision or newer.", + "The included Jetpack/AndroidX Library is too old or incomplete.", ) - pushTokenStatus = SubscriptionStatus.OUTDATED_ANDROID_SUPPORT_LIBRARY + pushTokenStatus = SubscriptionStatus.OUTDATED_JETPACK_LIBRARY } else -> { val registerResult = _pushRegistrator.registerForPush() diff --git a/OneSignalSDK/onesignal/notifications/src/test/java/com/onesignal/notifications/internal/pushtoken/PushTokenManagerTests.kt b/OneSignalSDK/onesignal/notifications/src/test/java/com/onesignal/notifications/internal/pushtoken/PushTokenManagerTests.kt index ff281d786e..ea2f1f5a44 100644 --- a/OneSignalSDK/onesignal/notifications/src/test/java/com/onesignal/notifications/internal/pushtoken/PushTokenManagerTests.kt +++ b/OneSignalSDK/onesignal/notifications/src/test/java/com/onesignal/notifications/internal/pushtoken/PushTokenManagerTests.kt @@ -20,11 +20,11 @@ class PushTokenManagerTests : FunSpec({ ShadowRoboNotificationManager.reset() } - test("retrievePushToken should fail with missing library when android support libraries are missing") { + test("retrievePushToken should fail with missing library when Jetpack libraries are missing") { // Given val mockPushRegistrator = mockk() val mockDeviceService = MockHelper.deviceService() - every { mockDeviceService.androidSupportLibraryStatus } returns IDeviceService.AndroidSupportLibraryStatus.MISSING + every { mockDeviceService.jetpackLibraryStatus } returns IDeviceService.JetpackLibraryStatus.MISSING val pushTokenManager = PushTokenManager(mockPushRegistrator, mockDeviceService) @@ -35,16 +35,16 @@ class PushTokenManagerTests : FunSpec({ // Then response.token shouldBe null - response.status shouldBe SubscriptionStatus.MISSING_ANDROID_SUPPORT_LIBRARY + response.status shouldBe SubscriptionStatus.MISSING_JETPACK_LIBRARY pushToken shouldBe null - pushTokenStatus shouldBe SubscriptionStatus.MISSING_ANDROID_SUPPORT_LIBRARY + pushTokenStatus shouldBe SubscriptionStatus.MISSING_JETPACK_LIBRARY } - test("retrievePushToken should fail with outdated library when android support libraries are missing") { + test("retrievePushToken should fail with outdated library when Jetpack libraries are missing") { // Given val mockPushRegistrator = mockk() val mockDeviceService = MockHelper.deviceService() - every { mockDeviceService.androidSupportLibraryStatus } returns IDeviceService.AndroidSupportLibraryStatus.OUTDATED + every { mockDeviceService.jetpackLibraryStatus } returns IDeviceService.JetpackLibraryStatus.OUTDATED val pushTokenManager = PushTokenManager(mockPushRegistrator, mockDeviceService) @@ -55,9 +55,9 @@ class PushTokenManagerTests : FunSpec({ // Then response.token shouldBe null - response.status shouldBe SubscriptionStatus.OUTDATED_ANDROID_SUPPORT_LIBRARY + response.status shouldBe SubscriptionStatus.OUTDATED_JETPACK_LIBRARY pushToken shouldBe null - pushTokenStatus shouldBe SubscriptionStatus.OUTDATED_ANDROID_SUPPORT_LIBRARY + pushTokenStatus shouldBe SubscriptionStatus.OUTDATED_JETPACK_LIBRARY } test("retrievePushToken should succeed when registration is successful") { @@ -65,7 +65,7 @@ class PushTokenManagerTests : FunSpec({ val mockPushRegistrator = mockk() coEvery { mockPushRegistrator.registerForPush() } returns IPushRegistrator.RegisterResult("pushToken", SubscriptionStatus.SUBSCRIBED) val mockDeviceService = MockHelper.deviceService() - every { mockDeviceService.androidSupportLibraryStatus } returns IDeviceService.AndroidSupportLibraryStatus.OK + every { mockDeviceService.jetpackLibraryStatus } returns IDeviceService.JetpackLibraryStatus.OK val pushTokenManager = PushTokenManager(mockPushRegistrator, mockDeviceService) @@ -89,7 +89,7 @@ class PushTokenManagerTests : FunSpec({ mockPushRegistrator.registerForPush() } returns IPushRegistrator.RegisterResult(null, SubscriptionStatus.MISSING_FIREBASE_FCM_LIBRARY) val mockDeviceService = MockHelper.deviceService() - every { mockDeviceService.androidSupportLibraryStatus } returns IDeviceService.AndroidSupportLibraryStatus.OK + every { mockDeviceService.jetpackLibraryStatus } returns IDeviceService.JetpackLibraryStatus.OK val pushTokenManager = PushTokenManager(mockPushRegistrator, mockDeviceService) @@ -113,7 +113,7 @@ class PushTokenManagerTests : FunSpec({ mockPushRegistrator.registerForPush() } returns IPushRegistrator.RegisterResult(null, SubscriptionStatus.FIREBASE_FCM_ERROR_MISC_EXCEPTION) val mockDeviceService = MockHelper.deviceService() - every { mockDeviceService.androidSupportLibraryStatus } returns IDeviceService.AndroidSupportLibraryStatus.OK + every { mockDeviceService.jetpackLibraryStatus } returns IDeviceService.JetpackLibraryStatus.OK val pushTokenManager = PushTokenManager(mockPushRegistrator, mockDeviceService) @@ -138,7 +138,7 @@ class PushTokenManagerTests : FunSpec({ IPushRegistrator.RegisterResult(null, SubscriptionStatus.FIREBASE_FCM_ERROR_MISC_EXCEPTION) val mockDeviceService = MockHelper.deviceService() - every { mockDeviceService.androidSupportLibraryStatus } returns IDeviceService.AndroidSupportLibraryStatus.OK + every { mockDeviceService.jetpackLibraryStatus } returns IDeviceService.JetpackLibraryStatus.OK val pushTokenManager = PushTokenManager(mockPushRegistrator, mockDeviceService) @@ -170,7 +170,7 @@ class PushTokenManagerTests : FunSpec({ IPushRegistrator.RegisterResult(null, SubscriptionStatus.MISSING_FIREBASE_FCM_LIBRARY) val mockDeviceService = MockHelper.deviceService() - every { mockDeviceService.androidSupportLibraryStatus } returns IDeviceService.AndroidSupportLibraryStatus.OK + every { mockDeviceService.jetpackLibraryStatus } returns IDeviceService.JetpackLibraryStatus.OK val pushTokenManager = PushTokenManager(mockPushRegistrator, mockDeviceService)