Implement Shizuku installer support

This commit is contained in:
grrfe
2023-06-15 17:28:05 +02:00
committed by Aayush Gupta
parent b4c4ac7cef
commit 20a0bea246
11 changed files with 236 additions and 1 deletions

View File

@@ -2,6 +2,7 @@
* Aurora Store * Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com> * Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
* Copyright (C) 2022, The Calyx Institute * Copyright (C) 2022, The Calyx Institute
* Copyright (C) 2023, grrfe <grrfe@420blaze.it>
* *
* Aurora Store is free software: you can redistribute it and/or modify * Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -25,6 +26,7 @@ plugins {
id 'androidx.navigation.safeargs.kotlin' id 'androidx.navigation.safeargs.kotlin'
id 'org.jlleitschuh.gradle.ktlint' id 'org.jlleitschuh.gradle.ktlint'
id 'com.starter.easylauncher' id 'com.starter.easylauncher'
id 'dev.rikka.tools.refine'
} }
java { java {
@@ -177,6 +179,16 @@ dependencies {
//Browser //Browser
implementation 'androidx.browser:browser:1.5.0' implementation 'androidx.browser:browser:1.5.0'
//Shizuku
def shizuku_version = '13.1.1'
compileOnly "dev.rikka.hidden:stub:4.2.0"
implementation "dev.rikka.tools.refine:runtime:4.3.0"
implementation "dev.rikka.shizuku:api:${shizuku_version}"
implementation "dev.rikka.shizuku:provider:${shizuku_version}"
implementation 'org.lsposed.hiddenapibypass:hiddenapibypass:4.3'
//Test //Test
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.ext:junit:1.1.5'

View File

@@ -2,6 +2,7 @@
~ Aurora Store ~ Aurora Store
~ Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com> ~ Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
~ Copyright (C) 2022, The Calyx Institute ~ Copyright (C) 2022, The Calyx Institute
~ Copyright (C) 2023, grrfe <grrfe@420blaze.it>
~ ~
~ Aurora Store is free software: you can redistribute it and/or modify ~ Aurora Store is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by ~ it under the terms of the GNU General Public License as published by
@@ -21,6 +22,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<uses-sdk tools:overrideLibrary="rikka.shizuku.api, rikka.shizuku.provider, rikka.shizuku.shared, rikka.shizuku.aidl" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
@@ -180,6 +183,15 @@
android:resource="@xml/paths" /> android:resource="@xml/paths" />
</provider> </provider>
<provider
android:name="rikka.shizuku.ShizukuProvider"
android:authorities="${applicationId}.shizuku"
android:multiprocess="false"
android:enabled="true"
android:exported="true"
android:permission="android.permission.INTERACT_ACROSS_USERS_FULL"
tools:ignore="MissingClass" />
<receiver android:name=".data.receiver.PackageManagerReceiver" <receiver android:name=".data.receiver.PackageManagerReceiver"
android:exported="false"> android:exported="false">
<intent-filter> <intent-filter>

View File

@@ -30,5 +30,11 @@
"title": "AM Installer", "title": "AM Installer",
"subtitle": "Install use App Manager", "subtitle": "Install use App Manager",
"description": "You must have App Manager. Need adb/root mode to install when miui optimization is on." "description": "You must have App Manager. Need adb/root mode to install when miui optimization is on."
},
{
"id": "5",
"title": "Shizuku Installer",
"subtitle": "Install using Shizuku",
"description": "Requires an active Shizuku installation, supports Android 8.0+"
} }
] ]

View File

@@ -1,6 +1,7 @@
/* /*
* Aurora Store * Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com> * Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
* Copyright (C) 2023, grrfe <grrfe@420blaze.it>
* *
* Aurora Store is free software: you can redistribute it and/or modify * Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -25,6 +26,7 @@ import android.os.Build
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.multidex.MultiDexApplication import androidx.multidex.MultiDexApplication
import com.aurora.Constants import com.aurora.Constants
import com.aurora.extensions.isPAndAbove
import com.aurora.store.data.downloader.DownloadManager import com.aurora.store.data.downloader.DownloadManager
import com.aurora.store.data.providers.NetworkProvider import com.aurora.store.data.providers.NetworkProvider
import com.aurora.store.data.receiver.PackageManagerReceiver import com.aurora.store.data.receiver.PackageManagerReceiver
@@ -35,6 +37,7 @@ import com.tonyodev.fetch2.Fetch
import java.util.ArrayList import java.util.ArrayList
import nl.komponents.kovenant.android.startKovenant import nl.komponents.kovenant.android.startKovenant
import nl.komponents.kovenant.android.stopKovenant import nl.komponents.kovenant.android.stopKovenant
import org.lsposed.hiddenapibypass.HiddenApiBypass
class AuroraApplication : MultiDexApplication() { class AuroraApplication : MultiDexApplication() {
@@ -48,6 +51,12 @@ class AuroraApplication : MultiDexApplication() {
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
// TODO: Only exempt required APIs
// Required for Shizuku installer
if (isPAndAbove()) {
HiddenApiBypass.addHiddenApiExemptions("")
}
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true) AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
//Create Notification Channels : General & Alert //Create Notification Channels : General & Alert

View File

@@ -1,6 +1,7 @@
/* /*
* Aurora Store * Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com> * Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
* Copyright (C) 2023, grrfe <grrfe@420blaze.it>
* *
* Aurora Store is free software: you can redistribute it and/or modify * Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -21,13 +22,16 @@ package com.aurora.store.data.installer
import android.content.Context import android.content.Context
import android.content.pm.PackageInstaller import android.content.pm.PackageInstaller
import android.content.pm.PackageManager
import com.aurora.extensions.isLAndAbove import com.aurora.extensions.isLAndAbove
import com.aurora.extensions.isOAndAbove
import com.aurora.store.BuildConfig import com.aurora.store.BuildConfig
import com.aurora.store.R import com.aurora.store.R
import com.aurora.store.util.PackageUtil import com.aurora.store.util.PackageUtil
import com.aurora.store.util.Preferences import com.aurora.store.util.Preferences
import com.aurora.store.util.Preferences.PREFERENCE_INSTALLER_ID import com.aurora.store.util.Preferences.PREFERENCE_INSTALLER_ID
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import rikka.shizuku.Shizuku
open class AppInstaller private constructor(var context: Context) { open class AppInstaller private constructor(var context: Context) {
@@ -75,6 +79,15 @@ open class AppInstaller private constructor(var context: Context) {
return PackageUtil.isInstalled(context, AMInstaller.AM_PACKAGE_NAME) or return PackageUtil.isInstalled(context, AMInstaller.AM_PACKAGE_NAME) or
PackageUtil.isInstalled(context, AMInstaller.AM_DEBUG_PACKAGE_NAME) PackageUtil.isInstalled(context, AMInstaller.AM_DEBUG_PACKAGE_NAME)
} }
fun hasShizuku(context: Context): Boolean {
return PackageUtil.isInstalled(context, ShizukuInstaller.SHIZUKU_PACKAGE_NAME)
}
fun hasShizukuPerm(): Boolean {
return Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED
}
} }
val choiceAndInstaller = HashMap<Int, IInstaller>() val choiceAndInstaller = HashMap<Int, IInstaller>()
@@ -122,6 +135,19 @@ open class AppInstaller private constructor(var context: Context) {
choiceAndInstaller[prefValue] = installer choiceAndInstaller[prefValue] = installer
installer installer
} }
5 -> {
if (isOAndAbove()) {
val installer = if (hasShizuku(context) && hasShizukuPerm()) {
ShizukuInstaller(context)
} else {
getDefaultInstaller(context)
}
choiceAndInstaller[prefValue] = installer
installer
} else {
getDefaultInstaller(context)
}
}
else -> { else -> {
val installer = getDefaultInstaller(context) val installer = getDefaultInstaller(context)
choiceAndInstaller[prefValue] = installer choiceAndInstaller[prefValue] = installer

View File

@@ -0,0 +1,99 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store 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 2 of the License, or
* (at your option) any later version.
*
* Aurora Store 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 Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.data.installer
import android.content.Context
import android.content.pm.*
import android.content.pm.PackageInstaller.SessionParams
import android.os.Build
import android.os.IBinder
import android.os.IInterface
import androidx.annotation.RequiresApi
import com.aurora.extensions.isOAndAbove
import com.aurora.extensions.isSAndAbove
import com.aurora.store.R
import com.aurora.store.util.Log
import dev.rikka.tools.refine.Refine
import rikka.shizuku.ShizukuBinderWrapper
import rikka.shizuku.SystemServiceHelper
class ShizukuInstaller(context: Context) : SessionInstallerBase(context) {
companion object {
const val SHIZUKU_PACKAGE_NAME = "moe.shizuku.privileged.api"
}
// Taken from LSPatch (https://github.com/LSPosed/LSPatch)
private fun IBinder.wrap() = ShizukuBinderWrapper(this)
private fun IInterface.asShizukuBinder() = this.asBinder().wrap()
private val iPackageManager: IPackageManager by lazy {
IPackageManager.Stub.asInterface(SystemServiceHelper.getSystemService("package").wrap())
}
private val iPackageInstaller: IPackageInstaller by lazy {
IPackageInstaller.Stub.asInterface(iPackageManager.packageInstaller.asShizukuBinder())
}
private val packageInstaller: PackageInstaller? by lazy {
if (isSAndAbove()) {
Refine.unsafeCast<PackageInstaller>(
PackageInstallerHidden(iPackageInstaller, "com.android.vending", null, 0)
)
} else if (isOAndAbove()) {
Refine.unsafeCast<PackageInstaller>(
PackageInstallerHidden(iPackageInstaller, "com.android.vending", 0)
)
} else null
}
@RequiresApi(Build.VERSION_CODES.O)
override fun install(packageName: String, files: List<Any>) {
if (isAlreadyQueued(packageName)) {
Log.i("$packageName already queued")
} else {
Log.i("Received session install request for $packageName")
val (sessionId, session) = kotlin.runCatching {
val sessionId =
packageInstaller!!.createSession(SessionParams(SessionParams.MODE_FULL_INSTALL))
val iSession = IPackageInstallerSession.Stub.asInterface(
iPackageInstaller.openSession(sessionId).asShizukuBinder()
)
val session = Refine.unsafeCast<PackageInstaller.Session>(
PackageInstallerHidden.SessionHidden(iSession)
)
sessionId to session
}.getOrElse { ex ->
ex.printStackTrace()
postError(
packageName,
context.getString(R.string.installer_status_failure),
context.getString(R.string.installer_shizuku_unavailable)
)
return
}
xInstall(sessionId, session, packageName, files)
}
}
}

View File

@@ -19,17 +19,21 @@
package com.aurora.store.view.ui.onboarding package com.aurora.store.view.ui.onboarding
import android.content.pm.PackageManager
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import com.aurora.extensions.isMIUI import com.aurora.extensions.isMIUI
import com.aurora.extensions.isMiuiOptimizationDisabled import com.aurora.extensions.isMiuiOptimizationDisabled
import com.aurora.extensions.isOAndAbove
import com.aurora.extensions.showDialog import com.aurora.extensions.showDialog
import com.aurora.store.R import com.aurora.store.R
import com.aurora.store.data.installer.AppInstaller.Companion.hasAppManager import com.aurora.store.data.installer.AppInstaller.Companion.hasAppManager
import com.aurora.store.data.installer.AppInstaller.Companion.hasRootAccess import com.aurora.store.data.installer.AppInstaller.Companion.hasRootAccess
import com.aurora.store.data.installer.AppInstaller.Companion.hasAuroraService import com.aurora.store.data.installer.AppInstaller.Companion.hasAuroraService
import com.aurora.store.data.installer.AppInstaller.Companion.hasShizuku
import com.aurora.store.data.installer.AppInstaller.Companion.hasShizukuPerm
import com.aurora.store.data.model.Installer import com.aurora.store.data.model.Installer
import com.aurora.store.databinding.FragmentOnboardingInstallerBinding import com.aurora.store.databinding.FragmentOnboardingInstallerBinding
import com.aurora.store.util.Preferences import com.aurora.store.util.Preferences
@@ -39,6 +43,7 @@ import com.aurora.store.view.epoxy.views.preference.InstallerViewModel_
import com.aurora.store.view.ui.commons.BaseFragment import com.aurora.store.view.ui.commons.BaseFragment
import com.aurora.store.view.ui.sheets.DeviceMiuiSheet import com.aurora.store.view.ui.sheets.DeviceMiuiSheet
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import rikka.shizuku.Shizuku
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets
@@ -48,11 +53,25 @@ class InstallerFragment : BaseFragment() {
var installerId: Int = 0 var installerId: Int = 0
private val shizukuResultListener =
Shizuku.OnRequestPermissionResultListener { _: Int, result: Int ->
if (result == PackageManager.PERMISSION_GRANTED) {
this.installerId = 5
save(PREFERENCE_INSTALLER_ID, 5)
} else {
showDialog(
R.string.action_installations,
R.string.installer_shizuku_unavailable
)
}
}
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
Shizuku.addRequestPermissionResultListener(shizukuResultListener)
B = FragmentOnboardingInstallerBinding.bind( B = FragmentOnboardingInstallerBinding.bind(
inflater.inflate( inflater.inflate(
R.layout.fragment_onboarding_installer, R.layout.fragment_onboarding_installer,
@@ -76,6 +95,11 @@ class InstallerFragment : BaseFragment() {
updateController(installerList) updateController(installerList)
} }
override fun onDestroy() {
Shizuku.removeRequestPermissionResultListener(shizukuResultListener)
super.onDestroy()
}
private fun updateController(installerList: List<Installer>) { private fun updateController(installerList: List<Installer>) {
B.epoxyRecycler.withModels { B.epoxyRecycler.withModels {
setFilterDuplicates(true) setFilterDuplicates(true)
@@ -140,6 +164,26 @@ class InstallerFragment : BaseFragment() {
) )
} }
} }
5 -> {
if (hasShizuku(requireContext()) && isOAndAbove()) {
if (hasShizukuPerm()) {
this.installerId = installerId
save(PREFERENCE_INSTALLER_ID, installerId)
} else if (Shizuku.shouldShowRequestPermissionRationale()) {
Shizuku.requestPermission(9000)
} else {
showDialog(
R.string.action_installations,
R.string.installer_shizuku_unavailable
)
}
} else {
showDialog(
R.string.action_installations,
R.string.installer_shizuku_unavailable
)
}
}
else -> { else -> {
this.installerId = installerId this.installerId = installerId
save(PREFERENCE_INSTALLER_ID, installerId) save(PREFERENCE_INSTALLER_ID, installerId)

View File

@@ -19,6 +19,7 @@
package com.aurora.store.view.ui.preferences package com.aurora.store.view.ui.preferences
import android.content.pm.PackageManager
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import androidx.preference.Preference import androidx.preference.Preference
@@ -30,12 +31,14 @@ import com.aurora.store.BuildConfig
import com.aurora.store.R import com.aurora.store.R
import com.aurora.store.data.installer.AMInstaller import com.aurora.store.data.installer.AMInstaller
import com.aurora.store.data.installer.ServiceInstaller import com.aurora.store.data.installer.ServiceInstaller
import com.aurora.store.data.installer.ShizukuInstaller
import com.aurora.store.util.CommonUtil import com.aurora.store.util.CommonUtil
import com.aurora.store.util.PackageUtil import com.aurora.store.util.PackageUtil
import com.aurora.store.util.Preferences import com.aurora.store.util.Preferences
import com.aurora.store.util.save import com.aurora.store.util.save
import com.aurora.store.view.custom.preference.AuroraListPreference import com.aurora.store.view.custom.preference.AuroraListPreference
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import rikka.shizuku.Shizuku
class InstallationPreference : PreferenceFragmentCompat() { class InstallationPreference : PreferenceFragmentCompat() {
@@ -100,6 +103,17 @@ class InstallationPreference : PreferenceFragmentCompat() {
) )
false false
} }
} else if (selectedId == 5) {
if (checkShizukuAvailability()) {
save(Preferences.PREFERENCE_INSTALLER_ID, selectedId)
true
} else {
showDialog(
R.string.action_installations,
R.string.installer_shizuku_unavailable
)
false
}
} else { } else {
save(Preferences.PREFERENCE_INSTALLER_ID, selectedId) save(Preferences.PREFERENCE_INSTALLER_ID, selectedId)
true true
@@ -137,4 +151,9 @@ class InstallationPreference : PreferenceFragmentCompat() {
AMInstaller.AM_DEBUG_PACKAGE_NAME AMInstaller.AM_DEBUG_PACKAGE_NAME
) )
} }
private fun checkShizukuAvailability(): Boolean {
return PackageUtil.isInstalled(requireContext(), ShizukuInstaller.SHIZUKU_PACKAGE_NAME) &&
Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED
}
} }

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?><!-- <?xml version="1.0" encoding="utf-8"?><!--
~ Aurora Store ~ Aurora Store
~ Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com> ~ Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
~ Copyright (C) 2023, grrfe <grrfe@420blaze.it>
~ ~
~ Aurora Store is free software: you can redistribute it and/or modify ~ Aurora Store is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by ~ it under the terms of the GNU General Public License as published by
@@ -115,6 +116,7 @@
<item>@string/pref_install_mode_root</item> <item>@string/pref_install_mode_root</item>
<item>@string/pref_install_mode_services</item> <item>@string/pref_install_mode_services</item>
<item>@string/pref_install_mode_am</item> <item>@string/pref_install_mode_am</item>
<item>@string/pref_install_mode_shizuku</item>
</string-array> </string-array>
<string-array name="pref_installation_method_values"> <string-array name="pref_installation_method_values">
@@ -123,6 +125,7 @@
<item>2</item> <item>2</item>
<item>3</item> <item>3</item>
<item>4</item> <item>4</item>
<item>5</item>
</string-array> </string-array>
<string-array name="link_urls"> <string-array name="link_urls">

View File

@@ -3,6 +3,7 @@
~ Aurora Store ~ Aurora Store
~ Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com> ~ Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
~ Copyright (C) 2022, The Calyx Institute ~ Copyright (C) 2022, The Calyx Institute
~ Copyright (C) 2023, grrfe <grrfe@420blaze.it>
~ ~
~ Aurora Store is free software: you can redistribute it and/or modify ~ Aurora Store is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by ~ it under the terms of the GNU General Public License as published by
@@ -160,6 +161,7 @@
<string name="filter_review_two">"Two"</string> <string name="filter_review_two">"Two"</string>
<string name="installer_am_unavailable">Install App Manager or change the installer.</string> <string name="installer_am_unavailable">Install App Manager or change the installer.</string>
<string name="installer_root_unavailable">No root access. Grant it or change the installer.</string> <string name="installer_root_unavailable">No root access. Grant it or change the installer.</string>
<string name="installer_shizuku_unavailable">Shizuku is not installed or set up properly.</string>
<string name="installer_service_available">"Aurora services is available and ready to install."</string> <string name="installer_service_available">"Aurora services is available and ready to install."</string>
<string name="installer_service_unavailable">Install Aurora services 1.0.9 or above, or change the installer.</string> <string name="installer_service_unavailable">Install Aurora services 1.0.9 or above, or change the installer.</string>
<string name="installer_service_misconfigured">Set up Aurora services and grant all permissions first.</string> <string name="installer_service_misconfigured">Set up Aurora services and grant all permissions first.</string>
@@ -228,6 +230,7 @@
<string name="pref_install_delete_summary">"APKs will be deleted by default"</string> <string name="pref_install_delete_summary">"APKs will be deleted by default"</string>
<string name="pref_install_delete_title">"Delete APK post-install"</string> <string name="pref_install_delete_title">"Delete APK post-install"</string>
<string name="pref_install_mode_am">AM installer.</string> <string name="pref_install_mode_am">AM installer.</string>
<string name="pref_install_mode_shizuku">Shizuku installer</string>
<string name="pref_install_mode_native">"Native installer"</string> <string name="pref_install_mode_native">"Native installer"</string>
<string name="pref_install_mode_root">"Root installer"</string> <string name="pref_install_mode_root">"Root installer"</string>
<string name="pref_install_mode_services">"Aurora Services"</string> <string name="pref_install_mode_services">"Aurora Services"</string>

View File

@@ -2,6 +2,7 @@
* Aurora Store * Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com> * Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
* Copyright (C) 2022, The Calyx Institute * Copyright (C) 2022, The Calyx Institute
* Copyright (C) 2023, grrfe <grrfe@420blaze.it>
* *
* Aurora Store is free software: you can redistribute it and/or modify * Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -24,6 +25,7 @@ plugins {
id 'androidx.navigation.safeargs.kotlin' version '2.6.0' apply false id 'androidx.navigation.safeargs.kotlin' version '2.6.0' apply false
id 'org.jlleitschuh.gradle.ktlint' version '11.4.0' apply false id 'org.jlleitschuh.gradle.ktlint' version '11.4.0' apply false
id 'com.starter.easylauncher' version '6.2.0' apply false id 'com.starter.easylauncher' version '6.2.0' apply false
id 'dev.rikka.tools.refine' version '4.3.0' apply false
} }
task clean(type: Delete) { task clean(type: Delete) {