diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/preferences/PreferenceStoreFix.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/preferences/PreferenceStoreFix.kt new file mode 100644 index 0000000000..773d1e4651 --- /dev/null +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/preferences/PreferenceStoreFix.kt @@ -0,0 +1,51 @@ +package com.onesignal.core.internal.preferences + +import android.content.Context +import android.os.Build +import com.onesignal.debug.LogLevel +import com.onesignal.debug.internal.logging.Logging +import java.io.File + +object PreferenceStoreFix { + /** + * Ensure the OneSignal preference store is not using the v4 obfuscated version, if one + * exists. + */ + fun ensureNoObfuscatedPrefStore(context: Context) { + try { + // In the v4 version the OneSignal shared preference name was based on the OneSignal + // class name, which might be minimized/obfuscated if the app is using ProGuard or + // similar. In order for a device to successfully migrate from v4 to v5 picking + // up the subscription, we need to copy the shared preferences from the obfuscated + // version to the static "OneSignal" preference name. We only do this + // if there isn't already a "OneSignal" preference store. + val sharedPrefsDir = + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + File(context.dataDir, "shared_prefs") + } else { + File(context.filesDir.parentFile, "shared_prefs") + } + + val osPrefsFile = File(sharedPrefsDir, "OneSignal.xml") + + if (!sharedPrefsDir.exists() || !sharedPrefsDir.isDirectory || osPrefsFile.exists()) { + return + } + + val prefsFileList = sharedPrefsDir.listFiles() ?: return + + // Go through every preference file, looking for the OneSignal preference store. + for (prefsFile in prefsFileList) { + val prefsStore = + context.getSharedPreferences(prefsFile.nameWithoutExtension, Context.MODE_PRIVATE) + + if (prefsStore.contains(PreferenceOneSignalKeys.PREFS_LEGACY_PLAYER_ID)) { + prefsFile.renameTo(osPrefsFile) + return + } + } + } catch (e: Throwable) { + Logging.log(LogLevel.ERROR, "error attempting to fix obfuscated preference store", e) + } + } +} diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/internal/OneSignalImp.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/internal/OneSignalImp.kt index b19dce209f..979ea310e2 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/internal/OneSignalImp.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/internal/OneSignalImp.kt @@ -19,6 +19,7 @@ import com.onesignal.core.internal.config.ConfigModelStore import com.onesignal.core.internal.operations.IOperationRepo import com.onesignal.core.internal.preferences.IPreferencesService import com.onesignal.core.internal.preferences.PreferenceOneSignalKeys +import com.onesignal.core.internal.preferences.PreferenceStoreFix import com.onesignal.core.internal.preferences.PreferenceStores import com.onesignal.core.internal.startup.StartupService import com.onesignal.debug.IDebugManager @@ -175,6 +176,8 @@ internal class OneSignalImp : IOneSignal, IServiceProvider { return true } + PreferenceStoreFix.ensureNoObfuscatedPrefStore(context) + // start the application service. This is called explicitly first because we want // to make sure it has the context provided on input, for all other startable services // to depend on if needed.