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!