Skip to content

Commit c2b6984

Browse files
authored
Merge pull request #13202 from TobiGr/update-refactor
Merge dev into refactor
2 parents d859a5e + aa8aa6a commit c2b6984

34 files changed

Lines changed: 227 additions & 166 deletions

File tree

.github/workflows/backport-pr.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
github.event.comment.author_association == 'MEMBER'
2323
)
2424
steps:
25-
- uses: actions/checkout@v4
25+
- uses: actions/checkout@v6
2626
- name: Get backport metadata
2727
# the target branch is the first argument after `/backport`
2828
env:

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838

3939
steps:
4040
- uses: actions/checkout@v6
41-
- uses: gradle/actions/wrapper-validation@v4
41+
- uses: gradle/actions/wrapper-validation@v5
4242

4343
- name: create and checkout branch
4444
# push events already checked out the branch

app/build.gradle.kts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
*/
55
import com.mikepenz.aboutlibraries.plugin.DuplicateMode
66

7+
import com.android.build.api.dsl.ApplicationExtension
8+
79
plugins {
810
alias(libs.plugins.android.application)
911
alias(libs.plugins.jetbrains.kotlin.android)
@@ -37,7 +39,7 @@ kotlin {
3739
}
3840
}
3941

40-
android {
42+
configure<ApplicationExtension> {
4143
compileSdk = 36
4244
namespace = "org.schabi.newpipe"
4345

@@ -47,9 +49,9 @@ android {
4749
minSdk = 23
4850
targetSdk = 35
4951

50-
versionCode = System.getProperty("versionCodeOverride")?.toInt() ?: 1007
52+
versionCode = System.getProperty("versionCodeOverride")?.toInt() ?: 1008
5153

52-
versionName = "0.28.2"
54+
versionName = "0.28.3"
5355
System.getProperty("versionNameSuffix")?.let { versionNameSuffix = it }
5456

5557
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
@@ -83,7 +85,10 @@ android {
8385
}
8486
isMinifyEnabled = true
8587
isShrinkResources = false // disabled to fix F-Droid"s reproducible build
86-
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
88+
proguardFiles(
89+
getDefaultProguardFile("proguard-android-optimize.txt"),
90+
"proguard-rules.pro"
91+
)
8792
}
8893
}
8994

@@ -105,7 +110,7 @@ android {
105110

106111
sourceSets {
107112
getByName("androidTest") {
108-
assets.srcDir("$projectDir/schemas")
113+
assets.directories += "$projectDir/schemas"
109114
}
110115
}
111116

@@ -117,6 +122,7 @@ android {
117122
viewBinding = true
118123
compose = true
119124
buildConfig = true
125+
resValues = true
120126
}
121127

122128
packaging {

app/proguard-rules.pro

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,8 @@
5454
-keepclasseswithmembers class org.schabi.newpipe.** {
5555
kotlinx.serialization.KSerializer serializer(...);
5656
}
57+
58+
# Prevent R8 from stripping or renaming Protobuf internal fields
59+
-keepclassmembers class * extends com.google.protobuf.GeneratedMessageLite {
60+
<fields>;
61+
}

app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadManager.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ class FeedLoadManager(private val context: Context) {
111111
broadcastProgress()
112112
}
113113
.observeOn(Schedulers.io())
114-
.flatMap { Flowable.fromIterable(it) }
114+
// Randomize user subscription ordering to attempt to resist fingerprinting
115+
.flatMap { Flowable.fromIterable(it.shuffled()) }
115116
.takeWhile { !cancelSignal.get() }
116117
.doOnNext { subscriptionEntity ->
117118
// throttle YouTube extractions once every BATCH_SIZE to avoid being rate limited

app/src/main/java/org/schabi/newpipe/player/Player.java

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ public void handleIntent(@NonNull final Intent intent) {
480480
&& newQueue.size() == 1 && newQueue.getItem() != null
481481
&& playQueue != null && playQueue.size() == 1 && playQueue.getItem() != null
482482
&& newQueue.getItem().equals(playQueue.getItem())
483-
&& newQueue.getItem().getRecoveryPosition() != Long.MIN_VALUE) {
483+
&& newQueue.getItem().getRecoveryPosition() != PlayQueueItem.RECOVERY_UNSET) {
484484
// Player can have state = IDLE when playback is stopped or failed
485485
// and we should retry in this case
486486
if (simpleExoPlayer.getPlaybackState()
@@ -509,7 +509,7 @@ public void handleIntent(@NonNull final Intent intent) {
509509
&& (playQueue == null || !playQueue.equalStreamsAndIndex(newQueue))
510510
&& !newQueue.isEmpty()
511511
&& newQueue.getItem() != null
512-
&& newQueue.getItem().getRecoveryPosition() == Long.MIN_VALUE) {
512+
&& newQueue.getItem().getRecoveryPosition() == PlayQueueItem.RECOVERY_UNSET) {
513513
databaseUpdateDisposable.add(recordManager.loadStreamState(newQueue.getItem())
514514
.observeOn(AndroidSchedulers.mainThread())
515515
// Do not place initPlayback() in doFinally() because
@@ -562,11 +562,7 @@ private static PlayQueue getPlayQueueFromCache(@NonNull final Intent intent) {
562562
if (queueCache == null) {
563563
return null;
564564
}
565-
final PlayQueue newQueue = SerializedCache.getInstance().take(queueCache, PlayQueue.class);
566-
if (newQueue == null) {
567-
return null;
568-
}
569-
return newQueue;
565+
return SerializedCache.getInstance().take(queueCache, PlayQueue.class);
570566
}
571567

572568
private void initUIsForCurrentPlayerType() {
@@ -1704,7 +1700,7 @@ public void onPlaybackSynchronize(@NonNull final PlayQueueItem item, final boole
17041700
}
17051701

17061702
// sync the player index with the queue index, and seek to the correct position
1707-
if (item.getRecoveryPosition() != Long.MIN_VALUE) {
1703+
if (item.getRecoveryPosition() != PlayQueueItem.RECOVERY_UNSET) {
17081704
simpleExoPlayer.seekTo(playQueueIndex, item.getRecoveryPosition());
17091705
playQueue.unsetRecovery(playQueueIndex);
17101706
} else {
@@ -2033,7 +2029,7 @@ public MediaSource sourceOf(final PlayQueueItem item, final StreamInfo info) {
20332029
// resolver was called when the app was in background, the app will only stream audio when
20342030
// the user come back to the app and will never fetch the video stream.
20352031
// Note that the video is not fetched when the app is in background because the video
2036-
// renderer is fully disabled (see useVideoSource method), except for HLS streams
2032+
// renderer is fully disabled (see useVideoAndSubtitles method), except for HLS streams
20372033
// (see https://github.com/google/ExoPlayer/issues/9282).
20382034
return videoResolver.resolve(info);
20392035
}
@@ -2214,13 +2210,23 @@ public void useVideoAndSubtitles(final boolean videoAndSubtitlesEnabled) {
22142210

22152211
isAudioOnly = !videoAndSubtitlesEnabled;
22162212

2213+
final var item = playQueue.getItem();
2214+
final boolean hasPendingRecovery =
2215+
item != null && item.getRecoveryPosition() != PlayQueueItem.RECOVERY_UNSET;
2216+
final boolean hasTimeline =
2217+
!exoPlayerIsNull() && !simpleExoPlayer.getCurrentTimeline().isEmpty();
2218+
2219+
22172220
getCurrentStreamInfo().ifPresentOrElse(info -> {
22182221
// In case we don't know the source type, fall back to either video-with-audio, or
22192222
// audio-only source type
22202223
final SourceType sourceType = videoResolver.getStreamSourceType()
22212224
.orElse(SourceType.VIDEO_WITH_AUDIO_OR_AUDIO_ONLY);
22222225

2223-
setRecovery(); // making sure to save playback position before reloadPlayQueueManager()
2226+
if (hasTimeline || !hasPendingRecovery) {
2227+
// making sure to save playback position before reloadPlayQueueManager()
2228+
setRecovery();
2229+
}
22242230

22252231
if (playQueueManagerReloadingNeeded(sourceType, info, getVideoRendererIndex())) {
22262232
reloadPlayQueueManager();
@@ -2233,7 +2239,10 @@ The current metadata may be null sometimes (for e.g. when using an unstable conn
22332239
Reload the play queue manager in this case, which is the behavior when we don't know the
22342240
index of the video renderer or playQueueManagerReloadingNeeded returns true
22352241
*/
2236-
setRecovery(); // making sure to save playback position before reloadPlayQueueManager()
2242+
if (hasTimeline || !hasPendingRecovery) {
2243+
// making sure to save playback position before reloadPlayQueueManager()
2244+
setRecovery();
2245+
}
22372246
reloadPlayQueueManager();
22382247
});
22392248

app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import org.schabi.newpipe.player.playqueue.PlayQueueEvent.RecoveryEvent
1515
import org.schabi.newpipe.player.playqueue.PlayQueueEvent.RemoveEvent
1616
import org.schabi.newpipe.player.playqueue.PlayQueueEvent.ReorderEvent
1717
import org.schabi.newpipe.player.playqueue.PlayQueueEvent.SelectEvent
18+
import org.schabi.newpipe.player.playqueue.PlayQueueItem
1819

1920
/**
2021
* PlayQueue is responsible for keeping track of a list of streams and the index of
@@ -390,7 +391,7 @@ abstract class PlayQueue internal constructor(
390391
*/
391392
@Synchronized
392393
fun unsetRecovery(index: Int) {
393-
setRecovery(index, Long.Companion.MIN_VALUE)
394+
setRecovery(index, PlayQueueItem.RECOVERY_UNSET)
394395
}
395396

396397
/**

app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItem.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class PlayQueueItem private constructor(
2828
var isAutoQueued: Boolean = false
2929

3030
// package-private
31-
var recoveryPosition = Long.Companion.MIN_VALUE
31+
var recoveryPosition = RECOVERY_UNSET
3232
var error: Throwable? = null
3333
private set
3434

@@ -68,4 +68,8 @@ class PlayQueueItem private constructor(
6868
override fun equals(o: Any?) = o is PlayQueueItem && serviceId == o.serviceId && url == o.url
6969

7070
override fun hashCode() = Objects.hash(url, serviceId)
71+
72+
companion object {
73+
const val RECOVERY_UNSET = Long.MIN_VALUE
74+
}
7175
}

app/src/main/res/values-az/strings.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@
397397
<string name="error_http_unsupported_range">Server çox iş parçalı endirmələri qəbul etmir, @string/msg_threads = 1 ilə yenidən cəhd edin</string>
398398
<string name="delete_downloaded_files_confirm">Bütün endirilmiş fayllar diskdən silinsin\?</string>
399399
<string name="max_retry_msg">Maksimum təkrar cəhdlər</string>
400-
<string name="remove_watched_popup_warning">Pleylistə əlavə olunandan əvvəl və sonrakı baxılmış videolar silinəcək. \nSiz əminsiniz? Bu geri qaytarıla bilməz!</string>
400+
<string name="remove_watched_popup_warning">Pleylistə əlavə olunandan əvvəl və sonrakı baxılan yayımlar silinəcək. \nSiz əminsiniz?</string>
401401
<string name="feed_groups_header_title">Kanal qrupları</string>
402402
<string name="feed_new_items">Yeni axın elementləri</string>
403403
<string name="feed_update_threshold_summary">Abunəlik köhnəlmiş hesab edilənə qədərki son yeniləmədən sonrakı vaxt — %s</string>
@@ -526,7 +526,7 @@
526526
</plurals>
527527
<string name="progressive_load_interval_exoplayer_default">ExoPlayer standartı</string>
528528
<string name="feed_use_dedicated_fetch_method_title">Mövcud olduqda xüsusi axından al</string>
529-
<string name="remove_watched_popup_title">Baxılmış videolar silinsin?</string>
529+
<string name="remove_watched_popup_title">Baxılan yayımlar silinsin?</string>
530530
<string name="remove_watched">İzləniləni sil</string>
531531
<string name="downloads_storage_use_saf_title">Sistem qovluğu seçicisini (SAF) istifadə et</string>
532532
<string name="error_timeout">Bağlantı fasiləsi</string>

app/src/main/res/values-bg/strings.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@
464464
\nЕвентуално може да бъде поддържано в бъдещи версии.</string>
465465
<string name="processing_may_take_a_moment">Обработка… Ще отнеме момент</string>
466466
<string name="new_seek_duration_toast">Поради ограничения в ExoPlayer, стъпката за превъртане е зададена на %d секунди</string>
467-
<string name="remove_watched_popup_warning">Видата, които са били изгледани преди и след добавянето към плейлиста ще бъдат премахнати. \nСигурни ли сте? Това не може да бъде отменено!</string>
467+
<string name="remove_watched_popup_warning">Потоците, които са били гледани преди и след добавянето им към плейлиста, ще бъдат премахнати. \nСигурни ли сте?</string>
468468
<string name="downloads_storage_use_saf_summary">„Storage Access Framework“ позволява изтегляния във външна SD-карта</string>
469469
<string name="start_downloads">Започни изтеглянията</string>
470470
<string name="close">Затвори</string>
@@ -500,7 +500,7 @@
500500
<string name="channel_created_by">Създаден от %s</string>
501501
<string name="paid_content">Съдържанието е достъпно само за хора, които са си платили, затова не може да бъде гледано или изтеглено с NewPipe.</string>
502502
<string name="youtube_music_premium_content">Това видео е достъпно за абонати на YouTube Music Premium, затова не може да бъде гледано или изтеглено с NewPipe.</string>
503-
<string name="remove_watched_popup_title">Премахни изгледаните видеа?</string>
503+
<string name="remove_watched_popup_title">Премахни изгледаните потоци?</string>
504504
<string name="remove_watched_popup_partially_watched_streams">Да, както и само частично изгледаните видеа</string>
505505
<string name="subscribers_count_not_available">Брой на абонати не е наличен</string>
506506
<string name="peertube_instance_add_exists">Инстанцията вече съществува</string>

0 commit comments

Comments
 (0)