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

Commit f9d76fc7 authored by Jonathan Klee's avatar Jonathan Klee
Browse files

Merge branch '1727-t-split-install-notification' into 'main'

Add Warning notification for Split installs

See merge request !416
parents e96c4c4b d77af3c3
Loading
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -118,6 +118,14 @@
            android:name=".install.splitinstall.SplitInstallService"
            tools:ignore="ExportedService"
            android:exported="true" />

        <receiver
            android:name=".install.splitinstall.SplitInstallBinder$IgnoreReceiver"
            android:exported="false" />

        <receiver
            android:name=".install.splitinstall.SplitInstallBinder$SignInReceiver"
            android:exported="false" />
    </application>

</manifest>
 No newline at end of file
+148 −0
Original line number Diff line number Diff line
@@ -18,9 +18,23 @@

package foundation.e.apps.install.splitinstall

import android.Manifest
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.pm.PackageInfoCompat
import foundation.e.apps.ISplitInstallService
import foundation.e.apps.MainActivity
import foundation.e.apps.R
import foundation.e.apps.data.DownloadManager
import foundation.e.apps.data.application.ApplicationRepository
import foundation.e.apps.data.login.AuthenticatorRepository
@@ -45,12 +59,19 @@ class SplitInstallBinder(
    companion object {
        const val TAG = "SplitInstallerBinder"
        const val AUTH_DATA_ERROR_MESSAGE = "Could not get auth data"
        const val NOTIFICATION_CHANNEL = "SplitInstallAppLounge"
        const val NOTIFICATION_ID_KEY = "notification_id_key"
    }

    override fun installSplitModule(packageName: String, moduleName: String) {
        try {
            coroutineScope.launch {
                authenticatorRepository.getValidatedAuthData()
            }

            if (authenticatorRepository.gplayAuth == null) {
                Timber.w(AUTH_DATA_ERROR_MESSAGE)
                handleError(packageName)
                return
            }

@@ -59,9 +80,106 @@ class SplitInstallBinder(
            }
        } catch (exception: GPlayLoginException) {
            Timber.w("$AUTH_DATA_ERROR_MESSAGE $exception")
            handleError(packageName)
        }
    }

    private fun handleError(packageName: String) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
            return
        }

        createNotificationChannel(context)
        showErrorNotification(context, packageName)
    }

    private fun createNotificationChannel(context: Context) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
            return
        }

        val descriptionText = context.getString(R.string.notification_channel_desc)
        val notificationChannel = NotificationChannel(
            NOTIFICATION_CHANNEL,
            NOTIFICATION_CHANNEL,
            NotificationManager.IMPORTANCE_HIGH
        ).apply {
            description = descriptionText
        }

        val notificationManager =
            context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        notificationManager.createNotificationChannel(notificationChannel)
    }

    private fun showErrorNotification(context: Context, packageName: String) {
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS)
            != PackageManager.PERMISSION_GRANTED
        ) {
            return
        }

        val appInfo = context.packageManager.getPackageInfo(packageName, 0).applicationInfo
        val appLabel = context.packageManager.getApplicationLabel(appInfo)
        val callerUid = appInfo.uid
        val contentText = context.getString(
            R.string.split_install_warning_text,
            appLabel
        )

        val notificationBuilder = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL)
            .setSmallIcon(R.drawable.app_lounge_notification_icon)
            .setContentTitle(context.getString(R.string.split_install_warning_title, appLabel))
            .setContentText(contentText)
            .setPriority(NotificationCompat.PRIORITY_MAX)
            .setStyle(NotificationCompat.BigTextStyle().bigText(contentText))
            .addAction(
                NotificationCompat.Action.Builder(
                    null,
                    context.getString(R.string.sign_in),
                    buildSignInPendingIntent(callerUid)
                ).build()
            )
            .addAction(
                NotificationCompat.Action.Builder(
                    null,
                    context.getString(R.string.ignore),
                    buildIgnorePendingIntent(callerUid)
                ).build()
            )

        with(NotificationManagerCompat.from(context)) {
            notify(callerUid, notificationBuilder.build())
        }
    }

    private fun buildIgnorePendingIntent(callerUid: Int): PendingIntent {
        val ignoreIntent = Intent(context, IgnoreReceiver::class.java).apply {
            putExtra(NOTIFICATION_ID_KEY, callerUid)
        }

        return PendingIntent.getBroadcast(
            context,
            callerUid,
            ignoreIntent,
            PendingIntent.FLAG_MUTABLE
        )
    }

    private fun buildSignInPendingIntent(callerUid: Int): PendingIntent {
        val signInIntent = Intent(context, SignInReceiver::class.java).apply {
            putExtra(NOTIFICATION_ID_KEY, callerUid)
        }

        return PendingIntent.getBroadcast(
            context,
            callerUid,
            signInIntent,
            PendingIntent.FLAG_MUTABLE
        )
    }

    fun setService(service: foundation.e.splitinstall.ISplitInstallService) {
        splitInstallSystemService = service
        installPendingModules()
@@ -123,4 +241,34 @@ class SplitInstallBinder(
            splitInstallSystemService?.installSplitModule(packageName, module)
        }
    }

    class IgnoreReceiver: BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            if (context == null || intent == null) {
                return
            }

            NotificationManagerCompat.from(context).cancel(
                intent.getIntExtra(NOTIFICATION_ID_KEY, -1)
            )
        }
    }

    class SignInReceiver: BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            if (context == null || intent == null) {
                return
            }

            NotificationManagerCompat.from(context).cancel(
                intent.getIntExtra(NOTIFICATION_ID_KEY, -1)
            )

            val launchAppLoungeIntent = Intent(context, MainActivity::class.java).apply {
                flags = Intent.FLAG_ACTIVITY_NEW_TASK
            }

            context.startActivity(launchAppLoungeIntent)
        }
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -170,4 +170,11 @@
    <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>

    <!--Split install-->
    <string name="split_install_warning_title">Warnung bezüglich %s</string>
    <string name="split_install_warning_text">%s möchte zusätzliche Module installieren. Sie müssen sich erneut bei AppLounge anmelden, um sie installieren zu können.</string>
    <string name="notification_channel_desc">Split-Installationskanal</string>
    <string name="sign_in">Einloggen</string>
    <string name="ignore">Ignorieren</string>
</resources>
 No newline at end of file
+5 −0
Original line number Diff line number Diff line
@@ -157,4 +157,9 @@
    <string name="free_space_for_update">Libera %1$s en tu teléfono para recibir las últimas actualizaciones.</string>

    <string name="notification_content_full_db">Por favor, libera algo de espacio en tu teléfono para que App Lounge funcione correctamente.</string>
    <string name="split_install_warning_title">Advertencia sobre %s</string>
    <string name="split_install_warning_text">%s quiere instalar módulos adicionales. Debes iniciar sesión nuevamente en AppLounge para poder instalarlos.</string>
    <string name="notification_channel_desc">Canal de instalación dividida</string>
    <string name="sign_in">Acceder</string>
    <string name="ignore">Ignorar</string>
</resources>
 No newline at end of file
+5 −0
Original line number Diff line number Diff line
@@ -168,4 +168,9 @@
    <string name="free_space_for_update">Libérez %1$s sur votre téléphone afin de bénéficier des dernières mises à jour.</string>
    <string name="notification_content_full_db">Merci de libérer de l\'espace sur votre téléphone pour qu\'App Lounge puisse fonctionner correctement.</string>
    <string name="checking_updates">Vérification des mises à jour...</string>
    <string name="split_install_warning_title">Avertissement concernant %s</string>
    <string name="split_install_warning_text">%s souhaite installer des modules supplémentaires. Vous devez vous reconnecter à AppLounge pour pouvoir les installer.</string>
    <string name="notification_channel_desc">Canal d\'installation fractionnée</string>
    <string name="sign_in">Connexion</string>
    <string name="ignore">Ignorer</string>
</resources>
 No newline at end of file
Loading