diff --git a/app/build.gradle b/app/build.gradle index 37b03e4ae..4a3cd82b5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -12,8 +12,8 @@ android { resValue "string", "app_name", "NewPipe" minSdkVersion 19 targetSdkVersion 28 - versionCode 900 - versionName "0.19.0" + versionCode 910 + versionName "0.19.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true @@ -46,6 +46,7 @@ android { } else { applicationIdSuffix ".debug." + normalizedWorkingBranch resValue "string", "app_name", "NewPipe " + workingBranch + archivesBaseName = 'NewPipe_' + normalizedWorkingBranch } } } diff --git a/app/src/androidTest/java/org/schabi/newpipe/database/AppDatabaseTest.kt b/app/src/androidTest/java/org/schabi/newpipe/database/AppDatabaseTest.kt index 9ecea9f86..2b7dcdf7c 100644 --- a/app/src/androidTest/java/org/schabi/newpipe/database/AppDatabaseTest.kt +++ b/app/src/androidTest/java/org/schabi/newpipe/database/AppDatabaseTest.kt @@ -25,6 +25,9 @@ class AppDatabaseTest { private const val DEFAULT_DURATION = 480L private const val DEFAULT_UPLOADER_NAME = "Uploader Test" private const val DEFAULT_THUMBNAIL = "https://example.com/example.jpg" + + private const val DEFAULT_SECOND_SERVICE_ID = 0 + private const val DEFAULT_SECOND_URL = "https://www.youtube.com/watch?v=ncQU6iBn5Fc" } @get:Rule val testHelper = MigrationTestHelper(InstrumentationRegistry.getInstrumentation(), @@ -45,6 +48,26 @@ class AppDatabaseTest { put("uploader", DEFAULT_UPLOADER_NAME) put("thumbnail_url", DEFAULT_THUMBNAIL) }) + insert("streams", SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply { + // put("uid", null) + put("service_id", DEFAULT_SECOND_SERVICE_ID) + put("url", DEFAULT_SECOND_URL) + // put("title", null) + // put("stream_type", null) + // put("duration", null) + // put("uploader", null) + // put("thumbnail_url", null) + }) + insert("streams", SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply { + // put("uid", null) + put("service_id", DEFAULT_SERVICE_ID) + // put("url", null) + // put("title", null) + // put("stream_type", null) + // put("duration", null) + // put("uploader", null) + // put("thumbnail_url", null) + }) close() } @@ -53,9 +76,11 @@ class AppDatabaseTest { val migratedDatabaseV3 = getMigratedDatabase() val listFromDB = migratedDatabaseV3.streamDAO().all.blockingFirst() - assertEquals(1, listFromDB.size) - val streamFromMigratedDatabase = listFromDB.first() + // Only expect 2, the one with the null url will be ignored + assertEquals(2, listFromDB.size) + + val streamFromMigratedDatabase = listFromDB[0] assertEquals(DEFAULT_SERVICE_ID, streamFromMigratedDatabase.serviceId) assertEquals(DEFAULT_URL, streamFromMigratedDatabase.url) assertEquals(DEFAULT_TITLE, streamFromMigratedDatabase.title) @@ -67,6 +92,20 @@ class AppDatabaseTest { assertNull(streamFromMigratedDatabase.textualUploadDate) assertNull(streamFromMigratedDatabase.uploadDate) assertNull(streamFromMigratedDatabase.isUploadDateApproximation) + + val secondStreamFromMigratedDatabase = listFromDB[1] + assertEquals(DEFAULT_SECOND_SERVICE_ID, secondStreamFromMigratedDatabase.serviceId) + assertEquals(DEFAULT_SECOND_URL, secondStreamFromMigratedDatabase.url) + assertEquals("", secondStreamFromMigratedDatabase.title) + // Should fallback to VIDEO_STREAM + assertEquals(StreamType.VIDEO_STREAM, secondStreamFromMigratedDatabase.streamType) + assertEquals(0, secondStreamFromMigratedDatabase.duration) + assertEquals("", secondStreamFromMigratedDatabase.uploader) + assertEquals("", secondStreamFromMigratedDatabase.thumbnailUrl) + assertNull(secondStreamFromMigratedDatabase.viewCount) + assertNull(secondStreamFromMigratedDatabase.textualUploadDate) + assertNull(secondStreamFromMigratedDatabase.uploadDate) + assertNull(secondStreamFromMigratedDatabase.isUploadDateApproximation) } private fun getMigratedDatabase(): AppDatabase { diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java index 7d77da774..798119e9e 100644 --- a/app/src/main/java/org/schabi/newpipe/MainActivity.java +++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java @@ -88,11 +88,12 @@ public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; public static final boolean DEBUG = !BuildConfig.BUILD_TYPE.equals("release"); - private ActionBarDrawerToggle toggle = null; - private DrawerLayout drawer = null; - private NavigationView drawerItems = null; - private TextView headerServiceView = null; - private Button toggleServiceButton = null; + private ActionBarDrawerToggle toggle; + private DrawerLayout drawer; + private NavigationView drawerItems; + private ImageView headerServiceIcon; + private TextView headerServiceView; + private Button toggleServiceButton; private boolean servicesShown = false; private ImageView serviceArrow; @@ -294,11 +295,10 @@ public class MainActivity extends AppCompatActivity { View hView = navigationView.getHeaderView(0); serviceArrow = hView.findViewById(R.id.drawer_arrow); + headerServiceIcon = hView.findViewById(R.id.drawer_header_service_icon); headerServiceView = hView.findViewById(R.id.drawer_header_service_view); toggleServiceButton = hView.findViewById(R.id.drawer_header_action_button); - toggleServiceButton.setOnClickListener(view -> { - toggleServices(); - }); + toggleServiceButton.setOnClickListener(view -> toggleServices()); } private void toggleServices() { @@ -308,7 +308,6 @@ public class MainActivity extends AppCompatActivity { drawerItems.getMenu().removeGroup(R.id.menu_tabs_group); drawerItems.getMenu().removeGroup(R.id.menu_options_about_group); - if(servicesShown) { showServices(); } else { @@ -321,7 +320,7 @@ public class MainActivity extends AppCompatActivity { } private void showServices() { - serviceArrow.setImageResource(R.drawable.ic_arrow_up_white); + serviceArrow.setImageResource(R.drawable.ic_arrow_drop_up_white_24dp); for(StreamingService s : NewPipe.getServices()) { final String title = s.getServiceInfo().getName() + @@ -379,7 +378,7 @@ public class MainActivity extends AppCompatActivity { } private void showTabs() throws ExtractionException { - serviceArrow.setImageResource(R.drawable.ic_arrow_down_white); + serviceArrow.setImageResource(R.drawable.ic_arrow_drop_down_white_24dp); //Tabs int currentServiceId = ServiceHelper.getSelectedServiceId(this); @@ -437,9 +436,11 @@ public class MainActivity extends AppCompatActivity { // when the user returns to MainActivity drawer.closeDrawer(GravityCompat.START, false); try { - String selectedServiceName = NewPipe.getService( - ServiceHelper.getSelectedServiceId(this)).getServiceInfo().getName(); + final int selectedServiceId = ServiceHelper.getSelectedServiceId(this); + final String selectedServiceName = NewPipe.getService(selectedServiceId).getServiceInfo().getName(); headerServiceView.setText(selectedServiceName); + headerServiceIcon.setImageResource(ServiceHelper.getIcon(selectedServiceId)); + headerServiceView.post(() -> headerServiceView.setSelected(true)); toggleServiceButton.setContentDescription( getString(R.string.drawer_header_description) + selectedServiceName); @@ -487,7 +488,7 @@ public class MainActivity extends AppCompatActivity { if (DEBUG) Log.d(TAG, "onBackPressed() called"); if (AndroidTvUtils.isTv()) { - View drawerPanel = findViewById(R.id.navigation_layout); + View drawerPanel = findViewById(R.id.navigation); if (drawer.isDrawerOpen(drawerPanel)) { drawer.closeDrawers(); return; diff --git a/app/src/main/java/org/schabi/newpipe/database/Migrations.java b/app/src/main/java/org/schabi/newpipe/database/Migrations.java index ccb097a7b..afefb2fd1 100644 --- a/app/src/main/java/org/schabi/newpipe/database/Migrations.java +++ b/app/src/main/java/org/schabi/newpipe/database/Migrations.java @@ -81,8 +81,16 @@ public class Migrations { " duration INTEGER NOT NULL, uploader TEXT NOT NULL, thumbnail_url TEXT, view_count INTEGER, textual_upload_date TEXT, upload_date INTEGER," + " is_upload_date_approximation INTEGER)"); - database.execSQL("INSERT INTO streams_new (uid, service_id, url, title, stream_type, duration, uploader, thumbnail_url, view_count, textual_upload_date, upload_date, is_upload_date_approximation)"+ - " SELECT uid, service_id, url, title, stream_type, duration, uploader, thumbnail_url, NULL, NULL, NULL, NULL FROM streams"); + database.execSQL("INSERT INTO streams_new (uid, service_id, url, title, stream_type," + + "duration, uploader, thumbnail_url, view_count," + + "textual_upload_date, upload_date, is_upload_date_approximation) " + + + "SELECT uid, service_id, url, ifnull(title, ''), ifnull(stream_type, 'VIDEO_STREAM')," + + "ifnull(duration, 0), ifnull(uploader, ''), ifnull(thumbnail_url, ''), NULL," + + "NULL, NULL, NULL " + + + "FROM streams " + + "WHERE url IS NOT NULL"); database.execSQL("DROP TABLE streams"); database.execSQL("ALTER TABLE streams_new RENAME TO streams"); diff --git a/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java b/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java index 113592b47..aff3586c8 100644 --- a/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java +++ b/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java @@ -3,17 +3,9 @@ package org.schabi.newpipe.player; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; -import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.IBinder; import android.provider.Settings; - -import androidx.appcompat.app.AppCompatActivity; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.appcompat.widget.Toolbar; -import androidx.recyclerview.widget.ItemTouchHelper; - import android.util.Log; import android.view.Menu; import android.view.MenuItem; @@ -26,6 +18,12 @@ import android.widget.ProgressBar; import android.widget.SeekBar; import android.widget.TextView; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + import com.google.android.exoplayer2.PlaybackParameters; import com.google.android.exoplayer2.Player; @@ -698,13 +696,10 @@ public abstract class ServicePlayerActivity extends AppCompatActivity item.setTitle(player.isMuted() ? R.string.unmute : R.string.mute); //2) Icon change accordingly to current App Theme - item.setIcon(player.isMuted() ? getThemedDrawable(R.attr.volume_off) : getThemedDrawable(R.attr.volume_on)); + // using rootView.getContext() because getApplicationContext() didn't work + item.setIcon(player.isMuted() + ? ThemeHelper.resolveResourceIdFromAttr(rootView.getContext(), R.attr.volume_off) + : ThemeHelper.resolveResourceIdFromAttr(rootView.getContext(), R.attr.volume_on)); } } - - private Drawable getThemedDrawable(int attribute) { - return getResources().getDrawable( - getTheme().obtainStyledAttributes(R.style.Theme_AppCompat, new int[]{attribute}) - .getResourceId(0, 0)); - } } diff --git a/app/src/main/java/org/schabi/newpipe/streams/DataReader.java b/app/src/main/java/org/schabi/newpipe/streams/DataReader.java index 75b55cd73..8c57d8978 100644 --- a/app/src/main/java/org/schabi/newpipe/streams/DataReader.java +++ b/app/src/main/java/org/schabi/newpipe/streams/DataReader.java @@ -69,6 +69,11 @@ public class DataReader { return primitive[0] << 24 | primitive[1] << 16 | primitive[2] << 8 | primitive[3]; } + public long readUnsignedInt() throws IOException { + long value = readInt(); + return value & 0xffffffffL; + } + public short readShort() throws IOException { primitiveRead(SHORT_SIZE); return (short) (primitive[0] << 8 | primitive[1]); diff --git a/app/src/main/java/org/schabi/newpipe/streams/Mp4DashReader.java b/app/src/main/java/org/schabi/newpipe/streams/Mp4DashReader.java index 0cfd856e1..b7efa038e 100644 --- a/app/src/main/java/org/schabi/newpipe/streams/Mp4DashReader.java +++ b/app/src/main/java/org/schabi/newpipe/streams/Mp4DashReader.java @@ -294,10 +294,6 @@ public class Mp4DashReader { - private long readUint() throws IOException { - return stream.readInt() & 0xffffffffL; - } - public static boolean hasFlag(int flags, int mask) { return (flags & mask) == mask; } @@ -317,7 +313,7 @@ public class Mp4DashReader { private Box readBox() throws IOException { Box b = new Box(); b.offset = stream.position(); - b.size = stream.readInt(); + b.size = stream.readUnsignedInt(); b.type = stream.readInt(); if (b.size == 1) { @@ -478,7 +474,7 @@ public class Mp4DashReader { private long parse_tfdt() throws IOException { int version = stream.read(); stream.skipBytes(3);// flags - return version == 0 ? readUint() : stream.readLong(); + return version == 0 ? stream.readUnsignedInt() : stream.readLong(); } private Trun parse_trun() throws IOException { @@ -551,7 +547,7 @@ public class Mp4DashReader { stream.skipBytes(2 * (version == 0 ? 4 : 8)); Mvhd obj = new Mvhd(); - obj.timeScale = readUint(); + obj.timeScale = stream.readUnsignedInt(); // chunkDuration stream.skipBytes(version == 0 ? 4 : 8); @@ -563,7 +559,7 @@ public class Mp4DashReader { // predefined stream.skipBytes(76); - obj.nextTrackId = readUint(); + obj.nextTrackId = stream.readUnsignedInt(); return obj; } @@ -582,7 +578,7 @@ public class Mp4DashReader { stream.skipBytes(4);// reserved - obj.duration = version == 0 ? readUint() : stream.readLong(); + obj.duration = version == 0 ? stream.readUnsignedInt() : stream.readLong(); stream.skipBytes(2 * 4);// reserved diff --git a/app/src/main/java/org/schabi/newpipe/streams/Mp4FromDashWriter.java b/app/src/main/java/org/schabi/newpipe/streams/Mp4FromDashWriter.java index 64e4534cb..67f68d3a7 100644 --- a/app/src/main/java/org/schabi/newpipe/streams/Mp4FromDashWriter.java +++ b/app/src/main/java/org/schabi/newpipe/streams/Mp4FromDashWriter.java @@ -46,7 +46,7 @@ public class Mp4FromDashWriter { private int overrideMainBrand = 0x00; - private ArrayList compatibleBrands = new ArrayList<>(5); + private final ArrayList compatibleBrands = new ArrayList<>(5); public Mp4FromDashWriter(SharpStream... sources) throws IOException { for (SharpStream src : sources) { diff --git a/app/src/main/java/us/shandian/giga/io/ChunkFileInputStream.java b/app/src/main/java/us/shandian/giga/io/ChunkFileInputStream.java index 98015e37e..f7edf3975 100644 --- a/app/src/main/java/us/shandian/giga/io/ChunkFileInputStream.java +++ b/app/src/main/java/us/shandian/giga/io/ChunkFileInputStream.java @@ -104,7 +104,7 @@ public class ChunkFileInputStream extends SharpStream { @Override public long available() { - return (int) (length - position); + return length - position; } @SuppressWarnings("EmptyCatchBlock") diff --git a/app/src/main/java/us/shandian/giga/io/CircularFileWriter.java b/app/src/main/java/us/shandian/giga/io/CircularFileWriter.java index 102580570..d3dde7835 100644 --- a/app/src/main/java/us/shandian/giga/io/CircularFileWriter.java +++ b/app/src/main/java/us/shandian/giga/io/CircularFileWriter.java @@ -221,7 +221,7 @@ public class CircularFileWriter extends SharpStream { available = out.length - offsetOut; } - int length = Math.min(len, (int) available); + int length = Math.min(len, (int) Math.min(Integer.MAX_VALUE, available)); out.write(b, off, length); len -= length; diff --git a/app/src/main/res/drawable-hdpi/ic_arrow_down_white.png b/app/src/main/res/drawable-hdpi/ic_arrow_down_white.png deleted file mode 100644 index 33939600d..000000000 Binary files a/app/src/main/res/drawable-hdpi/ic_arrow_down_white.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_arrow_up_white.png b/app/src/main/res/drawable-hdpi/ic_arrow_up_white.png deleted file mode 100644 index 0972a9bca..000000000 Binary files a/app/src/main/res/drawable-hdpi/ic_arrow_up_white.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_arrow_down_white.png b/app/src/main/res/drawable-mdpi/ic_arrow_down_white.png deleted file mode 100644 index 40a0f499e..000000000 Binary files a/app/src/main/res/drawable-mdpi/ic_arrow_down_white.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_arrow_up_white.png b/app/src/main/res/drawable-mdpi/ic_arrow_up_white.png deleted file mode 100644 index fe67b4673..000000000 Binary files a/app/src/main/res/drawable-mdpi/ic_arrow_up_white.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_arrow_down_white.png b/app/src/main/res/drawable-xhdpi/ic_arrow_down_white.png deleted file mode 100644 index 86bc5db3b..000000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_arrow_down_white.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_arrow_up_white.png b/app/src/main/res/drawable-xhdpi/ic_arrow_up_white.png deleted file mode 100644 index dda36882e..000000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_arrow_up_white.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_arrow_down_white.png b/app/src/main/res/drawable-xxhdpi/ic_arrow_down_white.png deleted file mode 100644 index 7e901e098..000000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_arrow_down_white.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_arrow_up_white.png b/app/src/main/res/drawable-xxhdpi/ic_arrow_up_white.png deleted file mode 100644 index bc71e23de..000000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_arrow_up_white.png and /dev/null differ diff --git a/app/src/main/res/drawable/drawer_header_bottom_background.xml b/app/src/main/res/drawable/drawer_header_bottom_background.xml new file mode 100644 index 000000000..913522274 --- /dev/null +++ b/app/src/main/res/drawable/drawer_header_bottom_background.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_arrow_drop_down_white_24dp.xml b/app/src/main/res/drawable/ic_arrow_drop_down_white_24dp.xml new file mode 100644 index 000000000..588d26403 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_drop_down_white_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_arrow_drop_up_white_24dp.xml b/app/src/main/res/drawable/ic_arrow_drop_up_white_24dp.xml new file mode 100644 index 000000000..2a2ceba52 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_drop_up_white_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout-v21/drawer_header.xml b/app/src/main/res/layout-v21/drawer_header.xml deleted file mode 100644 index 7a7c6f155..000000000 --- a/app/src/main/res/layout-v21/drawer_header.xml +++ /dev/null @@ -1,80 +0,0 @@ - - - -