Skip to content

Commit 6fa97e1

Browse files
committed
subscription: Port subscription import-export to workers from refactor
Please see TeamNewPipe#11759 for the original change Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
1 parent 0d65733 commit 6fa97e1

20 files changed

Lines changed: 570 additions & 1017 deletions

app/build.gradle.kts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ plugins {
1111
alias(libs.plugins.jetbrains.kotlin.kapt)
1212
alias(libs.plugins.google.ksp)
1313
alias(libs.plugins.jetbrains.kotlin.parcelize)
14+
alias(libs.plugins.jetbrains.kotlinx.serialization)
1415
alias(libs.plugins.sonarqube)
1516
checkstyle
1617
}
@@ -246,6 +247,12 @@ dependencies {
246247
implementation(libs.google.android.material)
247248
implementation(libs.androidx.webkit)
248249

250+
// Coroutines interop
251+
implementation(libs.kotlinx.coroutines.rx3)
252+
253+
// Kotlinx Serialization
254+
implementation(libs.kotlinx.serialization.json)
255+
249256
/** Third-party libraries **/
250257
implementation(libs.livefront.bridge)
251258
implementation(libs.evernote.statesaver.core)

app/proguard-rules.pro

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,18 @@
4444
-keepclassmembers class * extends com.google.protobuf.GeneratedMessageLite {
4545
<fields>;
4646
}
47+
48+
## Keep Kotlinx Serialization classes
49+
-keepclassmembers class kotlinx.serialization.json.** {
50+
*** Companion;
51+
}
52+
-keepclasseswithmembers class kotlinx.serialization.json.** {
53+
kotlinx.serialization.KSerializer serializer(...);
54+
}
55+
-keep,includedescriptorclasses class org.schabi.newpipe.**$$serializer { *; }
56+
-keepclassmembers class org.schabi.newpipe.** {
57+
*** Companion;
58+
}
59+
-keepclasseswithmembers class org.schabi.newpipe.** {
60+
kotlinx.serialization.KSerializer serializer(...);
61+
}

app/src/main/AndroidManifest.xml

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,6 @@
9696
android:exported="false"
9797
android:label="@string/title_activity_about" />
9898

99-
<service
100-
android:name=".local.subscription.services.SubscriptionsImportService"
101-
android:foregroundServiceType="dataSync" />
102-
103-
<service
104-
android:name=".local.subscription.services.SubscriptionsExportService"
105-
android:foregroundServiceType="dataSync" />
106-
10799
<service
108100
android:name=".local.feed.service.FeedLoadService"
109101
android:foregroundServiceType="dataSync" />

app/src/main/java/org/schabi/newpipe/local/subscription/ImportConfirmationDialog.java

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,63 @@
11
package org.schabi.newpipe.local.subscription;
22

33
import android.app.Dialog;
4-
import android.content.Intent;
54
import android.os.Bundle;
65

76
import androidx.annotation.NonNull;
87
import androidx.annotation.Nullable;
98
import androidx.appcompat.app.AlertDialog;
9+
import androidx.core.os.BundleCompat;
1010
import androidx.fragment.app.DialogFragment;
1111
import androidx.fragment.app.Fragment;
12+
import androidx.work.Constraints;
13+
import androidx.work.ExistingWorkPolicy;
14+
import androidx.work.NetworkType;
15+
import androidx.work.OneTimeWorkRequest;
16+
import androidx.work.OutOfQuotaPolicy;
17+
import androidx.work.WorkManager;
1218

1319
import com.livefront.bridge.Bridge;
1420

1521
import org.schabi.newpipe.R;
22+
import org.schabi.newpipe.local.subscription.workers.SubscriptionImportInput;
23+
import org.schabi.newpipe.local.subscription.workers.SubscriptionImportWorker;
1624

1725
public class ImportConfirmationDialog extends DialogFragment {
18-
protected Intent resultServiceIntent;
19-
private static final String EXTRA_RESULT_SERVICE_INTENT = "extra_result_service_intent";
20-
21-
public static void show(@NonNull final Fragment fragment,
22-
@NonNull final Intent resultServiceIntent) {
23-
final ImportConfirmationDialog confirmationDialog = new ImportConfirmationDialog();
24-
final Bundle args = new Bundle();
25-
args.putParcelable(EXTRA_RESULT_SERVICE_INTENT, resultServiceIntent);
26-
confirmationDialog.setArguments(args);
26+
private static final String INPUT = "input";
27+
28+
public static void show(@NonNull final Fragment fragment, final SubscriptionImportInput input) {
29+
final var confirmationDialog = new ImportConfirmationDialog();
30+
final var arguments = new Bundle();
31+
arguments.putParcelable(INPUT, input);
32+
confirmationDialog.setArguments(arguments);
2733
confirmationDialog.show(fragment.getParentFragmentManager(), null);
2834
}
2935

3036
@NonNull
3137
@Override
3238
public Dialog onCreateDialog(@Nullable final Bundle savedInstanceState) {
33-
return new AlertDialog.Builder(requireContext())
39+
final var context = requireContext();
40+
return new AlertDialog.Builder(context)
3441
.setMessage(R.string.import_network_expensive_warning)
3542
.setCancelable(true)
3643
.setNegativeButton(R.string.cancel, null)
3744
.setPositiveButton(R.string.ok, (dialogInterface, i) -> {
38-
requireContext().startService(resultServiceIntent);
45+
final var constraints = new Constraints.Builder()
46+
.setRequiredNetworkType(NetworkType.CONNECTED)
47+
.build();
48+
final var input = BundleCompat.getParcelable(requireArguments(), INPUT,
49+
SubscriptionImportInput.class);
50+
51+
final var req = new OneTimeWorkRequest.Builder(SubscriptionImportWorker.class)
52+
.setInputData(input.toData())
53+
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
54+
.setConstraints(constraints)
55+
.build();
56+
57+
WorkManager.getInstance(context)
58+
.enqueueUniqueWork(SubscriptionImportWorker.WORK_NAME,
59+
ExistingWorkPolicy.APPEND_OR_REPLACE, req);
60+
3961
dismiss();
4062
})
4163
.create();
@@ -45,7 +67,7 @@ public Dialog onCreateDialog(@Nullable final Bundle savedInstanceState) {
4567
public void onCreate(@Nullable final Bundle savedInstanceState) {
4668
super.onCreate(savedInstanceState);
4769

48-
resultServiceIntent = requireArguments().getParcelable(EXTRA_RESULT_SERVICE_INTENT);
70+
Bridge.restoreInstanceState(this, savedInstanceState);
4971
}
5072

5173
@Override

app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package org.schabi.newpipe.local.subscription
33
import android.app.Activity
44
import android.content.Context
55
import android.content.DialogInterface
6-
import android.content.Intent
76
import android.os.Bundle
87
import android.os.Parcelable
98
import android.view.LayoutInflater
@@ -53,11 +52,8 @@ import org.schabi.newpipe.local.subscription.item.FeedGroupCarouselItem
5352
import org.schabi.newpipe.local.subscription.item.GroupsHeader
5453
import org.schabi.newpipe.local.subscription.item.Header
5554
import org.schabi.newpipe.local.subscription.item.ImportSubscriptionsHintPlaceholderItem
56-
import org.schabi.newpipe.local.subscription.services.SubscriptionsExportService
57-
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService
58-
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.KEY_MODE
59-
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.KEY_VALUE
60-
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.PREVIOUS_EXPORT_MODE
55+
import org.schabi.newpipe.local.subscription.workers.SubscriptionExportWorker
56+
import org.schabi.newpipe.local.subscription.workers.SubscriptionImportInput
6157
import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard
6258
import org.schabi.newpipe.streams.io.StoredFileHelper
6359
import org.schabi.newpipe.util.NavigationHelper
@@ -223,21 +219,18 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
223219
}
224220

225221
private fun requestExportResult(result: ActivityResult) {
226-
if (result.data != null && result.resultCode == Activity.RESULT_OK) {
227-
activity.startService(
228-
Intent(activity, SubscriptionsExportService::class.java)
229-
.putExtra(SubscriptionsExportService.KEY_FILE_PATH, result.data?.data)
230-
)
222+
val data = result.data?.data
223+
if (data != null && result.resultCode == Activity.RESULT_OK) {
224+
SubscriptionExportWorker.schedule(activity, data)
231225
}
232226
}
233227

234228
private fun requestImportResult(result: ActivityResult) {
235-
if (result.data != null && result.resultCode == Activity.RESULT_OK) {
229+
val data = result.data?.dataString
230+
if (data != null && result.resultCode == Activity.RESULT_OK) {
236231
ImportConfirmationDialog.show(
237232
this,
238-
Intent(activity, SubscriptionsImportService::class.java)
239-
.putExtra(KEY_MODE, PREVIOUS_EXPORT_MODE)
240-
.putExtra(KEY_VALUE, result.data?.data)
233+
SubscriptionImportInput.PreviousExportMode(data)
241234
)
242235
}
243236
}

app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package org.schabi.newpipe.local.subscription
22

33
import android.content.Context
4-
import android.util.Pair
54
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
65
import io.reactivex.rxjava3.core.Completable
76
import io.reactivex.rxjava3.core.Flowable
@@ -51,23 +50,16 @@ class SubscriptionManager(context: Context) {
5150
}
5251
}
5352

54-
fun upsertAll(infoList: List<Pair<ChannelInfo, List<ChannelTabInfo>>>): List<SubscriptionEntity> {
55-
val listEntities = subscriptionTable.upsertAll(
56-
infoList.map { SubscriptionEntity.from(it.first) }
57-
)
53+
fun upsertAll(infoList: List<Pair<ChannelInfo, ChannelTabInfo>>) {
54+
val listEntities = infoList.map { SubscriptionEntity.from(it.first) }
55+
subscriptionTable.upsertAll(listEntities)
5856

5957
database.runInTransaction {
6058
infoList.forEachIndexed { index, info ->
61-
info.second.forEach {
62-
feedDatabaseManager.upsertAll(
63-
listEntities[index].uid,
64-
it.relatedItems.filterIsInstance<StreamInfoItem>()
65-
)
66-
}
59+
val streams = info.second.relatedItems.filterIsInstance<StreamInfoItem>()
60+
feedDatabaseManager.upsertAll(listEntities[index].uid, streams)
6761
}
6862
}
69-
70-
return listEntities
7163
}
7264

7365
fun updateChannelInfo(info: ChannelInfo): Completable = subscriptionTable.getSubscription(info.serviceId, info.url)

app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionsImportFragment.java

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
package org.schabi.newpipe.local.subscription;
22

33
import static org.schabi.newpipe.extractor.subscription.SubscriptionExtractor.ContentSource.CHANNEL_URL;
4-
import static org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.CHANNEL_URL_MODE;
5-
import static org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.INPUT_STREAM_MODE;
6-
import static org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.KEY_MODE;
7-
import static org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.KEY_VALUE;
84

95
import android.app.Activity;
106
import android.content.Intent;
@@ -37,7 +33,7 @@
3733
import org.schabi.newpipe.extractor.NewPipe;
3834
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
3935
import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor;
40-
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService;
36+
import org.schabi.newpipe.local.subscription.workers.SubscriptionImportInput;
4137
import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard;
4238
import org.schabi.newpipe.streams.io.StoredFileHelper;
4339
import org.schabi.newpipe.util.Constants;
@@ -168,10 +164,8 @@ private void onImportClicked() {
168164
}
169165

170166
public void onImportUrl(final String value) {
171-
ImportConfirmationDialog.show(this, new Intent(activity, SubscriptionsImportService.class)
172-
.putExtra(KEY_MODE, CHANNEL_URL_MODE)
173-
.putExtra(KEY_VALUE, value)
174-
.putExtra(Constants.KEY_SERVICE_ID, currentServiceId));
167+
ImportConfirmationDialog.show(this,
168+
new SubscriptionImportInput.ChannelUrlMode(currentServiceId, value));
175169
}
176170

177171
public void onImportFile() {
@@ -186,16 +180,10 @@ public void onImportFile() {
186180
}
187181

188182
private void requestImportFileResult(final ActivityResult result) {
189-
if (result.getData() == null) {
190-
return;
191-
}
192-
193-
if (result.getResultCode() == Activity.RESULT_OK && result.getData().getData() != null) {
183+
final String data = result.getData() != null ? result.getData().getDataString() : null;
184+
if (result.getResultCode() == Activity.RESULT_OK && data != null) {
194185
ImportConfirmationDialog.show(this,
195-
new Intent(activity, SubscriptionsImportService.class)
196-
.putExtra(KEY_MODE, INPUT_STREAM_MODE)
197-
.putExtra(KEY_VALUE, result.getData().getData())
198-
.putExtra(Constants.KEY_SERVICE_ID, currentServiceId));
186+
new SubscriptionImportInput.InputStreamMode(currentServiceId, data));
199187
}
200188
}
201189

0 commit comments

Comments
 (0)