BraveNewPipeLegacy: (Kitkat) reapply 'Clean up pre-Lollipop checks' in reverse

The patch is from commit 99104fc11d
'Clean up pre-Lollipop checks'
This commit is contained in:
evermind 2024-02-29 15:04:36 +01:00
parent 8fb17b4301
commit 225effed0b
25 changed files with 211 additions and 57 deletions

View file

@ -153,7 +153,7 @@ public final class DownloaderImpl extends Downloader {
RequestBody requestBody = null; RequestBody requestBody = null;
if (dataToSend != null) { if (dataToSend != null) {
requestBody = RequestBody.create(dataToSend); requestBody = RequestBody.create(null, dataToSend);
} }
final okhttp3.Request.Builder requestBuilder = new okhttp3.Request.Builder() final okhttp3.Request.Builder requestBuilder = new okhttp3.Request.Builder()

View file

@ -3,6 +3,7 @@ package org.schabi.newpipe;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.NavigationHelper;
@ -43,7 +44,11 @@ public class ExitActivity extends Activity {
protected void onCreate(final Bundle savedInstanceState) { protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
finishAndRemoveTask(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
finishAndRemoveTask();
} else {
finish();
}
NavigationHelper.restartApp(this); NavigationHelper.restartApp(this);
} }

View file

@ -28,6 +28,7 @@ import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
@ -85,6 +86,7 @@ import org.schabi.newpipe.util.PermissionHelper;
import org.schabi.newpipe.util.SerializedCache; import org.schabi.newpipe.util.SerializedCache;
import org.schabi.newpipe.util.ServiceHelper; import org.schabi.newpipe.util.ServiceHelper;
import org.schabi.newpipe.util.StateSaver; import org.schabi.newpipe.util.StateSaver;
import org.schabi.newpipe.util.BraveTLSSocketFactory;
import org.schabi.newpipe.util.ThemeHelper; import org.schabi.newpipe.util.ThemeHelper;
import org.schabi.newpipe.views.FocusOverlayView; import org.schabi.newpipe.views.FocusOverlayView;
@ -129,6 +131,11 @@ public class MainActivity extends AppCompatActivity {
+ "savedInstanceState = [" + savedInstanceState + "]"); + "savedInstanceState = [" + savedInstanceState + "]");
} }
// enable TLS1.1/1.2 for kitkat devices, to fix download and play for media.ccc.de sources
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
BraveTLSSocketFactory.setAsDefault();
}
ThemeHelper.setDayNightMode(this); ThemeHelper.setDayNightMode(this);
ThemeHelper.setTheme(this, ServiceHelper.getSelectedServiceId(this)); ThemeHelper.setTheme(this, ServiceHelper.getSelectedServiceId(this));

View file

@ -3,6 +3,7 @@ package org.schabi.newpipe;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
/* /*
@ -39,6 +40,10 @@ public class PanicResponderActivity extends Activity {
ExitActivity.exitAndRemoveFromRecentApps(this); ExitActivity.exitAndRemoveFromRecentApps(this);
} }
finishAndRemoveTask(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
finishAndRemoveTask();
} else {
finish();
}
} }
} }

View file

@ -3,6 +3,7 @@ package org.schabi.newpipe.error;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.Menu; import android.view.Menu;
@ -108,7 +109,12 @@ public class ReCaptchaActivity extends AppCompatActivity {
// cleaning cache, history and cookies from webView // cleaning cache, history and cookies from webView
recaptchaBinding.reCaptchaWebView.clearCache(true); recaptchaBinding.reCaptchaWebView.clearCache(true);
recaptchaBinding.reCaptchaWebView.clearHistory(); recaptchaBinding.reCaptchaWebView.clearHistory();
CookieManager.getInstance().removeAllCookies(null); final CookieManager cookieManager = CookieManager.getInstance();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
cookieManager.removeAllCookies(value -> { });
} else {
cookieManager.removeAllCookie();
}
recaptchaBinding.reCaptchaWebView.loadUrl(url); recaptchaBinding.reCaptchaWebView.loadUrl(url);
} }

View file

@ -1884,7 +1884,13 @@ public final class VideoDetailFragment
} }
scrollToTop(); scrollToTop();
tryAddVideoPlayerView(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
tryAddVideoPlayerView();
} else {
// KitKat needs a delay before addVideoPlayerView call or it reports wrong height in
// activity.getWindow().getDecorView().getHeight()
new Handler().post(this::tryAddVideoPlayerView);
}
} }
@Override @Override
@ -1947,8 +1953,10 @@ public final class VideoDetailFragment
} }
activity.getWindow().getDecorView().setSystemUiVisibility(0); activity.getWindow().getDecorView().setSystemUiVisibility(0);
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
activity.getWindow().setStatusBarColor(ThemeHelper.resolveColorFromAttr( if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
requireContext(), android.R.attr.colorPrimary)); activity.getWindow().setStatusBarColor(ThemeHelper.resolveColorFromAttr(
requireContext(), android.R.attr.colorPrimary));
}
} }
private void hideSystemUi() { private void hideSystemUi() {
@ -1979,7 +1987,8 @@ public final class VideoDetailFragment
} }
activity.getWindow().getDecorView().setSystemUiVisibility(visibility); activity.getWindow().getDecorView().setSystemUiVisibility(visibility);
if (isInMultiWindow || isFullscreen()) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
&& (isInMultiWindow || isFullscreen())) {
activity.getWindow().setStatusBarColor(Color.TRANSPARENT); activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
activity.getWindow().setNavigationBarColor(Color.TRANSPARENT); activity.getWindow().setNavigationBarColor(Color.TRANSPARENT);
} }

View file

@ -507,6 +507,9 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
+ lastSearchedString); + lastSearchedString);
} }
searchEditText.setText(searchString); searchEditText.setText(searchString);
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
searchEditText.setHintTextColor(searchEditText.getTextColors().withAlpha(128));
}
if (TextUtils.isEmpty(searchString) || TextUtils.isEmpty(searchEditText.getText())) { if (TextUtils.isEmpty(searchString) || TextUtils.isEmpty(searchEditText.getText())) {
searchToolbarContainer.setTranslationX(100); searchToolbarContainer.setTranslationX(100);

View file

@ -8,10 +8,12 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.widget.ImageViewCompat
import androidx.core.widget.doOnTextChanged import androidx.core.widget.doOnTextChanged
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
@ -122,6 +124,14 @@ class FeedGroupDialog : DialogFragment(), BackPressable {
_feedGroupCreateBinding = DialogFeedGroupCreateBinding.bind(view) _feedGroupCreateBinding = DialogFeedGroupCreateBinding.bind(view)
_searchLayoutBinding = feedGroupCreateBinding.subscriptionsHeaderSearchContainer _searchLayoutBinding = feedGroupCreateBinding.subscriptionsHeaderSearchContainer
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
// KitKat doesn't apply container's theme to <include> content
val contrastColor = AppCompatResources.getColorStateList(requireContext(), R.color.contrastColor)
searchLayoutBinding.toolbarSearchEditText.setTextColor(contrastColor)
searchLayoutBinding.toolbarSearchEditText.setHintTextColor(contrastColor.withAlpha(128))
ImageViewCompat.setImageTintList(searchLayoutBinding.toolbarSearchClearIcon, contrastColor)
}
viewModel = ViewModelProvider( viewModel = ViewModelProvider(
this, this,
FeedGroupDialogViewModel.getFactory( FeedGroupDialogViewModel.getFactory(

View file

@ -22,6 +22,7 @@ import android.content.res.Resources;
import android.database.ContentObserver; import android.database.ContentObserver;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Color; import android.graphics.Color;
import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.provider.Settings; import android.provider.Settings;
@ -449,8 +450,10 @@ public final class MainPlayerUi extends VideoPlayerUi implements View.OnLayoutCh
public void showSystemUIPartially() { public void showSystemUIPartially() {
if (isFullscreen) { if (isFullscreen) {
getParentActivity().map(Activity::getWindow).ifPresent(window -> { getParentActivity().map(Activity::getWindow).ifPresent(window -> {
window.setStatusBarColor(Color.TRANSPARENT); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.setNavigationBarColor(Color.TRANSPARENT); window.setStatusBarColor(Color.TRANSPARENT);
window.setNavigationBarColor(Color.TRANSPARENT);
}
final int visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE final int visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;

View file

@ -65,10 +65,16 @@ public class DownloadSettingsFragment extends BasePreferenceFragment {
prefStorageAsk = findPreference(downloadStorageAsk); prefStorageAsk = findPreference(downloadStorageAsk);
final SwitchPreferenceCompat prefUseSaf = findPreference(storageUseSafPreference); final SwitchPreferenceCompat prefUseSaf = findPreference(storageUseSafPreference);
prefUseSaf.setDefaultValue(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP);
prefUseSaf.setChecked(NewPipeSettings.useStorageAccessFramework(ctx)); prefUseSaf.setChecked(NewPipeSettings.useStorageAccessFramework(ctx));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
|| Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
prefUseSaf.setEnabled(false); prefUseSaf.setEnabled(false);
prefUseSaf.setSummary(R.string.downloads_storage_use_saf_summary_api_29); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
prefUseSaf.setSummary(R.string.downloads_storage_use_saf_summary_api_29);
} else {
prefUseSaf.setSummary(R.string.downloads_storage_use_saf_summary_api_19);
}
prefStorageAsk.setSummary(R.string.downloads_storage_ask_summary_no_saf_notice); prefStorageAsk.setSummary(R.string.downloads_storage_ask_summary_no_saf_notice);
} }
@ -246,7 +252,8 @@ public class DownloadSettingsFragment extends BasePreferenceFragment {
forgetSAFTree(context, defaultPreferences.getString(key, "")); forgetSAFTree(context, defaultPreferences.getString(key, ""));
if (!FilePickerActivityHelper.isOwnFileUri(context, uri)) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
&& !FilePickerActivityHelper.isOwnFileUri(context, uri)) {
// steps to acquire the selected path: // steps to acquire the selected path:
// 1. acquire permissions on the new save path // 1. acquire permissions on the new save path
// 2. save the new path, if step(2) was successful // 2. save the new path, if step(2) was successful

View file

@ -109,7 +109,7 @@ public final class NewPipeSettings {
public static boolean useStorageAccessFramework(final Context context) { public static boolean useStorageAccessFramework(final Context context) {
// There's a FireOS bug which prevents SAF open/close dialogs from being confirmed with a // There's a FireOS bug which prevents SAF open/close dialogs from being confirmed with a
// remote (see #6455). // remote (see #6455).
if (DeviceUtils.isFireTv()) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP || DeviceUtils.isFireTv()) {
return false; return false;
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
return true; return true;

View file

@ -1,9 +1,19 @@
package org.schabi.newpipe.settings package org.schabi.newpipe.settings
import android.os.Build
import android.os.Bundle import android.os.Bundle
import androidx.preference.Preference
import org.schabi.newpipe.R
class NotificationSettingsFragment : BasePreferenceFragment() { class NotificationSettingsFragment : BasePreferenceFragment() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResourceRegistry() addPreferencesFromResourceRegistry()
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
val colorizePref: Preference? = findPreference(getString(R.string.notification_colorize_key))
colorizePref?.let {
preferenceScreen.removePreference(it)
}
}
} }
} }

View file

@ -2,6 +2,7 @@ package org.schabi.newpipe.settings;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Build;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -71,12 +72,12 @@ public final class SettingMigrations {
// and standard way to access folders and files to be used consistently everywhere. // and standard way to access folders and files to be used consistently everywhere.
// We reset the setting to its default value, i.e. "use SAF", since now there are no // We reset the setting to its default value, i.e. "use SAF", since now there are no
// more issues with SAF and users should use that one instead of the old // more issues with SAF and users should use that one instead of the old
// NoNonsenseFilePicker. Also, there's a bug on FireOS in which SAF open/close // NoNonsenseFilePicker. SAF does not work on KitKat and below, though, so the setting
// is set to false in that case. Also, there's a bug on FireOS in which SAF open/close
// dialogs cannot be confirmed with a remote (see #6455). // dialogs cannot be confirmed with a remote (see #6455).
sp.edit().putBoolean( sp.edit().putBoolean(context.getString(R.string.storage_use_saf),
context.getString(R.string.storage_use_saf), Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
!DeviceUtils.isFireTv() && !DeviceUtils.isFireTv()).apply();
).apply();
} }
}; };

View file

@ -6,6 +6,7 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter; import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable; import android.graphics.drawable.RippleDrawable;
import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.util.Log; import android.util.Log;
@ -64,7 +65,8 @@ public final class PreferenceSearchResultHighlighter {
recyclerView.findViewHolderForAdapterPosition(position); recyclerView.findViewHolderForAdapterPosition(position);
if (holder != null) { if (holder != null) {
final Drawable background = holder.itemView.getBackground(); final Drawable background = holder.itemView.getBackground();
if (background instanceof RippleDrawable) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
&& background instanceof RippleDrawable) {
showRippleAnimation((RippleDrawable) background); showRippleAnimation((RippleDrawable) background);
return; return;
} }

View file

@ -5,6 +5,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.database.Cursor; import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import android.provider.DocumentsContract; import android.provider.DocumentsContract;
import android.util.Log; import android.util.Log;
@ -59,6 +60,10 @@ public class StoredDirectoryHelper {
throw new IOException(e); throw new IOException(e);
} }
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
throw new IOException("Storage Access Framework with Directory API is not available");
}
this.docTree = DocumentFile.fromTreeUri(context, path); this.docTree = DocumentFile.fromTreeUri(context, path);
if (this.docTree == null) { if (this.docTree == null) {
@ -75,7 +80,7 @@ public class StoredDirectoryHelper {
final String[] filename = splitFilename(name); final String[] filename = splitFilename(name);
final String lcFileName = filename[0].toLowerCase(); final String lcFileName = filename[0].toLowerCase();
if (docTree == null) { if (docTree == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
try (Stream<Path> stream = Files.list(ioTree)) { try (Stream<Path> stream = Files.list(ioTree)) {
matches.addAll(stream.map(path -> path.getFileName().toString().toLowerCase()) matches.addAll(stream.map(path -> path.getFileName().toString().toLowerCase())
.filter(fileName -> fileName.startsWith(lcFileName)) .filter(fileName -> fileName.startsWith(lcFileName))
@ -294,7 +299,7 @@ public class StoredDirectoryHelper {
*/ */
static DocumentFile findFileSAFHelper(@Nullable final Context context, final DocumentFile tree, static DocumentFile findFileSAFHelper(@Nullable final Context context, final DocumentFile tree,
final String filename) { final String filename) {
if (context == null) { if (context == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
return tree.findFile(filename); // warning: this is very slow return tree.findFile(filename); // warning: this is very slow
} }

View file

@ -1,5 +1,6 @@
package org.schabi.newpipe.streams.io; package org.schabi.newpipe.streams.io;
import android.annotation.TargetApi;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -77,6 +78,7 @@ public class StoredFileHelper implements Serializable {
this.tag = tag; this.tag = tag;
} }
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
StoredFileHelper(@Nullable final Context context, final DocumentFile tree, StoredFileHelper(@Nullable final Context context, final DocumentFile tree,
final String filename, final String mime, final boolean safe) final String filename, final String mime, final boolean safe)
throws IOException { throws IOException {
@ -118,6 +120,7 @@ public class StoredFileHelper implements Serializable {
srcType = mime; srcType = mime;
} }
@TargetApi(Build.VERSION_CODES.KITKAT)
public StoredFileHelper(final Context context, @Nullable final Uri parent, public StoredFileHelper(final Context context, @Nullable final Uri parent,
@NonNull final Uri path, final String tag) throws IOException { @NonNull final Uri path, final String tag) throws IOException {
this.tag = tag; this.tag = tag;

View file

@ -145,7 +145,7 @@ public final class DeviceUtils {
boolean isTv = ContextCompat.getSystemService(context, UiModeManager.class) boolean isTv = ContextCompat.getSystemService(context, UiModeManager.class)
.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION .getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION
|| isFireTv() || isFireTv()
|| pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK); || pm.hasSystemFeature(PackageManager.FEATURE_TELEVISION);
// from https://stackoverflow.com/a/58932366 // from https://stackoverflow.com/a/58932366
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
@ -157,6 +157,10 @@ public final class DeviceUtils {
&& pm.hasSystemFeature(PackageManager.FEATURE_ETHERNET)); && pm.hasSystemFeature(PackageManager.FEATURE_ETHERNET));
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
isTv = isTv || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
}
DeviceUtils.isTV = isTv; DeviceUtils.isTV = isTv;
return DeviceUtils.isTV; return DeviceUtils.isTV;
} }
@ -319,11 +323,12 @@ public final class DeviceUtils {
* <a href="https://github.com/TeamNewPipe/NewPipe/issues/9023">#9023</a> for more info.</p> * <a href="https://github.com/TeamNewPipe/NewPipe/issues/9023">#9023</a> for more info.</p>
* @Note Update {@link #MEDIA_TUNNELING_DEVICE_BLACKLIST_VERSION} * @Note Update {@link #MEDIA_TUNNELING_DEVICE_BLACKLIST_VERSION}
* when adding a new device to the method. * when adding a new device to the method.
* @return {@code false} if affected device; {@code true} otherwise * @return {@code false} if Kitkat (does not support tunneling) or affected device
*/ */
public static boolean shouldSupportMediaTunneling() { public static boolean shouldSupportMediaTunneling() {
// Maintainers note: update MEDIA_TUNNELING_DEVICES_UPDATE_APP_VERSION_CODE // Maintainers note: update MEDIA_TUNNELING_DEVICES_UPDATE_APP_VERSION_CODE
return !HI3798MV200 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
&& !HI3798MV200
&& !CVT_MT5886_EU_1G && !CVT_MT5886_EU_1G
&& !REALTEKATV && !REALTEKATV
&& !QM16XE_U && !QM16XE_U

View file

@ -36,6 +36,7 @@ public final class PermissionHelper {
return checkWriteStoragePermissions(activity, requestCode); return checkWriteStoragePermissions(activity, requestCode);
} }
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public static boolean checkReadStoragePermissions(final Activity activity, public static boolean checkReadStoragePermissions(final Activity activity,
final int requestCode) { final int requestCode) {
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE) if (ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE)

View file

@ -191,10 +191,17 @@ public final class ShareUtils {
} }
// Migrate any clip data and flags from the original intent. // Migrate any clip data and flags from the original intent.
final int permFlags = intent.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION final int permFlags;
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION permFlags = intent.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
| Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
} else {
permFlags = intent.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
}
if (permFlags != 0) { if (permFlags != 0) {
ClipData targetClipData = intent.getClipData(); ClipData targetClipData = intent.getClipData();
if (targetClipData == null && intent.getData() != null) { if (targetClipData == null && intent.getData() != null) {

View file

@ -21,6 +21,7 @@ package org.schabi.newpipe.views;
import android.animation.ValueAnimator; import android.animation.ValueAnimator;
import android.content.Context; import android.content.Context;
import android.os.Build;
import android.os.Parcelable; import android.os.Parcelable;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
@ -28,6 +29,7 @@ import android.widget.LinearLayout;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import org.schabi.newpipe.ktx.ViewUtils; import org.schabi.newpipe.ktx.ViewUtils;
@ -74,6 +76,7 @@ public class CollapsibleView extends LinearLayout {
super(context, attrs, defStyleAttr); super(context, attrs, defStyleAttr);
} }
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public CollapsibleView(final Context context, final AttributeSet attrs, final int defStyleAttr, public CollapsibleView(final Context context, final AttributeSet attrs, final int defStyleAttr,
final int defStyleRes) { final int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes); super(context, attrs, defStyleAttr, defStyleRes);

View file

@ -1,6 +1,7 @@
package org.schabi.newpipe.views; package org.schabi.newpipe.views;
import android.content.Context; import android.content.Context;
import android.os.Build;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.SurfaceView; import android.view.SurfaceView;
@ -44,7 +45,10 @@ public class ExpandableSurfaceView extends SurfaceView {
scaleX = 1.0f; scaleX = 1.0f;
scaleY = 1.0f; scaleY = 1.0f;
if (resizeMode == RESIZE_MODE_FIT) { if (resizeMode == RESIZE_MODE_FIT
// KitKat doesn't work well when a view has a scale like needed for ZOOM
|| (resizeMode == RESIZE_MODE_ZOOM
&& Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)) {
if (aspectDeformation > 0) { if (aspectDeformation > 0) {
height = (int) (width / videoAspectRatio); height = (int) (width / videoAspectRatio);
} else { } else {

View file

@ -17,8 +17,10 @@
*/ */
package org.schabi.newpipe.views; package org.schabi.newpipe.views;
import android.annotation.TargetApi;
import android.content.Context; import android.content.Context;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.Build;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -73,6 +75,7 @@ public final class FocusAwareCoordinator extends CoordinatorLayout {
* Makes possible for multiple fragments to co-exist. Without this code * Makes possible for multiple fragments to co-exist. Without this code
* the first ViewGroup who consumes will be the last who receive the insets * the first ViewGroup who consumes will be the last who receive the insets
*/ */
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override @Override
public WindowInsets dispatchApplyWindowInsets(final WindowInsets insets) { public WindowInsets dispatchApplyWindowInsets(final WindowInsets insets) {
boolean consumed = false; boolean consumed = false;

View file

@ -1,5 +1,6 @@
package us.shandian.giga.get; package us.shandian.giga.get;
import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.system.ErrnoException; import android.system.ErrnoException;
import android.system.OsConstants; import android.system.OsConstants;
@ -316,14 +317,16 @@ public class DownloadMission extends Mission {
public synchronized void notifyError(int code, Exception err) { public synchronized void notifyError(int code, Exception err) {
Log.e(TAG, "notifyError() code = " + code, err); Log.e(TAG, "notifyError() code = " + code, err);
if (err != null && err.getCause() instanceof ErrnoException) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
int errno = ((ErrnoException) err.getCause()).errno; if (err != null && err.getCause() instanceof ErrnoException) {
if (errno == OsConstants.ENOSPC) { int errno = ((ErrnoException) err.getCause()).errno;
code = ERROR_INSUFFICIENT_STORAGE; if (errno == OsConstants.ENOSPC) {
err = null; code = ERROR_INSUFFICIENT_STORAGE;
} else if (errno == OsConstants.EACCES) { err = null;
code = ERROR_PERMISSION_DENIED; } else if (errno == OsConstants.EACCES) {
err = null; code = ERROR_PERMISSION_DENIED;
err = null;
}
} }
} }

View file

@ -7,8 +7,10 @@ import android.app.Notification;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.Service; import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.graphics.Bitmap; import android.graphics.Bitmap;
@ -19,6 +21,7 @@ import android.net.NetworkInfo;
import android.net.NetworkRequest; import android.net.NetworkRequest;
import android.net.Uri; import android.net.Uri;
import android.os.Binder; import android.os.Binder;
import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.Handler.Callback; import android.os.Handler.Callback;
import android.os.IBinder; import android.os.IBinder;
@ -103,6 +106,7 @@ public class DownloadManagerService extends Service {
private final List<Callback> mEchoObservers = new ArrayList<>(1); private final List<Callback> mEchoObservers = new ArrayList<>(1);
private ConnectivityManager mConnectivityManager; private ConnectivityManager mConnectivityManager;
private BroadcastReceiver mNetworkStateListener = null;
private ConnectivityManager.NetworkCallback mNetworkStateListenerL = null; private ConnectivityManager.NetworkCallback mNetworkStateListenerL = null;
private SharedPreferences mPrefs = null; private SharedPreferences mPrefs = null;
@ -169,18 +173,28 @@ public class DownloadManagerService extends Service {
mConnectivityManager = ContextCompat.getSystemService(this, mConnectivityManager = ContextCompat.getSystemService(this,
ConnectivityManager.class); ConnectivityManager.class);
mNetworkStateListenerL = new ConnectivityManager.NetworkCallback() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
@Override mNetworkStateListenerL = new ConnectivityManager.NetworkCallback() {
public void onAvailable(Network network) { @Override
handleConnectivityState(false); public void onAvailable(Network network) {
} handleConnectivityState(false);
}
@Override @Override
public void onLost(Network network) { public void onLost(Network network) {
handleConnectivityState(false); handleConnectivityState(false);
} }
}; };
mConnectivityManager.registerNetworkCallback(new NetworkRequest.Builder().build(), mNetworkStateListenerL); mConnectivityManager.registerNetworkCallback(new NetworkRequest.Builder().build(), mNetworkStateListenerL);
} else {
mNetworkStateListener = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
handleConnectivityState(false);
}
};
registerReceiver(mNetworkStateListener, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
mPrefs.registerOnSharedPreferenceChangeListener(mPrefChangeListener); mPrefs.registerOnSharedPreferenceChangeListener(mPrefChangeListener);
@ -239,7 +253,10 @@ public class DownloadManagerService extends Service {
manageLock(false); manageLock(false);
mConnectivityManager.unregisterNetworkCallback(mNetworkStateListenerL); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
mConnectivityManager.unregisterNetworkCallback(mNetworkStateListenerL);
else
unregisterReceiver(mNetworkStateListener);
mPrefs.unregisterOnSharedPreferenceChangeListener(mPrefChangeListener); mPrefs.unregisterOnSharedPreferenceChangeListener(mPrefChangeListener);
@ -253,6 +270,21 @@ public class DownloadManagerService extends Service {
@Override @Override
public IBinder onBind(Intent intent) { public IBinder onBind(Intent intent) {
/*
int permissionCheck;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
permissionCheck = PermissionChecker.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
if (permissionCheck == PermissionChecker.PERMISSION_DENIED) {
Toast.makeText(this, "Permission denied (read)", Toast.LENGTH_SHORT).show();
}
}
permissionCheck = PermissionChecker.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permissionCheck == PermissionChecker.PERMISSION_DENIED) {
Toast.makeText(this, "Permission denied (write)", Toast.LENGTH_SHORT).show();
}
*/
return mBinder; return mBinder;
} }
@ -470,7 +502,12 @@ public class DownloadManagerService extends Service {
if (downloadDoneCount == 1) { if (downloadDoneCount == 1) {
downloadDoneList.append(name); downloadDoneList.append(name);
downloadDoneNotification.setContentTitle(null); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
downloadDoneNotification.setContentTitle(getString(R.string.app_name));
} else {
downloadDoneNotification.setContentTitle(null);
}
downloadDoneNotification.setContentText(Localization.downloadCount(this, downloadDoneCount)); downloadDoneNotification.setContentText(Localization.downloadCount(this, downloadDoneCount));
downloadDoneNotification.setStyle(new NotificationCompat.BigTextStyle() downloadDoneNotification.setStyle(new NotificationCompat.BigTextStyle()
.setBigContentTitle(Localization.downloadCount(this, downloadDoneCount)) .setBigContentTitle(Localization.downloadCount(this, downloadDoneCount))
@ -503,10 +540,16 @@ public class DownloadManagerService extends Service {
.setContentIntent(mOpenDownloadList); .setContentIntent(mOpenDownloadList);
} }
downloadFailedNotification.setContentTitle(getString(R.string.download_failed)); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
downloadFailedNotification.setContentText(mission.storage.getName()); downloadFailedNotification.setContentTitle(getString(R.string.app_name));
downloadFailedNotification.setStyle(new NotificationCompat.BigTextStyle() downloadFailedNotification.setStyle(new NotificationCompat.BigTextStyle()
.bigText(mission.storage.getName())); .bigText(getString(R.string.download_failed).concat(": ").concat(mission.storage.getName())));
} else {
downloadFailedNotification.setContentTitle(getString(R.string.download_failed));
downloadFailedNotification.setContentText(mission.storage.getName());
downloadFailedNotification.setStyle(new NotificationCompat.BigTextStyle()
.bigText(mission.storage.getName()));
}
mNotificationManager.notify(id, downloadFailedNotification.build()); mNotificationManager.notify(id, downloadFailedNotification.build());
} }
@ -543,7 +586,12 @@ public class DownloadManagerService extends Service {
if (path.charAt(0) == File.separatorChar) { if (path.charAt(0) == File.separatorChar) {
Log.i(TAG, "Old save path style present: " + path); Log.i(TAG, "Old save path style present: " + path);
path = "";
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
path = Uri.fromFile(new File(path)).toString();
else
path = "";
mPrefs.edit().putString(getString(prefKey), "").apply(); mPrefs.edit().putString(getString(prefKey), "").apply();
} }

View file

@ -370,7 +370,11 @@ public class MissionAdapter extends Adapter<ViewHolder> implements Handler.Callb
Intent intent = new Intent(Intent.ACTION_VIEW); Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(resolveShareableUri(mission), mimeType); intent.setDataAndType(resolveShareableUri(mission), mimeType);
intent.addFlags(FLAG_GRANT_READ_URI_PERMISSION); intent.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(FLAG_GRANT_PREFIX_URI_PERMISSION);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
intent.addFlags(FLAG_GRANT_PREFIX_URI_PERMISSION);
}
ShareUtils.openIntentInApp(mContext, intent); ShareUtils.openIntentInApp(mContext, intent);
} }