Merge pull request #3509 from wb9688/upgrade-dependencies

Upgrade some dependencies
This commit is contained in:
Tobias Groza 2020-05-28 22:07:04 +02:00 committed by GitHub
commit 9d25c0bf8a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 208 additions and 316 deletions

View file

@ -5,13 +5,13 @@ android:
components: components:
# The BuildTools version used by NewPipe # The BuildTools version used by NewPipe
- tools - tools
- build-tools-28.0.3 - build-tools-29.0.3
# The SDK version used to compile NewPipe # The SDK version used to compile NewPipe
- android-28 - android-29
before_install: before_install:
- yes | sdkmanager "platforms;android-28" - yes | sdkmanager "platforms;android-29"
script: ./gradlew -Dorg.gradle.jvmargs=-Xmx1536m assembleDebug lintDebug testDebugUnitTest script: ./gradlew -Dorg.gradle.jvmargs=-Xmx1536m assembleDebug lintDebug testDebugUnitTest
licenses: licenses:

View file

@ -5,14 +5,14 @@ apply plugin: 'kotlin-kapt'
apply plugin: 'checkstyle' apply plugin: 'checkstyle'
android { android {
compileSdkVersion 28 compileSdkVersion 29
buildToolsVersion '28.0.3' buildToolsVersion '29.0.3'
defaultConfig { defaultConfig {
applicationId "org.schabi.newpipe" applicationId "org.schabi.newpipe"
resValue "string", "app_name", "NewPipe" resValue "string", "app_name", "NewPipe"
minSdkVersion 19 minSdkVersion 19
targetSdkVersion 28 targetSdkVersion 29
versionCode 930 versionCode 930
versionName "0.19.3" versionName "0.19.3"
@ -80,22 +80,22 @@ android {
} }
ext { ext {
androidxLibVersion = '1.1.0' icepickVersion = '3.2.0'
exoPlayerLibVersion = '2.11.4' checkstyleVersion = '8.32'
roomDbLibVersion = '2.1.0' stethoVersion = '1.5.1'
leakCanaryLibVersion = '1.5.4' //1.6.1 leakCanaryVersion = '2.2'
okHttpLibVersion = '3.12.6' exoPlayerVersion = '2.11.4'
icepickLibVersion = '3.2.0' androidxLifecycleVersion = '2.2.0'
stethoLibVersion = '1.5.0' androidxRoomVersion = '2.2.5'
markwonVersion = '4.2.1' groupieVersion = '2.8.0'
checkstyleVersion = '8.31' markwonVersion = '4.3.1'
} }
checkstyle { checkstyle {
configFile rootProject.file('checkstyle.xml') configFile rootProject.file('checkstyle.xml')
ignoreFailures false ignoreFailures false
showViolations true showViolations true
toolVersion = "${checkstyleVersion}" toolVersion = checkstyleVersion
} }
task runCheckstyle(type: Checkstyle) { task runCheckstyle(type: Checkstyle) {
@ -140,70 +140,73 @@ afterEvaluate {
dependencies { dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "frankiesardo:icepick:${icepickVersion}"
kapt "frankiesardo:icepick-processor:${icepickVersion}"
debugImplementation "com.puppycrawl.tools:checkstyle:${checkstyleVersion}" debugImplementation "com.puppycrawl.tools:checkstyle:${checkstyleVersion}"
ktlint "com.pinterest:ktlint:0.35.0" ktlint "com.pinterest:ktlint:0.35.0"
androidTestImplementation 'androidx.test.ext:junit:1.1.1' debugImplementation "com.facebook.stetho:stetho:${stethoVersion}"
androidTestImplementation "android.arch.persistence.room:testing:1.1.1" debugImplementation "com.facebook.stetho:stetho-okhttp3:${stethoVersion}"
androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', {
debugImplementation "com.squareup.leakcanary:leakcanary-android:${leakCanaryVersion}"
implementation "com.squareup.leakcanary:leakcanary-object-watcher-android:${leakCanaryVersion}"
debugImplementation "androidx.multidex:multidex:2.0.1"
testImplementation 'junit:junit:4.13'
testImplementation 'org.mockito:mockito-core:3.3.3'
androidTestImplementation "androidx.test.ext:junit:1.1.1"
androidTestImplementation "androidx.room:room-testing:${androidxRoomVersion}"
androidTestImplementation "androidx.test.espresso:espresso-core:3.2.0", {
exclude module: 'support-annotations' exclude module: 'support-annotations'
}) }
implementation 'com.github.TeamNewPipe:NewPipeExtractor:f3913e241e379adf0091319091e8f895c5fcfd07' implementation 'com.github.TeamNewPipe:NewPipeExtractor:0b4977bb0c7c9928cd8904951cfe94c71b4e81de'
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:2.23.0'
implementation "androidx.appcompat:appcompat:${androidxLibVersion}" implementation "com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751"
implementation "com.google.android.material:material:${androidxLibVersion}" implementation "org.jsoup:jsoup:1.13.1"
implementation "androidx.recyclerview:recyclerview:${androidxLibVersion}"
implementation "androidx.preference:preference:${androidxLibVersion}" implementation "com.squareup.okhttp3:okhttp:3.12.11"
implementation "com.google.android.exoplayer:exoplayer:${exoPlayerVersion}"
implementation "com.google.android.exoplayer:extension-mediasession:${exoPlayerVersion}"
implementation "com.google.android.material:material:1.1.0"
implementation "androidx.appcompat:appcompat:1.1.0"
implementation "androidx.preference:preference:1.1.1"
implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation "androidx.cardview:cardview:1.0.0" implementation "androidx.cardview:cardview:1.0.0"
implementation "androidx.constraintlayout:constraintlayout:1.1.3" implementation "androidx.constraintlayout:constraintlayout:1.1.3"
implementation 'com.xwray:groupie:2.7.0' implementation "androidx.lifecycle:lifecycle-livedata:${androidxLifecycleVersion}"
implementation 'com.xwray:groupie-kotlin-android-extensions:2.7.0' implementation "androidx.lifecycle:lifecycle-viewmodel:${androidxLifecycleVersion}"
implementation "androidx.lifecycle:lifecycle-extensions:${androidxLifecycleVersion}"
implementation 'androidx.lifecycle:lifecycle-livedata:2.0.0' implementation "androidx.room:room-runtime:${androidxRoomVersion}"
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.0.0' implementation "androidx.room:room-rxjava2:${androidxRoomVersion}"
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0' kapt "androidx.room:room-compiler:${androidxRoomVersion}"
// Originally in NewPipeExtractor implementation "com.xwray:groupie:${groupieVersion}"
implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' implementation "com.xwray:groupie-kotlin-android-extensions:${groupieVersion}"
implementation 'org.jsoup:jsoup:1.9.2'
implementation 'ch.acra:acra:4.9.2' //4.11 implementation "de.hdodenhof:circleimageview:3.1.0"
implementation "com.nostra13.universalimageloader:universal-image-loader:1.9.5"
implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
implementation 'de.hdodenhof:circleimageview:2.2.0'
implementation 'com.nononsenseapps:filepicker:4.2.1'
implementation "com.google.android.exoplayer:exoplayer:${exoPlayerLibVersion}"
implementation "com.google.android.exoplayer:extension-mediasession:${exoPlayerLibVersion}"
debugImplementation "com.facebook.stetho:stetho:${stethoLibVersion}"
debugImplementation "com.facebook.stetho:stetho-urlconnection:${stethoLibVersion}"
debugImplementation 'androidx.multidex:multidex:2.0.1'
implementation 'io.reactivex.rxjava2:rxjava:2.2.2'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'
implementation 'org.ocpsoft.prettytime:prettytime:4.0.3.Final'
implementation "androidx.room:room-runtime:${roomDbLibVersion}"
implementation "androidx.room:room-rxjava2:${roomDbLibVersion}"
kapt "androidx.room:room-compiler:${roomDbLibVersion}"
implementation "frankiesardo:icepick:${icepickLibVersion}"
kapt "frankiesardo:icepick-processor:${icepickLibVersion}"
debugImplementation "com.squareup.leakcanary:leakcanary-android:${leakCanaryLibVersion}"
releaseImplementation "com.squareup.leakcanary:leakcanary-android-no-op:${leakCanaryLibVersion}"
implementation "com.squareup.okhttp3:okhttp:${okHttpLibVersion}"
debugImplementation "com.facebook.stetho:stetho-okhttp3:${stethoLibVersion}"
implementation "io.noties.markwon:core:${markwonVersion}" implementation "io.noties.markwon:core:${markwonVersion}"
implementation "io.noties.markwon:linkify:${markwonVersion}" implementation "io.noties.markwon:linkify:${markwonVersion}"
implementation "com.nononsenseapps:filepicker:4.2.1"
implementation "ch.acra:acra-core:5.5.0"
implementation "io.reactivex.rxjava2:rxjava:2.2.19"
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
implementation "com.jakewharton.rxbinding2:rxbinding:2.2.0"
implementation "org.ocpsoft.prettytime:prettytime:4.0.5.Final"
} }
static String getGitWorkingBranch() { static String getGitWorkingBranch() {

View file

@ -1,107 +0,0 @@
package org.schabi.newpipe;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import androidx.annotation.NonNull;
import androidx.multidex.MultiDex;
import com.facebook.stetho.Stetho;
import com.facebook.stetho.okhttp3.StethoInterceptor;
import com.squareup.leakcanary.AndroidHeapDumper;
import com.squareup.leakcanary.DefaultLeakDirectoryProvider;
import com.squareup.leakcanary.HeapDumper;
import com.squareup.leakcanary.LeakCanary;
import com.squareup.leakcanary.LeakDirectoryProvider;
import com.squareup.leakcanary.RefWatcher;
import org.schabi.newpipe.extractor.downloader.Downloader;
import java.io.File;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
public class DebugApp extends App {
private static final String TAG = DebugApp.class.toString();
@Override
protected void attachBaseContext(final Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
@Override
public void onCreate() {
super.onCreate();
initStetho();
}
@Override
protected Downloader getDownloader() {
DownloaderImpl downloader = DownloaderImpl.init(new OkHttpClient.Builder()
.addNetworkInterceptor(new StethoInterceptor()));
setCookiesToDownloader(downloader);
return downloader;
}
private void initStetho() {
// Create an InitializerBuilder
Stetho.InitializerBuilder initializerBuilder =
Stetho.newInitializerBuilder(this);
// Enable Chrome DevTools
initializerBuilder.enableWebKitInspector(
Stetho.defaultInspectorModulesProvider(this)
);
// Enable command line interface
initializerBuilder.enableDumpapp(
Stetho.defaultDumperPluginsProvider(getApplicationContext())
);
// Use the InitializerBuilder to generate an Initializer
Stetho.Initializer initializer = initializerBuilder.build();
// Initialize Stetho with the Initializer
Stetho.initialize(initializer);
}
@Override
protected boolean isDisposedRxExceptionsReported() {
return PreferenceManager.getDefaultSharedPreferences(this)
.getBoolean(getString(R.string.allow_disposed_exceptions_key), false);
}
@Override
protected RefWatcher installLeakCanary() {
return LeakCanary.refWatcher(this)
.heapDumper(new ToggleableHeapDumper(this))
// give each object 10 seconds to be gc'ed, before leak canary gets nosy on it
.watchDelay(10, TimeUnit.SECONDS)
.buildAndInstall();
}
public static class ToggleableHeapDumper implements HeapDumper {
private final HeapDumper dumper;
private final SharedPreferences preferences;
private final String dumpingAllowanceKey;
ToggleableHeapDumper(@NonNull final Context context) {
LeakDirectoryProvider leakDirectoryProvider = new DefaultLeakDirectoryProvider(context);
this.dumper = new AndroidHeapDumper(context, leakDirectoryProvider);
this.preferences = PreferenceManager.getDefaultSharedPreferences(context);
this.dumpingAllowanceKey = context.getString(R.string.allow_heap_dumping_key);
}
private boolean isDumpingAllowed() {
return preferences.getBoolean(dumpingAllowanceKey, false);
}
@Override
public File dumpHeap() {
return isDumpingAllowed() ? dumper.dumpHeap() : HeapDumper.RETRY_LATER;
}
}
}

View file

@ -0,0 +1,59 @@
package org.schabi.newpipe
import android.content.Context
import androidx.multidex.MultiDex
import androidx.preference.PreferenceManager
import com.facebook.stetho.Stetho
import com.facebook.stetho.okhttp3.StethoInterceptor
import leakcanary.AppWatcher
import leakcanary.LeakCanary
import okhttp3.OkHttpClient
import org.schabi.newpipe.extractor.downloader.Downloader
class DebugApp : App() {
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base)
MultiDex.install(this)
}
override fun onCreate() {
super.onCreate()
initStetho()
// Give each object 10 seconds to be GC'ed, before LeakCanary gets nosy on it
AppWatcher.config = AppWatcher.config.copy(watchDurationMillis = 10000)
LeakCanary.config = LeakCanary.config.copy(dumpHeap = PreferenceManager
.getDefaultSharedPreferences(this).getBoolean(getString(
R.string.allow_heap_dumping_key), false))
}
override fun getDownloader(): Downloader {
val downloader = DownloaderImpl.init(OkHttpClient.Builder()
.addNetworkInterceptor(StethoInterceptor()))
setCookiesToDownloader(downloader)
return downloader
}
private fun initStetho() {
// Create an InitializerBuilder
val initializerBuilder = Stetho.newInitializerBuilder(this)
// Enable Chrome DevTools
initializerBuilder.enableWebKitInspector(Stetho.defaultInspectorModulesProvider(this))
// Enable command line interface
initializerBuilder.enableDumpapp(
Stetho.defaultDumperPluginsProvider(applicationContext))
// Use the InitializerBuilder to generate an Initializer
val initializer = initializerBuilder.build()
// Initialize Stetho with the Initializer
Stetho.initialize(initializer)
}
override fun isDisposedRxExceptionsReported(): Boolean {
return PreferenceManager.getDefaultSharedPreferences(this)
.getBoolean(getString(R.string.allow_disposed_exceptions_key), false)
}
}

View file

@ -9,19 +9,16 @@ import android.content.SharedPreferences;
import android.os.Build; import android.os.Build;
import android.util.Log; import android.util.Log;
import androidx.annotation.Nullable;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import com.nostra13.universalimageloader.cache.memory.impl.LRULimitedMemoryCache; import com.nostra13.universalimageloader.cache.memory.impl.LRULimitedMemoryCache;
import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.squareup.leakcanary.LeakCanary;
import com.squareup.leakcanary.RefWatcher;
import org.acra.ACRA; import org.acra.ACRA;
import org.acra.config.ACRAConfiguration;
import org.acra.config.ACRAConfigurationException; import org.acra.config.ACRAConfigurationException;
import org.acra.config.ConfigurationBuilder; import org.acra.config.CoreConfiguration;
import org.acra.config.CoreConfigurationBuilder;
import org.acra.sender.ReportSenderFactory; import org.acra.sender.ReportSenderFactory;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.downloader.Downloader; import org.schabi.newpipe.extractor.downloader.Downloader;
@ -72,13 +69,6 @@ public class App extends Application {
private static final Class<? extends ReportSenderFactory>[] private static final Class<? extends ReportSenderFactory>[]
REPORT_SENDER_FACTORY_CLASSES = new Class[]{AcraReportSenderFactory.class}; REPORT_SENDER_FACTORY_CLASSES = new Class[]{AcraReportSenderFactory.class};
private static App app; private static App app;
private RefWatcher refWatcher;
@Nullable
public static RefWatcher getRefWatcher(final Context context) {
final App application = (App) context.getApplicationContext();
return application.refWatcher;
}
public static App getApp() { public static App getApp() {
return app; return app;
@ -95,13 +85,6 @@ public class App extends Application {
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
if (LeakCanary.isInAnalyzerProcess(this)) {
// This process is dedicated to LeakCanary for heap analysis.
// You should not init your app in this process.
return;
}
refWatcher = installLeakCanary();
app = this; app = this;
// Initialize settings first because others inits can use its values // Initialize settings first because others inits can use its values
@ -219,7 +202,7 @@ public class App extends Application {
private void initACRA() { private void initACRA() {
try { try {
final ACRAConfiguration acraConfig = new ConfigurationBuilder(this) final CoreConfiguration acraConfig = new CoreConfigurationBuilder(this)
.setReportSenderFactoryClasses(REPORT_SENDER_FACTORY_CLASSES) .setReportSenderFactoryClasses(REPORT_SENDER_FACTORY_CLASSES)
.setBuildConfigClass(BuildConfig.class) .setBuildConfigClass(BuildConfig.class)
.build(); .build();
@ -280,10 +263,6 @@ public class App extends Application {
appUpdateNotificationManager.createNotificationChannel(appUpdateChannel); appUpdateNotificationManager.createNotificationChannel(appUpdateChannel);
} }
protected RefWatcher installLeakCanary() {
return RefWatcher.DISABLED;
}
protected boolean isDisposedRxExceptionsReported() { protected boolean isDisposedRxExceptionsReported() {
return false; return false;
} }

View file

@ -11,10 +11,10 @@ import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoader;
import com.squareup.leakcanary.RefWatcher;
import icepick.Icepick; import icepick.Icepick;
import icepick.State; import icepick.State;
import leakcanary.AppWatcher;
public abstract class BaseFragment extends Fragment { public abstract class BaseFragment extends Fragment {
public static final ImageLoader IMAGE_LOADER = ImageLoader.getInstance(); public static final ImageLoader IMAGE_LOADER = ImageLoader.getInstance();
@ -78,16 +78,14 @@ public abstract class BaseFragment extends Fragment {
Icepick.saveInstanceState(this, outState); Icepick.saveInstanceState(this, outState);
} }
protected void onRestoreInstanceState(@NonNull final Bundle savedInstanceState) { } protected void onRestoreInstanceState(@NonNull final Bundle savedInstanceState) {
}
@Override @Override
public void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
RefWatcher refWatcher = App.getRefWatcher(getActivity()); AppWatcher.INSTANCE.getObjectWatcher().watch(this);
if (refWatcher != null) {
refWatcher.watch(this);
}
} }
@Override @Override
@ -100,9 +98,11 @@ public abstract class BaseFragment extends Fragment {
// Init // Init
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
protected void initViews(final View rootView, final Bundle savedInstanceState) { } protected void initViews(final View rootView, final Bundle savedInstanceState) {
}
protected void initListeners() { } protected void initListeners() {
}
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////
// Utils // Utils

View file

@ -2,8 +2,6 @@ package org.schabi.newpipe.about;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.view.ContextMenu; import android.view.ContextMenu;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -17,9 +15,9 @@ import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.util.ShareUtils;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator;
/** /**
* Fragment containing the software licenses. * Fragment containing the software licenses.
@ -27,7 +25,7 @@ import java.util.Comparator;
public class LicenseFragment extends Fragment { public class LicenseFragment extends Fragment {
private static final String ARG_COMPONENTS = "components"; private static final String ARG_COMPONENTS = "components";
private SoftwareComponent[] softwareComponents; private SoftwareComponent[] softwareComponents;
private SoftwareComponent mComponentForContextMenu; private SoftwareComponent componentForContextMenu;
public static LicenseFragment newInstance(final SoftwareComponent[] softwareComponents) { public static LicenseFragment newInstance(final SoftwareComponent[] softwareComponents) {
if (softwareComponents == null) { if (softwareComponents == null) {
@ -46,7 +44,7 @@ public class LicenseFragment extends Fragment {
* @param context the context to use * @param context the context to use
* @param license the license to show * @param license the license to show
*/ */
public static void showLicense(final Context context, final License license) { private static void showLicense(final Context context, final License license) {
new LicenseFragmentHelper((Activity) context).execute(license); new LicenseFragmentHelper((Activity) context).execute(license);
} }
@ -57,45 +55,34 @@ public class LicenseFragment extends Fragment {
.getParcelableArray(ARG_COMPONENTS); .getParcelableArray(ARG_COMPONENTS);
// Sort components by name // Sort components by name
Arrays.sort(softwareComponents, new Comparator<SoftwareComponent>() { Arrays.sort(softwareComponents, (o1, o2) -> o1.getName().compareTo(o2.getName()));
@Override
public int compare(final SoftwareComponent o1, final SoftwareComponent o2) {
return o1.getName().compareTo(o2.getName());
}
});
} }
@Nullable @Nullable
@Override @Override
public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container, public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container,
@Nullable final Bundle savedInstanceState) { @Nullable final Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_licenses, container, false); final View rootView = inflater.inflate(R.layout.fragment_licenses, container, false);
ViewGroup softwareComponentsView = rootView.findViewById(R.id.software_components); final ViewGroup softwareComponentsView = rootView.findViewById(R.id.software_components);
View licenseLink = rootView.findViewById(R.id.app_read_license); final View licenseLink = rootView.findViewById(R.id.app_read_license);
licenseLink.setOnClickListener(new OnReadFullLicenseClickListener()); licenseLink.setOnClickListener(v ->
showLicense(getActivity(), StandardLicenses.GPL3));
for (final SoftwareComponent component : softwareComponents) { for (final SoftwareComponent component : softwareComponents) {
View componentView = inflater final View componentView = inflater
.inflate(R.layout.item_software_component, container, false); .inflate(R.layout.item_software_component, container, false);
TextView softwareName = componentView.findViewById(R.id.name); final TextView softwareName = componentView.findViewById(R.id.name);
TextView copyright = componentView.findViewById(R.id.copyright); final TextView copyright = componentView.findViewById(R.id.copyright);
softwareName.setText(component.getName()); softwareName.setText(component.getName());
copyright.setText(getContext().getString(R.string.copyright, copyright.setText(getString(R.string.copyright,
component.getYears(), component.getYears(),
component.getCopyrightOwner(), component.getCopyrightOwner(),
component.getLicense().getAbbreviation())); component.getLicense().getAbbreviation()));
componentView.setTag(component); componentView.setTag(component);
componentView.setOnClickListener(new View.OnClickListener() { componentView.setOnClickListener(v ->
@Override showLicense(getActivity(), component.getLicense()));
public void onClick(final View v) {
Context context = v.getContext();
if (context != null) {
showLicense(context, component.getLicense());
}
}
});
softwareComponentsView.addView(componentView); softwareComponentsView.addView(componentView);
registerForContextMenu(componentView); registerForContextMenu(componentView);
} }
@ -105,40 +92,28 @@ public class LicenseFragment extends Fragment {
@Override @Override
public void onCreateContextMenu(final ContextMenu menu, final View v, public void onCreateContextMenu(final ContextMenu menu, final View v,
final ContextMenu.ContextMenuInfo menuInfo) { final ContextMenu.ContextMenuInfo menuInfo) {
MenuInflater inflater = getActivity().getMenuInflater(); final MenuInflater inflater = getActivity().getMenuInflater();
SoftwareComponent component = (SoftwareComponent) v.getTag(); final SoftwareComponent component = (SoftwareComponent) v.getTag();
menu.setHeaderTitle(component.getName()); menu.setHeaderTitle(component.getName());
inflater.inflate(R.menu.software_component, menu); inflater.inflate(R.menu.software_component, menu);
super.onCreateContextMenu(menu, v, menuInfo); super.onCreateContextMenu(menu, v, menuInfo);
mComponentForContextMenu = (SoftwareComponent) v.getTag(); componentForContextMenu = (SoftwareComponent) v.getTag();
} }
@Override @Override
public boolean onContextItemSelected(final MenuItem item) { public boolean onContextItemSelected(final MenuItem item) {
// item.getMenuInfo() is null so we use the tag of the view // item.getMenuInfo() is null so we use the tag of the view
final SoftwareComponent component = mComponentForContextMenu; final SoftwareComponent component = componentForContextMenu;
if (component == null) { if (component == null) {
return false; return false;
} }
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.action_website: case R.id.action_website:
openWebsite(component.getLink()); ShareUtils.openUrlInBrowser(getActivity(), component.getLink());
return true; return true;
case R.id.action_show_license: case R.id.action_show_license:
showLicense(getContext(), component.getLicense()); showLicense(getActivity(), component.getLicense());
} }
return false; return false;
} }
private void openWebsite(final String componentLink) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(componentLink));
startActivity(browserIntent);
}
private static class OnReadFullLicenseClickListener implements View.OnClickListener {
@Override
public void onClick(final View v) {
LicenseFragment.showLicense(v.getContext(), StandardLicenses.GPL3);
}
}
} }

View file

@ -3,8 +3,10 @@ package org.schabi.newpipe.about;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.util.Base64;
import android.webkit.WebView; import android.webkit.WebView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
@ -12,6 +14,7 @@ import org.schabi.newpipe.R;
import org.schabi.newpipe.util.ThemeHelper; import org.schabi.newpipe.util.ThemeHelper;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -26,28 +29,18 @@ public class LicenseFragmentHelper extends AsyncTask<Object, Void, Integer> {
weakReference = new WeakReference<>(activity); weakReference = new WeakReference<>(activity);
} }
private static String getFinishString(final Activity activity) {
return activity.getApplicationContext().getResources().getString(R.string.finish);
}
/** /**
* @param context the context to use * @param context the context to use
* @param license the license * @param license the license
* @return String which contains a HTML formatted license page * @return String which contains a HTML formatted license page
* styled according to the context's theme * styled according to the context's theme
*/ */
public static String getFormattedLicense(final Context context, final License license) { private static String getFormattedLicense(@NonNull final Context context,
if (context == null) { @NonNull final License license) {
throw new NullPointerException("context is null"); final StringBuilder licenseContent = new StringBuilder();
} final String webViewData;
if (license == null) {
throw new NullPointerException("license is null");
}
StringBuilder licenseContent = new StringBuilder();
String webViewData;
try { try {
BufferedReader in = new BufferedReader(new InputStreamReader( final BufferedReader in = new BufferedReader(new InputStreamReader(
context.getAssets().open(license.getFilename()), StandardCharsets.UTF_8)); context.getAssets().open(license.getFilename()), StandardCharsets.UTF_8));
String str; String str;
while ((str = in.readLine()) != null) { while ((str = in.readLine()) != null) {
@ -56,13 +49,11 @@ public class LicenseFragmentHelper extends AsyncTask<Object, Void, Integer> {
in.close(); in.close();
// split the HTML file and insert the stylesheet into the HEAD of the file // split the HTML file and insert the stylesheet into the HEAD of the file
String[] insert = licenseContent.toString().split("</head>"); webViewData = licenseContent.toString().replace("</head>",
webViewData = insert[0] + "<style type=\"text/css\">" "<style>" + getLicenseStylesheet(context) + "</style></head>");
+ getLicenseStylesheet(context) + "</style></head>" } catch (IOException e) {
+ insert[1]; throw new IllegalArgumentException(
} catch (Exception e) { "Could not get license file: " + license.getFilename(), e);
throw new NullPointerException("could not get license file:"
+ getLicenseStylesheet(context));
} }
return webViewData; return webViewData;
} }
@ -71,21 +62,19 @@ public class LicenseFragmentHelper extends AsyncTask<Object, Void, Integer> {
* @param context * @param context
* @return String which is a CSS stylesheet according to the context's theme * @return String which is a CSS stylesheet according to the context's theme
*/ */
public static String getLicenseStylesheet(final Context context) { private static String getLicenseStylesheet(final Context context) {
boolean isLightTheme = ThemeHelper.isLightThemeSelected(context); final boolean isLightTheme = ThemeHelper.isLightThemeSelected(context);
return "body{padding:12px 15px;margin:0;background:#" return "body{padding:12px 15px;margin:0;"
+ getHexRGBColor(context, isLightTheme + "background:#" + getHexRGBColor(context, isLightTheme
? R.color.light_license_background_color ? R.color.light_license_background_color
: R.color.dark_license_background_color) : R.color.dark_license_background_color) + ";"
+ ";color:#" + "color:#" + getHexRGBColor(context, isLightTheme
+ getHexRGBColor(context, isLightTheme
? R.color.light_license_text_color ? R.color.light_license_text_color
: R.color.dark_license_text_color) + ";}" : R.color.dark_license_text_color) + "}"
+ "a[href]{color:#" + "a[href]{color:#" + getHexRGBColor(context, isLightTheme
+ getHexRGBColor(context, isLightTheme
? R.color.light_youtube_primary_color ? R.color.light_youtube_primary_color
: R.color.dark_youtube_primary_color) + ";}" : R.color.dark_youtube_primary_color) + "}"
+ "pre{white-space: pre-wrap;}"; + "pre{white-space:pre-wrap}";
} }
/** /**
@ -95,13 +84,13 @@ public class LicenseFragmentHelper extends AsyncTask<Object, Void, Integer> {
* @param color the color number from R.color * @param color the color number from R.color
* @return a six characters long String with hexadecimal RGB values * @return a six characters long String with hexadecimal RGB values
*/ */
public static String getHexRGBColor(final Context context, final int color) { private static String getHexRGBColor(final Context context, final int color) {
return context.getResources().getString(color).substring(3); return context.getResources().getString(color).substring(3);
} }
@Nullable @Nullable
private Activity getActivity() { private Activity getActivity() {
Activity activity = weakReference.get(); final Activity activity = weakReference.get();
if (activity != null && activity.isFinishing()) { if (activity != null && activity.isFinishing()) {
return null; return null;
@ -118,22 +107,22 @@ public class LicenseFragmentHelper extends AsyncTask<Object, Void, Integer> {
@Override @Override
protected void onPostExecute(final Integer result) { protected void onPostExecute(final Integer result) {
Activity activity = getActivity(); final Activity activity = getActivity();
if (activity == null) { if (activity == null) {
return; return;
} }
String webViewData = getFormattedLicense(activity, license); final String webViewData = Base64.encodeToString(getFormattedLicense(activity, license)
AlertDialog.Builder alert = new AlertDialog.Builder(activity); .getBytes(StandardCharsets.UTF_8), Base64.NO_PADDING);
final WebView webView = new WebView(activity);
webView.loadData(webViewData, "text/html; charset=UTF-8", "base64");
final AlertDialog.Builder alert = new AlertDialog.Builder(activity);
alert.setTitle(license.getName()); alert.setTitle(license.getName());
alert.setView(webView);
WebView wv = new WebView(activity); assureCorrectAppLanguage(activity);
wv.loadData(webViewData, "text/html; charset=UTF-8", null); alert.setNegativeButton(activity.getString(R.string.finish),
(dialog, which) -> dialog.dismiss());
alert.setView(wv);
assureCorrectAppLanguage(activity.getApplicationContext());
alert.setNegativeButton(getFinishString(activity), (dialog, which) -> dialog.dismiss());
alert.show(); alert.show();
} }
} }

View file

@ -3,6 +3,7 @@ package org.schabi.newpipe.info_list.holder;
import android.content.ClipData; import android.content.ClipData;
import android.content.ClipboardManager; import android.content.ClipboardManager;
import android.content.Context; import android.content.Context;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod; import android.text.method.LinkMovementMethod;
import android.text.style.URLSpan; import android.text.style.URLSpan;
import android.text.util.Linkify; import android.text.util.Linkify;
@ -12,7 +13,6 @@ import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import org.jsoup.helper.StringUtil;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.comments.CommentsInfoItem; import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
@ -143,7 +143,7 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder {
} }
private void openCommentAuthor(final CommentsInfoItem item) { private void openCommentAuthor(final CommentsInfoItem item) {
if (StringUtil.isBlank(item.getUploaderUrl())) { if (TextUtils.isEmpty(item.getUploaderUrl())) {
return; return;
} }
try { try {

View file

@ -4,7 +4,7 @@ import android.content.Context;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import org.acra.collector.CrashReportData; import org.acra.data.CrashReportData;
import org.acra.sender.ReportSender; import org.acra.sender.ReportSender;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;

View file

@ -4,7 +4,7 @@ import android.content.Context;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import org.acra.config.ACRAConfiguration; import org.acra.config.CoreConfiguration;
import org.acra.sender.ReportSender; import org.acra.sender.ReportSender;
import org.acra.sender.ReportSenderFactory; import org.acra.sender.ReportSenderFactory;
@ -31,7 +31,7 @@ import org.acra.sender.ReportSenderFactory;
public class AcraReportSenderFactory implements ReportSenderFactory { public class AcraReportSenderFactory implements ReportSenderFactory {
@NonNull @NonNull
public ReportSender create(@NonNull final Context context, public ReportSender create(@NonNull final Context context,
@NonNull final ACRAConfiguration config) { @NonNull final CoreConfiguration config) {
return new AcraReportSender(); return new AcraReportSender();
} }
} }

View file

@ -32,7 +32,7 @@ import com.google.android.material.snackbar.Snackbar;
import com.grack.nanojson.JsonWriter; import com.grack.nanojson.JsonWriter;
import org.acra.ReportField; import org.acra.ReportField;
import org.acra.collector.CrashReportData; import org.acra.data.CrashReportData;
import org.schabi.newpipe.ActivityCommunicator; import org.schabi.newpipe.ActivityCommunicator;
import org.schabi.newpipe.BuildConfig; import org.schabi.newpipe.BuildConfig;
import org.schabi.newpipe.MainActivity; import org.schabi.newpipe.MainActivity;
@ -149,14 +149,7 @@ public class ErrorActivity extends AppCompatActivity {
public static void reportError(final Context context, final CrashReportData report, public static void reportError(final Context context, final CrashReportData report,
final ErrorInfo errorInfo) { final ErrorInfo errorInfo) {
// get key first (don't ask about this solution) String[] el = new String[]{report.getString(ReportField.STACK_TRACE)};
ReportField key = null;
for (ReportField k : report.keySet()) {
if (k.toString().equals("STACK_TRACE")) {
key = k;
}
}
String[] el = new String[]{report.get(key).toString()};
Intent intent = new Intent(context, ErrorActivity.class); Intent intent = new Intent(context, ErrorActivity.class);
intent.putExtra(ERROR_INFO, errorInfo); intent.putExtra(ERROR_INFO, errorInfo);

View file

@ -1,6 +1,6 @@
package org.schabi.newpipe.util; package org.schabi.newpipe.util;
import org.jsoup.helper.StringUtil; import android.text.TextUtils;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@ -16,7 +16,7 @@ public final class CookieUtils {
for (String cookies : cookieStrings) { for (String cookies : cookieStrings) {
cookieSet.addAll(splitCookies(cookies)); cookieSet.addAll(splitCookies(cookies));
} }
return StringUtil.join(cookieSet, "; ").trim(); return TextUtils.join("; ", cookieSet).trim();
} }
public static Set<String> splitCookies(final String cookies) { public static Set<String> splitCookies(final String cookies) {

View file

@ -1,13 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
ext.kotlin_version = '1.3.50' ext.kotlin_version = '1.3.72'
repositories { repositories {
jcenter() jcenter()
google() google()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.5.1' classpath 'com.android.tools.build:gradle:3.6.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong

View file

@ -1,5 +1,6 @@
#Fri May 01 19:39:41 CEST 2020
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip