Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eb9c3cf9 authored by Hasib Prince's avatar Hasib Prince
Browse files

Merge branch 'main' into 1709-remove_code_smell

parents 97abd5aa fc46c00b
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import foundation.e.apps.install.pkg.PkgManagerModule
import foundation.e.apps.install.updates.UpdatesWorkManager
import foundation.e.apps.install.workmanager.InstallWorkManager
import foundation.e.apps.ui.setup.tos.TOS_VERSION
import foundation.e.apps.utils.CustomUncaughtExceptionHandler
import foundation.e.lib.telemetry.Telemetry
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.MainScope
@@ -59,10 +60,15 @@ class AppLoungeApplication : Application(), Configuration.Provider {
    @Inject
    lateinit var preferenceManagerModule: PreferenceManagerModule

    @Inject
    lateinit var uncaughtExceptionHandler: CustomUncaughtExceptionHandler

    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
    override fun onCreate() {
        super.onCreate()

        Thread.setDefaultUncaughtExceptionHandler(uncaughtExceptionHandler)

        InstallWorkManager.context = this
        // Register broadcast receiver for package manager
        val pkgManagerBR = object : PkgManagerBR() {}
+6 −4
Original line number Diff line number Diff line
@@ -72,9 +72,11 @@ class InstallAppWorker @AssistedInject constructor(
    private fun createForegroundInfo(progress: String): ForegroundInfo {
        val title = applicationContext.getString(R.string.app_name)
        val cancel = applicationContext.getString(R.string.cancel)
        val channelId = context.getString(R.string.basic_notification_channel_id)

        // This PendingIntent can be used to cancel the worker
        val intent = WorkManager.getInstance(applicationContext)
            .createCancelPendingIntent(getId())
            .createCancelPendingIntent(id)

        val notificationManager =
            context.getSystemService(Context.NOTIFICATION_SERVICE) as
@@ -82,14 +84,14 @@ class InstallAppWorker @AssistedInject constructor(
        // Create a Notification channel if necessary
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val mChannel = NotificationChannel(
                "applounge_notification",
                channelId,
                title,
                NotificationManager.IMPORTANCE_LOW
            )
            notificationManager.createNotificationChannel(mChannel)
        }

        val notification = NotificationCompat.Builder(applicationContext, "applounge_notification")
        val notification = NotificationCompat.Builder(applicationContext, channelId)
            .setContentTitle(title)
            .setTicker(title)
            .setContentText(progress)
+4 −1
Original line number Diff line number Diff line
@@ -103,7 +103,10 @@ class HomeViewModel @Inject constructor(
    private fun postHomeResult(homeResult: ResultSupreme<List<Home>>) {
        if (shouldUpdateResult(homeResult)) {
            homeScreenData.value = homeResult
            currentHomes = homeResult.data
            // Here, homeResult.data is a mutableList which can be changed anytime.
            // That's why we're setting copy of the list, so that currentHomes isn't changed,
            // when homeresult.data is changed.
            currentHomes = homeResult.data?.map { it.copy() }
            return
        }

+97 −0
Original line number Diff line number Diff line
/*
 * Apps  Quickly and easily install Android apps onto your device!
 * Copyright (C) 2023 MURENA SAS
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package foundation.e.apps.utils

import android.Manifest
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.content.pm.PackageManager
import android.database.sqlite.SQLiteFullException
import android.os.Build
import androidx.annotation.StringRes
import androidx.core.app.ActivityCompat
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import dagger.hilt.android.qualifiers.ApplicationContext
import foundation.e.apps.R
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class CustomUncaughtExceptionHandler @Inject constructor(
    @ApplicationContext private val context: Context
) : Thread.UncaughtExceptionHandler {

    companion object {
        private const val NOTIFICATION_ID = 404
    }

    override fun uncaughtException(thread: Thread, throwable: Throwable) {
        Timber.e(throwable, "unhandled exception is caught at thread: ${thread.name}")

        if (throwable is SQLiteFullException || throwable.cause is SQLiteFullException) {
            showNotification(R.string.notification_content_full_db)
        }
    }

    private fun showNotification(@StringRes contentId: Int) {
        if (ActivityCompat.checkSelfPermission(
                context, Manifest.permission.POST_NOTIFICATIONS
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            return
        }

        createNotificationChannel()

        val notification = getNotification(contentId)
        NotificationManagerCompat.from(context).notify(NOTIFICATION_ID, notification)
    }

    private fun getNotification(@StringRes contentId: Int): Notification {
        val content = context.getString(contentId)
        val channelId = context.getString(R.string.warning_notification_channel_id)
        val title = context.getString(R.string.app_name)

        return NotificationCompat.Builder(context, channelId)
            .setSmallIcon(R.drawable.app_lounge_notification_icon)
            .setContentTitle(title)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setAutoCancel(true)
            .setContentText(content).build()
    }

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val id = context.getString(R.string.warning_notification_channel_id)
            val title = context.getString(R.string.warning_notification_channel_title)

            val channel = NotificationChannel(
                id, title, NotificationManager.IMPORTANCE_DEFAULT
            )

            val notificationManager: NotificationManager =
                context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -169,4 +169,6 @@
    <string name="checking_updates">Aktualisierungen werden überprüft …</string>
    <string name="too_many_requests_desc">Das anonyme Konto, das von Ihnen genutzt wird, ist nicht verfügbar. Bitte erneuern (refresh) Sie die Sitzung, um ein neues anonymes Konto zu erhalten.</string>
    <string name="refresh_session">SITZUNG ERNEUERN</string>

    <string name="notification_content_full_db">Bitte etwas Platz auf dem Telefon freimachen, damit die App Lounge ordnungsgemäß funktionieren kann.</string>
</resources>
 No newline at end of file
Loading