1 // Copyright 2015-present 650 Industries. All rights reserved. 2 package host.exp.exponent.storage 3 4 import android.content.Context 5 import host.exp.exponent.analytics.EXL 6 import host.exp.exponent.kernel.ExperienceKey 7 import host.exp.expoview.ExpoViewBuildConfig 8 import host.exp.expoview.R 9 import org.json.JSONException 10 import org.json.JSONObject 11 import javax.inject.Singleton 12 13 @Singleton 14 class ExponentSharedPreferences constructor(val context: Context) { 15 private val sharedPreferences = context.getSharedPreferences( 16 context.getString(R.string.preference_file_key), 17 Context.MODE_PRIVATE 18 ) 19 20 private val exponentInstallationId = ExponentInstallationId(context, sharedPreferences) 21 getBooleannull22 fun getBoolean(key: ExponentSharedPreferencesKey): Boolean { 23 return sharedPreferences.getBoolean(key.preferenceKey, DEFAULT_VALUES[key] ?: false) 24 } 25 getBooleannull26 fun getBoolean(key: ExponentSharedPreferencesKey, defaultValue: Boolean): Boolean { 27 return sharedPreferences.getBoolean(key.preferenceKey, defaultValue) 28 } 29 setBooleannull30 fun setBoolean(key: ExponentSharedPreferencesKey, value: Boolean) { 31 sharedPreferences.edit().putBoolean(key.preferenceKey, value).apply() 32 } 33 getIntegernull34 fun getInteger(key: ExponentSharedPreferencesKey): Int { 35 return getInteger(key, 0) 36 } 37 getIntegernull38 fun getInteger(key: ExponentSharedPreferencesKey, defaultValue: Int): Int { 39 return sharedPreferences.getInt(key.preferenceKey, defaultValue) 40 } 41 setIntegernull42 fun setInteger(key: ExponentSharedPreferencesKey, value: Int) { 43 sharedPreferences.edit().putInt(key.preferenceKey, value).apply() 44 } 45 getStringnull46 fun getString(key: ExponentSharedPreferencesKey): String? { 47 return getString(key, null) 48 } 49 getStringnull50 fun getString(key: ExponentSharedPreferencesKey, defaultValue: String?): String? { 51 return sharedPreferences.getString(key.preferenceKey, defaultValue) 52 } 53 setStringnull54 fun setString(key: ExponentSharedPreferencesKey, value: String?) { 55 sharedPreferences.edit().putString(key.preferenceKey, value).apply() 56 } 57 deletenull58 fun delete(key: ExponentSharedPreferencesKey) { 59 sharedPreferences.edit().remove(key.preferenceKey).apply() 60 } 61 shouldUseEmbeddedKernelnull62 fun shouldUseEmbeddedKernel(): Boolean { 63 return getBoolean(ExponentSharedPreferencesKey.USE_EMBEDDED_KERNEL_KEY) 64 } 65 getUUIDnull66 fun getUUID(): String? { 67 return exponentInstallationId.getUUID() 68 } 69 getOrCreateUUIDnull70 fun getOrCreateUUID(): String { 71 return exponentInstallationId.getOrCreateUUID() 72 } 73 updateSessionnull74 fun updateSession(session: JSONObject) { 75 setString(ExponentSharedPreferencesKey.EXPO_AUTH_SESSION, session.toString()) 76 } 77 removeSessionnull78 fun removeSession() { 79 setString(ExponentSharedPreferencesKey.EXPO_AUTH_SESSION, null) 80 } 81 82 val sessionSecret: String? 83 get() { 84 val sessionString = getString(ExponentSharedPreferencesKey.EXPO_AUTH_SESSION) 85 ?: return null 86 return try { 87 val session = JSONObject(sessionString) 88 session.getString(EXPO_AUTH_SESSION_SECRET_KEY) 89 } catch (e: Exception) { 90 EXL.e(TAG, e) 91 null 92 } 93 } 94 removeLegacyManifestnull95 fun removeLegacyManifest(manifestUrl: String) { 96 sharedPreferences.edit().remove(manifestUrl).apply() 97 } 98 updateExperienceMetadatanull99 fun updateExperienceMetadata(experienceKey: ExperienceKey, metadata: JSONObject) { 100 sharedPreferences.edit() 101 .putString(EXPERIENCE_METADATA_PREFIX + experienceKey.scopeKey, metadata.toString()).apply() 102 } 103 getExperienceMetadatanull104 fun getExperienceMetadata(experienceKey: ExperienceKey): JSONObject? { 105 val jsonString = 106 sharedPreferences.getString(EXPERIENCE_METADATA_PREFIX + experienceKey.scopeKey, null) 107 ?: return null 108 return try { 109 JSONObject(jsonString) 110 } catch (e: JSONException) { 111 EXL.e(TAG, e) 112 null 113 } 114 } 115 116 companion object { 117 private val TAG = ExponentSharedPreferences::class.java.simpleName 118 119 const val EXPO_AUTH_SESSION_SECRET_KEY = "sessionSecret" 120 121 // Metadata 122 const val EXPERIENCE_METADATA_PREFIX = "experience_metadata_" 123 const val EXPERIENCE_METADATA_UNREAD_REMOTE_NOTIFICATIONS = "unreadNotifications" 124 const val EXPERIENCE_METADATA_ALL_NOTIFICATION_IDS = "allNotificationIds" 125 const val EXPERIENCE_METADATA_ALL_SCHEDULED_NOTIFICATION_IDS = "allScheduledNotificationIds" 126 const val EXPERIENCE_METADATA_LOADING_ERROR = "loadingError" 127 const val EXPERIENCE_METADATA_PERMISSIONS = "permissions" 128 const val EXPERIENCE_METADATA_NOTIFICATION_CHANNELS = "notificationChannels" 129 130 private val DEFAULT_VALUES = mutableMapOf( 131 ExponentSharedPreferencesKey.USE_EMBEDDED_KERNEL_KEY to ExpoViewBuildConfig.USE_EMBEDDED_KERNEL, 132 ExponentSharedPreferencesKey.IS_ONBOARDING_FINISHED_KEY to false, 133 ExponentSharedPreferencesKey.NUX_HAS_FINISHED_FIRST_RUN_KEY to false, 134 ExponentSharedPreferencesKey.SHOULD_NOT_USE_KERNEL_CACHE to false 135 ) 136 } 137 138 init { 139 // We renamed `nux` to `onboarding` in January 2020 - the old preference key can be removed from here after some time, 140 // but since then we need to rewrite nux setting to the new key. 141 if (!sharedPreferences.contains(ExponentSharedPreferencesKey.IS_ONBOARDING_FINISHED_KEY.preferenceKey)) { 142 setBoolean(ExponentSharedPreferencesKey.IS_ONBOARDING_FINISHED_KEY, getBoolean(ExponentSharedPreferencesKey.NUX_HAS_FINISHED_FIRST_RUN_KEY)) 143 } 144 } 145 146 enum class ExponentSharedPreferencesKey(val preferenceKey: String) { 147 // Dev options 148 USE_EMBEDDED_KERNEL_KEY("use_embedded_kernel"), 149 150 // Other 151 FCM_TOKEN_KEY("fcm_token"), 152 REFERRER_KEY("referrer"), 153 NUX_HAS_FINISHED_FIRST_RUN_KEY("nux_has_finished_first_run"), 154 IS_ONBOARDING_FINISHED_KEY("is_onboarding_finished"), 155 SHOULD_NOT_USE_KERNEL_CACHE("should_not_use_kernel_cache"), 156 KERNEL_REVISION_ID("kernel_revision_id"), 157 EXPO_AUTH_SESSION("expo_auth_session"), 158 OKHTTP_CACHE_VERSION_KEY("okhttp_cache_version"), 159 } 160 } 161