From 98322b33589b68df003a3b327e51a2b716c5ebf7 Mon Sep 17 00:00:00 2001 From: Aayush Gupta Date: Wed, 9 Oct 2024 21:52:14 +0530 Subject: [PATCH] Support unarchiving apps on Android 15+ devices Signed-off-by: Aayush Gupta --- app/src/main/AndroidManifest.xml | 9 +++ app/src/main/java/com/aurora/Constants.kt | 1 + .../data/receiver/UnarchivePackageReceiver.kt | 65 +++++++++++++++++++ .../com/aurora/store/util/NotificationUtil.kt | 29 ++++++++- app/src/main/res/values/strings.xml | 5 ++ 5 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/com/aurora/store/data/receiver/UnarchivePackageReceiver.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1b8789b97..98d0c8135 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -173,5 +173,14 @@ + + + + + + + diff --git a/app/src/main/java/com/aurora/Constants.kt b/app/src/main/java/com/aurora/Constants.kt index 2c9aec6a8..97142a8dc 100644 --- a/app/src/main/java/com/aurora/Constants.kt +++ b/app/src/main/java/com/aurora/Constants.kt @@ -41,6 +41,7 @@ object Constants { const val NOTIFICATION_CHANNEL_INSTALL = "NOTIFICATION_CHANNEL_INSTALL" const val NOTIFICATION_CHANNEL_DOWNLOADS = "NOTIFICATION_CHANNEL_DOWNLOADS" const val NOTIFICATION_CHANNEL_UPDATES = "NOTIFICATION_CHANNEL_UPDATES" + const val NOTIFICATION_CHANNEL_ACCOUNT = "NOTIFICATION_CHANNEL_ACCOUNT" const val GITLAB_URL = "https://gitlab.com/AuroraOSS/AuroraStore" const val URL_DISPENSER = "https://auroraoss.com/api/auth" diff --git a/app/src/main/java/com/aurora/store/data/receiver/UnarchivePackageReceiver.kt b/app/src/main/java/com/aurora/store/data/receiver/UnarchivePackageReceiver.kt new file mode 100644 index 000000000..3c91ad53c --- /dev/null +++ b/app/src/main/java/com/aurora/store/data/receiver/UnarchivePackageReceiver.kt @@ -0,0 +1,65 @@ +package com.aurora.store.data.receiver + +import android.app.NotificationManager +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.pm.PackageInstaller.EXTRA_UNARCHIVE_PACKAGE_NAME +import android.util.Log +import androidx.core.content.getSystemService +import com.aurora.extensions.isVAndAbove +import com.aurora.gplayapi.helpers.AppDetailsHelper +import com.aurora.gplayapi.network.IHttpClient +import com.aurora.store.AuroraApp +import com.aurora.store.data.helper.DownloadHelper +import com.aurora.store.data.providers.AccountProvider +import com.aurora.store.data.providers.AuthProvider +import com.aurora.store.util.NotificationUtil +import dagger.hilt.android.AndroidEntryPoint +import javax.inject.Inject +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch + +/** + * Triggers re-install/unarchive of a previously archived app on Android 15+ devices. + */ +@AndroidEntryPoint +class UnarchivePackageReceiver: BroadcastReceiver() { + + private val TAG = UnarchivePackageReceiver::class.java.simpleName + + @Inject + lateinit var httpClient: IHttpClient + + @Inject + lateinit var authProvider: AuthProvider + + @Inject + lateinit var downloadHelper: DownloadHelper + + override fun onReceive(context: Context?, intent: Intent?) { + if (isVAndAbove() && context != null && intent?.action == Intent.ACTION_UNARCHIVE_PACKAGE) { + val packageName = intent.getStringExtra(EXTRA_UNARCHIVE_PACKAGE_NAME)!! + Log.i(TAG, "Received request to unarchive $packageName") + + AuroraApp.scope.launch(Dispatchers.IO) { + if (!authProvider.isSavedAuthDataValid() || !AccountProvider.isLoggedIn(context)) { + Log.e(TAG, "Failed to authenticate user!") + with(context.getSystemService()!!) { + notify( + packageName.hashCode(), + NotificationUtil.getAuthDataExpiredNotification(context, packageName) + ) + } + return@launch + } + + val app = AppDetailsHelper(authProvider.authData!!) + .using(httpClient) + .getAppByPackageName(packageName) + + downloadHelper.enqueueApp(app) + } + } + } +} diff --git a/app/src/main/java/com/aurora/store/util/NotificationUtil.kt b/app/src/main/java/com/aurora/store/util/NotificationUtil.kt index 7987d0648..06f781533 100644 --- a/app/src/main/java/com/aurora/store/util/NotificationUtil.kt +++ b/app/src/main/java/com/aurora/store/util/NotificationUtil.kt @@ -49,6 +49,13 @@ object NotificationUtil { NotificationManager.IMPORTANCE_HIGH ) ) + channels.add( + NotificationChannel( + Constants.NOTIFICATION_CHANNEL_ACCOUNT, + context.getString(R.string.notification_channel_account), + NotificationManager.IMPORTANCE_HIGH + ) + ) channels.add( NotificationChannel( Constants.NOTIFICATION_CHANNEL_DOWNLOADS, @@ -254,7 +261,18 @@ object NotificationUtil { .setSmallIcon(R.drawable.ic_file_copy) .setContentTitle(context.getString(R.string.export_app_title)) .setContentText(context.getString(R.string.export_app_summary)) - .setOngoing(false) + .build() + } + + fun getAuthDataExpiredNotification(context: Context, packageName: String): Notification { + return NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_ACCOUNT) + .setSmallIcon(R.drawable.ic_account) + .setContentTitle(context.getString(R.string.authentication_required_title)) + .setContentText(context.getString(R.string.authentication_required_unarchive)) + .setAutoCancel(true) + .setContentIntent(getContentIntentForSplash(context, packageName)) + .setCategory(NotificationCompat.CATEGORY_ERROR) + .setPriority(NotificationCompat.PRIORITY_HIGH) .build() } @@ -315,6 +333,15 @@ object NotificationUtil { ) } + private fun getContentIntentForSplash(context: Context, packageName: String): PendingIntent { + return NavDeepLinkBuilder(context) + .setGraph(R.navigation.mobile_navigation) + .setDestination(R.id.splashFragment) + .setComponentName(MainActivity::class.java) + .setArguments(bundleOf("packageName" to packageName)) + .createPendingIntent() + } + private fun getContentIntentForDetails(context: Context, packageName: String): PendingIntent { return NavDeepLinkBuilder(context) .setGraph(R.navigation.mobile_navigation) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c9f489cbf..e8750035b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -188,6 +188,7 @@ "Optionally you can choose Native installer, but then you can not install bundled (split) APKs, so choice is yours." "New update available" "You can not install bundled(split) apps via Native Installer. Change your installer to Session, Services or Root." + Account-related notification App export notification Install notification Downloads notification @@ -465,4 +466,8 @@ Completed Queued Unavailable + + + Authentication required + Please log in to your Google Play account to unarchive the app!