Merge pull request #3585 from Isira-Seneviratne/AGP_8.0

Upgrade to AGP 8.0.
This commit is contained in:
Bnyro 2023-05-10 20:50:08 +02:00 committed by GitHub
commit 9dcdda2bab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 113 additions and 33 deletions

View File

@ -33,10 +33,10 @@ jobs:
python checkrun.py python checkrun.py
cd .. cd ..
- name: Set up JDK 11 - name: Set up JDK 17
uses: actions/setup-java@v3 uses: actions/setup-java@v3
with: with:
java-version: 11 java-version: 17
distribution: "temurin" distribution: "temurin"
cache: "gradle" cache: "gradle"

View File

@ -37,9 +37,17 @@ jobs:
# Learn more about CodeQL language support at https://git.io/codeql-language-support # Learn more about CodeQL language support at https://git.io/codeql-language-support
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: Setup Java 17
uses: actions/setup-java@v3
with:
java-version: 17
distribution: "temurin"
cache: "gradle"
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v2 uses: github/codeql-action/init@v2

View File

@ -53,11 +53,11 @@ android {
} }
compileOptions { compileOptions {
coreLibraryDesugaringEnabled true coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_17
} }
kotlinOptions { kotlinOptions {
jvmTarget = '1.8' jvmTarget = JavaVersion.VERSION_17
} }
splits { splits {
abi { abi {

View File

@ -52,3 +52,57 @@
} }
-keepattributes RuntimeVisibleAnnotations,AnnotationDefault -keepattributes RuntimeVisibleAnnotations,AnnotationDefault
# -- Retrofit keep rules, obtained from https://github.com/square/retrofit/blob/master/retrofit/src/main/resources/META-INF/proguard/retrofit2.pro
# Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and
# EnclosingMethod is required to use InnerClasses.
-keepattributes Signature, InnerClasses, EnclosingMethod
# Retrofit does reflection on method and parameter annotations.
-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations
# Keep annotation default values (e.g., retrofit2.http.Field.encoded).
-keepattributes AnnotationDefault
# Retain service method parameters when optimizing.
-keepclassmembers,allowshrinking,allowobfuscation interface * {
@retrofit2.http.* <methods>;
}
# Ignore annotation used for build tooling.
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
# Ignore JSR 305 annotations for embedding nullability information.
-dontwarn javax.annotation.**
# Guarded by a NoClassDefFoundError try/catch and only used when on the classpath.
-dontwarn kotlin.Unit
# Top-level functions that can only be used by Kotlin.
-dontwarn retrofit2.KotlinExtensions
-dontwarn retrofit2.KotlinExtensions$*
# With R8 full mode, it sees no subtypes of Retrofit interfaces since they are created with a Proxy
# and replaces all potential values with null. Explicitly keeping the interfaces prevents this.
-if interface * { @retrofit2.http.* <methods>; }
-keep,allowobfuscation interface <1>
# Keep inherited services.
-if interface * { @retrofit2.http.* <methods>; }
-keep,allowobfuscation interface * extends <1>
# Keep generic signature of Call, Response (R8 full mode strips signatures from non-kept items).
-keep,allowobfuscation,allowshrinking interface retrofit2.Call
-keep,allowobfuscation,allowshrinking class retrofit2.Response
# With R8 full mode generic signatures are stripped for classes that are not
# kept. Suspend functions are wrapped in continuations where the type argument
# is used.
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
# -- End of Retrofit keep rules
-dontwarn org.conscrypt.**
-dontwarn org.bouncycastle.**
-dontwarn org.openjsse.**

View File

@ -35,7 +35,6 @@ data class Streams(
val uploaderSubscriberCount: Long = 0, val uploaderSubscriberCount: Long = 0,
val previewFrames: List<PreviewFrames> = emptyList(), val previewFrames: List<PreviewFrames> = emptyList(),
) { ) {
@Suppress("NewApi") // The Paths class is desugared.
fun toDownloadItems( fun toDownloadItems(
videoId: String, videoId: String,
fileName: String, fileName: String,

View File

@ -10,6 +10,5 @@ fun Path.toAndroidUriOrNull(): Uri? {
} }
fun Path.toAndroidUri(): Uri { fun Path.toAndroidUri(): Uri {
@Suppress("NewApi") // The Path class is desugared.
return toFile().toUri() return toFile().toUri()
} }

View File

@ -9,7 +9,6 @@ import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.db.obj.DownloadItem import com.github.libretube.db.obj.DownloadItem
import com.github.libretube.services.DownloadService import com.github.libretube.services.DownloadService
import java.nio.file.Path import java.nio.file.Path
import kotlin.io.path.createDirectories
object DownloadHelper { object DownloadHelper {
const val VIDEO_DIR = "video" const val VIDEO_DIR = "video"
@ -35,8 +34,11 @@ object DownloadHelper {
} }
fun getDownloadDir(context: Context, path: String): Path { fun getDownloadDir(context: Context, path: String): Path {
@Suppress("NewApi") // The Path class is desugared. // TODO: Use createDirectories() when https://issuetracker.google.com/issues/279034662 is
return getOfflineStorageDir(context).resolve(path).createDirectories() // fixed.
return getOfflineStorageDir(context).resolve(path).apply {
toFile().mkdirs()
}
} }
fun getMaxConcurrentDownloads(): Int { fun getMaxConcurrentDownloads(): Int {

View File

@ -44,6 +44,7 @@ object ImportHelper {
/** /**
* Get a list of channel IDs from a file [Uri] * Get a list of channel IDs from a file [Uri]
*/ */
@OptIn(ExperimentalSerializationApi::class)
private fun getChannelsFromUri(activity: Activity, uri: Uri): List<String> { private fun getChannelsFromUri(activity: Activity, uri: Uri): List<String> {
return when (val fileType = activity.contentResolver.getType(uri)) { return when (val fileType = activity.contentResolver.getType(uri)) {
"application/json", "application/*", "application/octet-stream" -> { "application/json", "application/*", "application/octet-stream" -> {
@ -72,6 +73,7 @@ object ImportHelper {
/** /**
* Write the text to the document * Write the text to the document
*/ */
@OptIn(ExperimentalSerializationApi::class)
suspend fun exportSubscriptions(activity: Activity, uri: Uri) { suspend fun exportSubscriptions(activity: Activity, uri: Uri) {
val token = PreferenceHelper.getToken() val token = PreferenceHelper.getToken()
val subs = if (token.isNotEmpty()) { val subs = if (token.isNotEmpty()) {
@ -149,6 +151,7 @@ object ImportHelper {
/** /**
* Export Playlists * Export Playlists
*/ */
@OptIn(ExperimentalSerializationApi::class)
suspend fun exportPlaylists(activity: Activity, uri: Uri) { suspend fun exportPlaylists(activity: Activity, uri: Uri) {
val playlists = PlaylistsHelper.exportPlaylists() val playlists = PlaylistsHelper.exportPlaylists()
val playlistFile = ImportPlaylistFile("Piped", 1, playlists) val playlistFile = ImportPlaylistFile("Piped", 1, playlists)

View File

@ -10,6 +10,7 @@ object NetworkHelper {
/** /**
* Detect whether network is available * Detect whether network is available
*/ */
@Suppress("DEPRECATION")
fun isNetworkAvailable(context: Context): Boolean { fun isNetworkAvailable(context: Context): Boolean {
// In case we are using a VPN, we return true since we might be using reverse tethering // In case we are using a VPN, we return true since we might be using reverse tethering
val connectivityManager = context.getSystemService<ConnectivityManager>() ?: return false val connectivityManager = context.getSystemService<ConnectivityManager>() ?: return false
@ -36,6 +37,7 @@ object NetworkHelper {
* @param context Context of the application * @param context Context of the application
* @return whether the network is metered or not * @return whether the network is metered or not
*/ */
@Suppress("DEPRECATION")
fun isNetworkMetered(context: Context): Boolean { fun isNetworkMetered(context: Context): Boolean {
val connectivityManager = context.getSystemService<ConnectivityManager>()!! val connectivityManager = context.getSystemService<ConnectivityManager>()!!
val activeNetworkInfo = connectivityManager.activeNetworkInfo val activeNetworkInfo = connectivityManager.activeNetworkInfo

View File

@ -132,7 +132,7 @@ object ThemeHelper {
* Get the styled app name * Get the styled app name
*/ */
fun getStyledAppName(context: Context): Spanned { fun getStyledAppName(context: Context): Spanned {
val colorPrimary = getThemeColor(context, R.attr.colorPrimaryDark) val colorPrimary = getThemeColor(context, androidx.appcompat.R.attr.colorPrimaryDark)
val hexColor = String.format("#%06X", (0xFFFFFF and colorPrimary)) val hexColor = String.format("#%06X", (0xFFFFFF and colorPrimary))
return "Libre<span style='color:$hexColor';>Tube</span>" return "Libre<span style='color:$hexColor';>Tube</span>"
.parseAsHtml(HtmlCompat.FROM_HTML_MODE_COMPACT) .parseAsHtml(HtmlCompat.FROM_HTML_MODE_COMPACT)

View File

@ -57,6 +57,7 @@ import java.nio.file.StandardOpenOption
import java.util.concurrent.Executors import java.util.concurrent.Executors
import kotlin.io.path.absolute import kotlin.io.path.absolute
import kotlin.io.path.createFile import kotlin.io.path.createFile
import kotlin.io.path.deleteIfExists
import kotlin.io.path.fileSize import kotlin.io.path.fileSize
/** /**
@ -103,7 +104,6 @@ class DownloadService : LifecycleService() {
} }
val thumbnailTargetPath = getDownloadPath(DownloadHelper.THUMBNAIL_DIR, fileName) val thumbnailTargetPath = getDownloadPath(DownloadHelper.THUMBNAIL_DIR, fileName)
.absolute()
val download = Download( val download = Download(
videoId, videoId,
@ -147,7 +147,7 @@ class DownloadService : LifecycleService() {
FileType.AUDIO -> getDownloadPath(DownloadHelper.AUDIO_DIR, item.fileName) FileType.AUDIO -> getDownloadPath(DownloadHelper.AUDIO_DIR, item.fileName)
FileType.VIDEO -> getDownloadPath(DownloadHelper.VIDEO_DIR, item.fileName) FileType.VIDEO -> getDownloadPath(DownloadHelper.VIDEO_DIR, item.fileName)
FileType.SUBTITLE -> getDownloadPath(DownloadHelper.SUBTITLE_DIR, item.fileName) FileType.SUBTITLE -> getDownloadPath(DownloadHelper.SUBTITLE_DIR, item.fileName)
}.createFile().absolute() }.apply { deleteIfExists() }.createFile()
lifecycleScope.launch(coroutineContext) { lifecycleScope.launch(coroutineContext) {
item.id = Database.downloadDao().insertDownloadItem(item).toInt() item.id = Database.downloadDao().insertDownloadItem(item).toInt()
@ -440,8 +440,7 @@ class DownloadService : LifecycleService() {
* Get a [File] from the corresponding download directory and the file name * Get a [File] from the corresponding download directory and the file name
*/ */
private fun getDownloadPath(directory: String, fileName: String): Path { private fun getDownloadPath(directory: String, fileName: String): Path {
@Suppress("NewApi") // The Path class is desugared. return DownloadHelper.getDownloadDir(this, directory).resolve(fileName).absolute()
return DownloadHelper.getDownloadDir(this, directory).resolve(fileName)
} }
override fun onDestroy() { override fun onDestroy() {

View File

@ -238,8 +238,14 @@ class MainActivity : BaseActivity() {
if (lastSeenVideoIndex < 1) return@observe if (lastSeenVideoIndex < 1) return@observe
binding.bottomNav.getOrCreateBadge(R.id.subscriptionsFragment).apply { binding.bottomNav.getOrCreateBadge(R.id.subscriptionsFragment).apply {
number = lastSeenVideoIndex number = lastSeenVideoIndex
backgroundColor = ThemeHelper.getThemeColor(this@MainActivity, R.attr.colorPrimary) backgroundColor = ThemeHelper.getThemeColor(
badgeTextColor = ThemeHelper.getThemeColor(this@MainActivity, R.attr.colorOnPrimary) this@MainActivity,
androidx.appcompat.R.attr.colorPrimary,
)
badgeTextColor = ThemeHelper.getThemeColor(
this@MainActivity,
com.google.android.material.R.attr.colorOnPrimary,
)
} }
} }
} }

View File

@ -103,8 +103,9 @@ class CommentsAdapter(
// highlight the comment that is being replied to // highlight the comment that is being replied to
if (comment == comments.firstOrNull()) { if (comment == comments.firstOrNull()) {
root.setBackgroundColor( root.setBackgroundColor(
ThemeHelper.getThemeColor(root.context, R.attr.colorSurface), ThemeHelper.getThemeColor(root.context, com.google.android.material.R.attr.colorSurface),
) )
root.updatePadding(top = 20) root.updatePadding(top = 20)
root.updateLayoutParams<MarginLayoutParams> { bottomMargin = 20 } root.updateLayoutParams<MarginLayoutParams> { bottomMargin = 20 }
} else { } else {

View File

@ -35,12 +35,12 @@ class LegacySubscriptionAdapter(
root.setOnClickListener { root.setOnClickListener {
NavigationHelper.navigateChannel( NavigationHelper.navigateChannel(
root.context, root.context,
subscription.url!!.toID(), subscription.url.toID(),
) )
} }
root.setOnLongClickListener { root.setOnLongClickListener {
ChannelOptionsBottomSheet(subscription.url!!.toID(), subscription.name) ChannelOptionsBottomSheet(subscription.url.toID(), subscription.name)
.show((root.context as BaseActivity).supportFragmentManager) .show((root.context as BaseActivity).supportFragmentManager)
true true
} }

View File

@ -40,7 +40,8 @@ class PlaylistsAdapter(
// set imageview drawable as empty playlist if imageview empty // set imageview drawable as empty playlist if imageview empty
if (playlist.thumbnail.orEmpty().split("/").size <= 4) { if (playlist.thumbnail.orEmpty().split("/").size <= 4) {
playlistThumbnail.setImageResource(R.drawable.ic_empty_playlist) playlistThumbnail.setImageResource(R.drawable.ic_empty_playlist)
playlistThumbnail.setBackgroundColor(R.attr.colorSurface) playlistThumbnail
.setBackgroundColor(com.google.android.material.R.attr.colorSurface)
} else { } else {
ImageHelper.loadImage(playlist.thumbnail, playlistThumbnail) ImageHelper.loadImage(playlist.thumbnail, playlistThumbnail)
} }

View File

@ -38,13 +38,13 @@ class SubscriptionChannelAdapter(
NavigationHelper.navigateChannel(root.context, subscription.url) NavigationHelper.navigateChannel(root.context, subscription.url)
} }
root.setOnLongClickListener { root.setOnLongClickListener {
ChannelOptionsBottomSheet(subscription.url!!.toID(), subscription.name) ChannelOptionsBottomSheet(subscription.url.toID(), subscription.name)
.show((root.context as BaseActivity).supportFragmentManager) .show((root.context as BaseActivity).supportFragmentManager)
true true
} }
subscriptionSubscribe.setupSubscriptionButton( subscriptionSubscribe.setupSubscriptionButton(
subscription.url?.toID(), subscription.url.toID(),
subscription.name, subscription.name,
notificationBell, notificationBell,
true, true,

View File

@ -21,7 +21,7 @@ class ErrorDialog : DialogFragment() {
.setTitle(R.string.error_occurred) .setTitle(R.string.error_occurred)
.setMessage(errorLog) .setMessage(errorLog)
.setNegativeButton(R.string.okay, null) .setNegativeButton(R.string.okay, null)
.setPositiveButton(R.string.copy) { _, _ -> .setPositiveButton(androidx.preference.R.string.copy) { _, _ ->
ClipboardHelper.save(requireContext(), errorLog) ClipboardHelper.save(requireContext(), errorLog)
Toast.makeText(context, R.string.copied, Toast.LENGTH_SHORT).show() Toast.makeText(context, R.string.copied, Toast.LENGTH_SHORT).show()
} }

View File

@ -41,7 +41,7 @@ class NotificationSettings : BasePreferenceFragment() {
NotificationHelper NotificationHelper
.enqueueWork( .enqueueWork(
context = requireContext(), context = requireContext(),
existingPeriodicWorkPolicy = ExistingPeriodicWorkPolicy.REPLACE, existingPeriodicWorkPolicy = ExistingPeriodicWorkPolicy.UPDATE,
) )
} }
} }

View File

@ -102,7 +102,7 @@ class CommentsSheet : ExpandedBottomSheet() {
// BottomSheetDialogFragment passthrough user outside touch event // BottomSheetDialogFragment passthrough user outside touch event
dialog.setOnShowListener { dialog.setOnShowListener {
dialog.findViewById<View>(R.id.touch_outside)?.apply { dialog.findViewById<View>(com.google.android.material.R.id.touch_outside)?.apply {
setOnTouchListener { v, event -> setOnTouchListener { v, event ->
event.setLocation(event.rawX - v.x, event.rawY - v.y) event.setLocation(event.rawX - v.x, event.rawY - v.y)
activity?.dispatchTouchEvent(event) activity?.dispatchTouchEvent(event)

View File

@ -7,7 +7,6 @@ import android.view.MotionEvent
import android.view.MotionEvent.ACTION_MOVE import android.view.MotionEvent.ACTION_MOVE
import android.view.ViewConfiguration import android.view.ViewConfiguration
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.github.libretube.R
import com.github.libretube.helpers.ThemeHelper import com.github.libretube.helpers.ThemeHelper
import com.google.android.material.elevation.SurfaceColors import com.google.android.material.elevation.SurfaceColors
import kotlin.math.abs import kotlin.math.abs
@ -18,7 +17,9 @@ class CustomSwipeToRefresh(context: Context?, attrs: AttributeSet?) :
private var mPrevX = 0f private var mPrevX = 0f
init { init {
setColorSchemeColors(ThemeHelper.getThemeColor(this.context, R.attr.colorPrimary)) setColorSchemeColors(
ThemeHelper.getThemeColor(this.context, androidx.appcompat.R.attr.colorPrimary),
)
setProgressBackgroundColorSchemeColor( setProgressBackgroundColorSchemeColor(
SurfaceColors.getColorForElevation(this.context, 20f), SurfaceColors.getColorForElevation(this.context, 20f),
) )

View File

@ -7,7 +7,6 @@ import android.graphics.Rect
import android.util.AttributeSet import android.util.AttributeSet
import android.view.View import android.view.View
import androidx.core.view.marginLeft import androidx.core.view.marginLeft
import com.github.libretube.R
import com.github.libretube.api.obj.Segment import com.github.libretube.api.obj.Segment
import com.github.libretube.constants.PreferenceKeys import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.extensions.dpToPx import com.github.libretube.extensions.dpToPx
@ -56,7 +55,10 @@ class MarkableTimeBar(
canvas.height - marginY, canvas.height - marginY,
), ),
Paint().apply { Paint().apply {
color = ThemeHelper.getThemeColor(context, R.attr.colorOnSecondary) color = ThemeHelper.getThemeColor(
context,
com.google.android.material.R.attr.colorOnSecondary,
)
}, },
) )
} }

View File

@ -11,7 +11,7 @@ buildscript {
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.4.2' classpath 'com.android.tools.build:gradle:8.0.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"

View File

@ -14,4 +14,7 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# Kotlin code style for this project: "official" or "obsolete": # Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official kotlin.code.style=official
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true
android.defaults.buildfeatures.buildconfig=true
android.nonTransitiveRClass=true
android.nonFinalResIds=true

View File

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
networkTimeout=10000 networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists