Skip to content

Commit

Permalink
Merge pull request #1 from openedx/develop
Browse files Browse the repository at this point in the history
Update the develop branch with the latest changes
  • Loading branch information
dixidroid authored Oct 4, 2024
2 parents b5256ce + 4c1a909 commit 75ac68d
Show file tree
Hide file tree
Showing 133 changed files with 3,800 additions and 1,188 deletions.
3 changes: 2 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ apply plugin: 'com.android.application'
apply plugin: 'org.jetbrains.kotlin.android'
apply plugin: 'kotlin-parcelize'
apply plugin: 'kotlin-kapt'
apply plugin: 'fullstory'

if (firebaseEnabled) {
apply plugin: 'com.google.gms.google-services'
Expand All @@ -30,6 +29,7 @@ if (firebaseEnabled) {
}

if (fullstoryEnabled) {
apply plugin: 'fullstory'
def fullstoryOrgId = fullstoryConfig?.get("ORG_ID")

fullstory {
Expand Down Expand Up @@ -107,6 +107,7 @@ android {
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_17
freeCompilerArgs = List.of("-Xstring-concat=inline")
}
buildFeatures {
viewBinding true
Expand Down
100 changes: 30 additions & 70 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -1,66 +1,3 @@
# 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

#====================/////Retrofit Rules\\\\\===============
# Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and
# EnclosingMethod is required to use InnerClasses.
-keepattributes Signature, InnerClasses, EnclosingMethod

# Retrofit does reflection on method and parameter annotations.
-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations

# Keep annotation default values (e.g., retrofit2.http.Field.encoded).
-keepattributes AnnotationDefault

# Retain service method parameters when optimizing.
-keepclassmembers,allowshrinking,allowobfuscation interface * {
@retrofit2.http.* <methods>;
}

# Ignore JSR 305 annotations for embedding nullability information.
-dontwarn javax.annotation.**

# Guarded by a NoClassDefFoundError try/catch and only used when on the classpath.
-dontwarn kotlin.Unit

# Top-level functions that can only be used by Kotlin.
-dontwarn retrofit2.KotlinExtensions
-dontwarn retrofit2.KotlinExtensions$*

# With R8 full mode, it sees no subtypes of Retrofit interfaces since they are created with a Proxy
# and replaces all potential values with null. Explicitly keeping the interfaces prevents this.
-if interface * { @retrofit2.http.* <methods>; }
-keep,allowobfuscation interface <1>

# Keep generic signature of Call, Response (R8 full mode strips signatures from non-kept items).
-keep,allowobfuscation,allowshrinking interface retrofit2.Call
-keep,allowobfuscation,allowshrinking class retrofit2.Response

# With R8 full mode generic signatures are stripped for classes that are not
# kept. Suspend functions are wrapped in continuations where the type argument
# is used.
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation

#===============/////GSON RULES \\\\\\\============
##---------------Begin: proguard configuration for Gson ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
Expand All @@ -69,12 +6,8 @@
# For using GSON @Expose annotation
-keepattributes *Annotation*

# Gson specific classes
-dontwarn sun.misc.**
#-keep class com.google.gson.stream.** { *; }

# Application classes that will be serialized/deserialized over Gson
-keep class org.openedx.*.data.model.** { <fields>; }
-keepclassmembers class org.openedx.**.data.model.** { *; }

# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
Expand All @@ -85,13 +18,13 @@

# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
<init>();
@com.google.gson.annotations.SerializedName <fields>;
}

# Retain generic signatures of TypeToken and its subclasses with R8 version 3.0 and higher.
-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken
-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken

##---------------End: proguard configuration for Gson ----------

-keepclassmembers class * extends java.lang.Enum {
Expand All @@ -108,4 +41,31 @@
-dontwarn org.conscrypt.ConscryptHostnameVerifier
-dontwarn org.openjsse.javax.net.ssl.SSLParameters
-dontwarn org.openjsse.javax.net.ssl.SSLSocket
-dontwarn org.openjsse.net.ssl.OpenJSSE
-dontwarn org.openjsse.net.ssl.OpenJSSE
-dontwarn com.google.crypto.tink.subtle.Ed25519Sign$KeyPair
-dontwarn com.google.crypto.tink.subtle.Ed25519Sign
-dontwarn com.google.crypto.tink.subtle.Ed25519Verify
-dontwarn com.google.crypto.tink.subtle.X25519
-dontwarn com.segment.analytics.kotlin.core.platform.plugins.logger.LogFilterKind
-dontwarn com.segment.analytics.kotlin.core.platform.plugins.logger.LogTargetKt
-dontwarn edu.umd.cs.findbugs.annotations.NonNull
-dontwarn edu.umd.cs.findbugs.annotations.Nullable
-dontwarn edu.umd.cs.findbugs.annotations.SuppressFBWarnings
-dontwarn org.bouncycastle.asn1.ASN1Encodable
-dontwarn org.bouncycastle.asn1.pkcs.PrivateKeyInfo
-dontwarn org.bouncycastle.asn1.x509.AlgorithmIdentifier
-dontwarn org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
-dontwarn org.bouncycastle.cert.X509CertificateHolder
-dontwarn org.bouncycastle.cert.jcajce.JcaX509CertificateHolder
-dontwarn org.bouncycastle.crypto.BlockCipher
-dontwarn org.bouncycastle.crypto.CipherParameters
-dontwarn org.bouncycastle.crypto.InvalidCipherTextException
-dontwarn org.bouncycastle.crypto.engines.AESEngine
-dontwarn org.bouncycastle.crypto.modes.GCMBlockCipher
-dontwarn org.bouncycastle.crypto.params.AEADParameters
-dontwarn org.bouncycastle.crypto.params.KeyParameter
-dontwarn org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
-dontwarn org.bouncycastle.jce.provider.BouncyCastleProvider
-dontwarn org.bouncycastle.openssl.PEMKeyPair
-dontwarn org.bouncycastle.openssl.PEMParser
-dontwarn org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter
13 changes: 13 additions & 0 deletions app/src/main/java/org/openedx/app/AppActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.window.layout.WindowMetricsCalculator
import com.braze.support.toStringMap
import io.branch.referral.Branch
import io.branch.referral.Branch.BranchUniversalReferralInitListener
import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.openedx.app.databinding.ActivityAppBinding
Expand All @@ -30,6 +32,7 @@ import org.openedx.core.ui.WindowSize
import org.openedx.core.ui.WindowType
import org.openedx.core.utils.Logger
import org.openedx.core.worker.CalendarSyncScheduler
import org.openedx.course.presentation.download.DownloadDialogManager
import org.openedx.profile.presentation.ProfileRouter
import org.openedx.whatsnew.WhatsNewManager
import org.openedx.whatsnew.presentation.whatsnew.WhatsNewFragment
Expand All @@ -51,6 +54,7 @@ class AppActivity : AppCompatActivity(), InsetHolder, WindowSizeHolder {
private val whatsNewManager by inject<WhatsNewManager>()
private val corePreferencesManager by inject<CorePreferences>()
private val profileRouter by inject<ProfileRouter>()
private val downloadDialogManager by inject<DownloadDialogManager>()
private val calendarSyncScheduler by inject<CalendarSyncScheduler>()

private val branchLogger = Logger(BRANCH_TAG)
Expand Down Expand Up @@ -163,6 +167,15 @@ class AppActivity : AppCompatActivity(), InsetHolder, WindowSizeHolder {
profileRouter.restartApp(supportFragmentManager, viewModel.isLogistrationEnabled)
}

lifecycleScope.launch {
viewModel.downloadFailedDialog.collect {
downloadDialogManager.showDownloadFailedPopup(
downloadModel = it.downloadModel,
fragmentManager = supportFragmentManager,
)
}
}

calendarSyncScheduler.scheduleDailySync()
}

Expand Down
22 changes: 20 additions & 2 deletions app/src/main/java/org/openedx/app/AppViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.viewModelScope
import androidx.room.RoomDatabase
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.openedx.app.deeplink.DeepLink
Expand All @@ -20,6 +23,8 @@ import org.openedx.core.SingleEventLiveData
import org.openedx.core.config.Config
import org.openedx.core.data.model.User
import org.openedx.core.data.storage.CorePreferences
import org.openedx.core.system.notifier.DownloadFailed
import org.openedx.core.system.notifier.DownloadNotifier
import org.openedx.core.system.notifier.app.AppNotifier
import org.openedx.core.system.notifier.app.LogoutEvent
import org.openedx.core.system.notifier.app.SignInEvent
Expand All @@ -29,20 +34,26 @@ import org.openedx.core.utils.FileUtil
@SuppressLint("StaticFieldLeak")
class AppViewModel(
private val config: Config,
private val notifier: AppNotifier,
private val appNotifier: AppNotifier,
private val room: RoomDatabase,
private val preferencesManager: CorePreferences,
private val dispatcher: CoroutineDispatcher,
private val analytics: AppAnalytics,
private val deepLinkRouter: DeepLinkRouter,
private val fileUtil: FileUtil,
private val downloadNotifier: DownloadNotifier,
private val context: Context
) : BaseViewModel() {

private val _logoutUser = SingleEventLiveData<Unit>()
val logoutUser: LiveData<Unit>
get() = _logoutUser

private val _downloadFailedDialog = MutableSharedFlow<DownloadFailed>()
val downloadFailedDialog: SharedFlow<DownloadFailed>
get() = _downloadFailedDialog.asSharedFlow()


val isLogistrationEnabled get() = config.isPreLoginExperienceEnabled()

private var logoutHandledAt: Long = 0
Expand All @@ -66,14 +77,21 @@ class AppViewModel(
}

viewModelScope.launch {
notifier.notifier.collect { event ->
appNotifier.notifier.collect { event ->
if (event is SignInEvent && config.getFirebaseConfig().isCloudMessagingEnabled) {
SyncFirebaseTokenWorker.schedule(context)
} else if (event is LogoutEvent) {
handleLogoutEvent(event)
}
}
}
viewModelScope.launch {
downloadNotifier.notifier.collect { event ->
if (event is DownloadFailed) {
_downloadFailedDialog.emit(event)
}
}
}
}

fun logAppLaunchEvent() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,12 @@ class PreferencesManager(context: Context) : CorePreferences, ProfilePreferences
saveString(APP_CONFIG, appConfigJson)
}
get() {
val appConfigString = getString(APP_CONFIG)
val appConfigString = getString(APP_CONFIG, getDefaultAppConfig())
return Gson().fromJson(appConfigString, AppConfig::class.java)
}

private fun getDefaultAppConfig() = Gson().toJson(AppConfig())

override var lastWhatsNewVersion: String
set(value) {
saveString(LAST_WHATS_NEW_VERSION, value)
Expand Down Expand Up @@ -193,6 +195,12 @@ class PreferencesManager(context: Context) : CorePreferences, ProfilePreferences
}
get() = getString(CALENDAR_USER)

override var isRelativeDatesEnabled: Boolean
set(value) {
saveBoolean(IS_RELATIVE_DATES_ENABLED, value)
}
get() = getBoolean(IS_RELATIVE_DATES_ENABLED, true)

override var isHideInactiveCourses: Boolean
set(value) {
saveBoolean(HIDE_INACTIVE_COURSES, value)
Expand Down Expand Up @@ -223,6 +231,7 @@ class PreferencesManager(context: Context) : CorePreferences, ProfilePreferences
private const val CALENDAR_ID = "CALENDAR_ID"
private const val RESET_APP_DIRECTORY = "reset_app_directory"
private const val IS_CALENDAR_SYNC_ENABLED = "IS_CALENDAR_SYNC_ENABLED"
private const val IS_RELATIVE_DATES_ENABLED = "IS_RELATIVE_DATES_ENABLED"
private const val HIDE_INACTIVE_COURSES = "HIDE_INACTIVE_COURSES"
private const val CALENDAR_USER = "CALENDAR_USER"
}
Expand Down
7 changes: 7 additions & 0 deletions app/src/main/java/org/openedx/app/di/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import org.openedx.core.data.storage.CorePreferences
import org.openedx.core.data.storage.InAppReviewPreferences
import org.openedx.core.module.DownloadWorkerController
import org.openedx.core.module.TranscriptManager
import org.openedx.core.module.download.DownloadHelper
import org.openedx.core.module.download.FileDownloader
import org.openedx.core.presentation.CoreAnalytics
import org.openedx.core.presentation.dialog.appreview.AppReviewAnalytics
Expand All @@ -57,6 +58,8 @@ import org.openedx.core.worker.CalendarSyncScheduler
import org.openedx.course.data.storage.CoursePreferences
import org.openedx.course.presentation.CourseAnalytics
import org.openedx.course.presentation.CourseRouter
import org.openedx.course.presentation.download.DownloadDialogManager
import org.openedx.course.worker.OfflineProgressSyncScheduler
import org.openedx.dashboard.presentation.DashboardAnalytics
import org.openedx.dashboard.presentation.DashboardRouter
import org.openedx.discovery.presentation.DiscoveryAnalytics
Expand Down Expand Up @@ -89,6 +92,7 @@ val appModule = module {
single { AppCookieManager(get(), get()) }
single { ReviewManagerFactory.create(get()) }
single { CalendarManager(get(), get()) }
single { DownloadDialogManager(get(), get(), get(), get()) }
single { DatabaseManager(get(), get(), get(), get()) }
single<IDatabaseManager> { get<DatabaseManager>() }

Expand Down Expand Up @@ -200,6 +204,9 @@ val appModule = module {
factory { OAuthHelper(get(), get(), get()) }

factory { FileUtil(get()) }
single { DownloadHelper(get(), get()) }

factory { OfflineProgressSyncScheduler(get()) }

single { CalendarSyncScheduler(get()) }
}
Loading

0 comments on commit 75ac68d

Please sign in to comment.