Skip to content

Commit ddb318a

Browse files
Stypoxwhistlingwoods
authored andcommitted
Merge pull request TeamNewPipe#12044 from TeamNewPipe/android-auto
Add support for Android Auto *(season 2)*
1 parent 033846d commit ddb318a

27 files changed

+1202
-115
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@
6565
<intent-filter>
6666
<action android:name="android.intent.action.MEDIA_BUTTON" />
6767
</intent-filter>
68+
<intent-filter>
69+
<action android:name="android.media.browse.MediaBrowserService"/>
70+
</intent-filter>
6871
</service>
6972

7073
<activity
@@ -355,5 +358,10 @@
355358
<meta-data
356359
android:name="com.samsung.android.multidisplay.keep_process_alive"
357360
android:value="true" />
361+
<!-- Android Auto -->
362+
<meta-data android:name="com.google.android.gms.car.application"
363+
android:resource="@xml/automotive_app_desc" />
364+
<meta-data android:name="com.google.android.gms.car.notification.SmallIcon"
365+
android:resource="@mipmap/ic_launcher" />
358366
</application>
359367
</manifest>

app/src/main/java/org/schabi/newpipe/MainActivity.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,8 @@ private void openMiniPlayerUponPlayerStarted() {
878878
@Override
879879
public void onReceive(final Context context, final Intent intent) {
880880
if (Objects.equals(intent.getAction(),
881-
VideoDetailFragment.ACTION_PLAYER_STARTED)) {
881+
VideoDetailFragment.ACTION_PLAYER_STARTED)
882+
&& PlayerHolder.getInstance().isPlayerOpen()) {
882883
openMiniPlayerIfMissing();
883884
// At this point the player is added 100%, we can unregister. Other actions
884885
// are useless since the fragment will not be removed after that.
@@ -890,6 +891,10 @@ public void onReceive(final Context context, final Intent intent) {
890891
final IntentFilter intentFilter = new IntentFilter();
891892
intentFilter.addAction(VideoDetailFragment.ACTION_PLAYER_STARTED);
892893
registerReceiver(broadcastReceiver, intentFilter);
894+
895+
// If the PlayerHolder is not bound yet, but the service is running, try to bind to it.
896+
// Once the connection is established, the ACTION_PLAYER_STARTED will be sent.
897+
PlayerHolder.getInstance().tryBindIfNeeded(this);
893898
}
894899
}
895900

app/src/main/java/org/schabi/newpipe/database/history/model/StreamHistoryEntry.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package org.schabi.newpipe.database.history.model
33
import androidx.room.ColumnInfo
44
import androidx.room.Embedded
55
import org.schabi.newpipe.database.stream.model.StreamEntity
6+
import org.schabi.newpipe.extractor.stream.StreamInfoItem
7+
import org.schabi.newpipe.util.image.ImageStrategy
68
import java.time.OffsetDateTime
79

810
data class StreamHistoryEntry(
@@ -27,4 +29,17 @@ data class StreamHistoryEntry(
2729
return this.streamEntity.uid == other.streamEntity.uid && streamId == other.streamId &&
2830
accessDate.isEqual(other.accessDate)
2931
}
32+
33+
fun toStreamInfoItem(): StreamInfoItem =
34+
StreamInfoItem(
35+
streamEntity.serviceId,
36+
streamEntity.url,
37+
streamEntity.title,
38+
streamEntity.streamType,
39+
).apply {
40+
duration = streamEntity.duration
41+
uploaderName = streamEntity.uploader
42+
uploaderUrl = streamEntity.uploaderUrl
43+
thumbnails = ImageStrategy.dbUrlToImageList(streamEntity.thumbnailUrl)
44+
}
3045
}

app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistLocalItem.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.schabi.newpipe.database.playlist;
22

3+
import androidx.annotation.Nullable;
4+
35
import org.schabi.newpipe.database.LocalItem;
46

57
public interface PlaylistLocalItem extends LocalItem {
@@ -10,4 +12,7 @@ public interface PlaylistLocalItem extends LocalItem {
1012
long getUid();
1113

1214
void setDisplayIndex(long displayIndex);
15+
16+
@Nullable
17+
String getThumbnailUrl();
1318
}

app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistMetadataEntry.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_THUMBNAIL_STREAM_ID;
1010
import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_THUMBNAIL_URL;
1111

12+
import androidx.annotation.Nullable;
13+
1214
public class PlaylistMetadataEntry implements PlaylistLocalItem {
1315
public static final String PLAYLIST_STREAM_COUNT = "streamCount";
1416

@@ -71,4 +73,10 @@ public long getUid() {
7173
public void setDisplayIndex(final long displayIndex) {
7274
this.displayIndex = displayIndex;
7375
}
76+
77+
@Nullable
78+
@Override
79+
public String getThumbnailUrl() {
80+
return thumbnailUrl;
81+
}
7482
}

app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistRemoteDAO.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public interface PlaylistRemoteDAO extends BasicDAO<PlaylistRemoteEntity> {
3434

3535
@Query("SELECT * FROM " + REMOTE_PLAYLIST_TABLE + " WHERE "
3636
+ REMOTE_PLAYLIST_ID + " = :playlistId")
37-
Flowable<List<PlaylistRemoteEntity>> getPlaylist(long playlistId);
37+
Flowable<PlaylistRemoteEntity> getPlaylist(long playlistId);
3838

3939
@Query("SELECT * FROM " + REMOTE_PLAYLIST_TABLE + " WHERE "
4040
+ REMOTE_PLAYLIST_URL + " = :url AND " + REMOTE_PLAYLIST_SERVICE_ID + " = :serviceId")

app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import android.text.TextUtils;
44

5+
import androidx.annotation.Nullable;
56
import androidx.room.ColumnInfo;
67
import androidx.room.Entity;
78
import androidx.room.Ignore;
@@ -134,6 +135,8 @@ public void setName(final String name) {
134135
this.name = name;
135136
}
136137

138+
@Nullable
139+
@Override
137140
public String getThumbnailUrl() {
138141
return thumbnailUrl;
139142
}

app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -261,11 +261,14 @@ private void onSharedPreferencesChanged(final SharedPreferences sharedPreference
261261
// Service management
262262
//////////////////////////////////////////////////////////////////////////*/
263263
@Override
264-
public void onServiceConnected(final Player connectedPlayer,
265-
final PlayerService connectedPlayerService,
266-
final boolean playAfterConnect) {
267-
player = connectedPlayer;
264+
public void onServiceConnected(@NonNull final PlayerService connectedPlayerService) {
268265
playerService = connectedPlayerService;
266+
}
267+
268+
@Override
269+
public void onPlayerConnected(@NonNull final Player connectedPlayer,
270+
final boolean playAfterConnect) {
271+
player = connectedPlayer;
269272

270273
// It will do nothing if the player is not in fullscreen mode
271274
hideSystemUiIfNeeded();
@@ -297,11 +300,18 @@ && isAutoplayEnabled()
297300
updateOverlayPlayQueueButtonVisibility();
298301
}
299302

303+
@Override
304+
public void onPlayerDisconnected() {
305+
player = null;
306+
// the binding could be null at this point, if the app is finishing
307+
if (binding != null) {
308+
restoreDefaultBrightness();
309+
}
310+
}
311+
300312
@Override
301313
public void onServiceDisconnected() {
302314
playerService = null;
303-
player = null;
304-
restoreDefaultBrightness();
305315
}
306316

307317

@@ -1998,13 +2008,16 @@ public void onPlayerError(final PlaybackException error, final boolean isCatchab
19982008

19992009
@Override
20002010
public void onServiceStopped() {
2001-
setOverlayPlayPauseImage(false);
2002-
if (currentInfo != null) {
2003-
updateOverlayData(currentInfo.getName(),
2004-
currentInfo.getUploaderName(),
2005-
currentInfo.getThumbnails());
2011+
// the binding could be null at this point, if the app is finishing
2012+
if (binding != null) {
2013+
setOverlayPlayPauseImage(false);
2014+
if (currentInfo != null) {
2015+
updateOverlayData(currentInfo.getName(),
2016+
currentInfo.getUploaderName(),
2017+
currentInfo.getThumbnails());
2018+
}
2019+
updateOverlayPlayQueueButtonVisibility();
20062020
}
2007-
updateOverlayPlayQueueButtonVisibility();
20082021
}
20092022

20102023
@Override

app/src/main/java/org/schabi/newpipe/ktx/Bundle.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,16 @@ import androidx.core.os.BundleCompat
77
inline fun <reified T : Parcelable> Bundle.parcelableArrayList(key: String?): ArrayList<T>? {
88
return BundleCompat.getParcelableArrayList(this, key, T::class.java)
99
}
10+
11+
fun Bundle?.toDebugString(): String {
12+
if (this == null) {
13+
return "null"
14+
}
15+
val string = StringBuilder("Bundle{")
16+
for (key in this.keySet()) {
17+
@Suppress("DEPRECATION") // we want this[key] to return items of any type
18+
string.append(" ").append(key).append(" => ").append(this[key]).append(";")
19+
}
20+
string.append(" }")
21+
return string.toString()
22+
}

app/src/main/java/org/schabi/newpipe/local/playlist/RemotePlaylistManager.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ public Flowable<List<PlaylistRemoteEntity>> getPlaylists() {
2626
return playlistRemoteTable.getPlaylists().subscribeOn(Schedulers.io());
2727
}
2828

29+
public Flowable<PlaylistRemoteEntity> getPlaylist(final long playlistId) {
30+
return playlistRemoteTable.getPlaylist(playlistId).subscribeOn(Schedulers.io());
31+
}
32+
2933
public Flowable<List<PlaylistRemoteEntity>> getPlaylist(final PlaylistInfo info) {
3034
return playlistRemoteTable.getPlaylist(info.getServiceId(), info.getUrl())
3135
.subscribeOn(Schedulers.io());

0 commit comments

Comments
 (0)