Skip to content

Commit

Permalink
Move useExternalPlayer and getPlaybackActivityClass functions to new …
Browse files Browse the repository at this point in the history
…PlaybackLauncher interface (#1064)

* Move useExternalPlayer and getPlaybackActivityClass functions to new PlaybackLauncher interface

* Add toggle to enable new playback module

* Add BuildConfig.DEVELOPMENT
  • Loading branch information
nielsvanvelzen authored Aug 8, 2021
1 parent 5177800 commit fe75e4b
Show file tree
Hide file tree
Showing 13 changed files with 125 additions and 58 deletions.
4 changes: 4 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ android {

// Set flavored application name
resValue("string", "app_name", "@string/app_name_release")

buildConfigField("boolean", "DEVELOPMENT", "false")
}

val debug by getting {
Expand All @@ -50,6 +52,8 @@ android {

// Set flavored application name
resValue("string", "app_name", "@string/app_name_debug")

buildConfigField("boolean", "DEVELOPMENT", (defaultConfig.versionCode!! < 100).toString())
}
}

Expand Down
31 changes: 2 additions & 29 deletions app/src/main/java/org/jellyfin/androidtv/TvApp.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.jellyfin.androidtv;

import static org.koin.java.KoinJavaComponent.inject;

import android.app.Activity;
import android.app.Application;

Expand All @@ -8,17 +10,12 @@
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MediatorLiveData;

import org.jellyfin.androidtv.preference.UserPreferences;
import org.jellyfin.androidtv.preference.constant.PreferredVideoPlayer;
import org.jellyfin.androidtv.ui.livetv.TvManager;
import org.jellyfin.androidtv.ui.playback.ExternalPlayerActivity;
import org.jellyfin.androidtv.ui.playback.PlaybackController;
import org.jellyfin.androidtv.ui.playback.PlaybackOverlayActivity;
import org.jellyfin.apiclient.interaction.ApiClient;
import org.jellyfin.apiclient.interaction.EmptyResponse;
import org.jellyfin.apiclient.interaction.Response;
import org.jellyfin.apiclient.model.dto.BaseItemDto;
import org.jellyfin.apiclient.model.dto.BaseItemType;
import org.jellyfin.apiclient.model.dto.UserDto;
import org.jellyfin.apiclient.model.entities.DisplayPreferences;

Expand All @@ -27,8 +24,6 @@
import kotlin.Lazy;
import timber.log.Timber;

import static org.koin.java.KoinJavaComponent.inject;

public class TvApp extends Application {
public static final String DISPLAY_PREFS_APP_NAME = "ATV";

Expand All @@ -48,7 +43,6 @@ public class TvApp extends Application {
private Activity currentActivity;

private Lazy<ApiClient> apiClient = inject(ApiClient.class);
private Lazy<UserPreferences> userPreferences = inject(UserPreferences.class);

@Override
public void onCreate() {
Expand Down Expand Up @@ -102,27 +96,6 @@ public void setPlaybackController(PlaybackController playbackController) {
this.playbackController = playbackController;
}

public boolean useExternalPlayer(BaseItemType itemType) {
switch (itemType) {
case Movie:
case Episode:
case Video:
case Series:
case Recording:
return userPreferences.getValue().get(UserPreferences.Companion.getVideoPlayer()) == PreferredVideoPlayer.EXTERNAL;
case TvChannel:
case Program:
return userPreferences.getValue().get(UserPreferences.Companion.getLiveTvVideoPlayer()) == PreferredVideoPlayer.EXTERNAL;
default:
return false;
}
}

@NonNull
public Class<? extends Activity> getPlaybackActivityClass(BaseItemType itemType) {
return useExternalPlayer(itemType) ? ExternalPlayerActivity.class : PlaybackOverlayActivity.class;
}

@NonNull
public boolean canManageRecordings() {
UserDto currentUser = getCurrentUser();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.jellyfin.androidtv.data.eventhandling;

import static org.koin.java.KoinJavaComponent.get;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
Expand All @@ -14,6 +16,7 @@
import org.jellyfin.androidtv.ui.itemhandling.ItemLauncher;
import org.jellyfin.androidtv.ui.playback.MediaManager;
import org.jellyfin.androidtv.ui.playback.PlaybackController;
import org.jellyfin.androidtv.ui.playback.PlaybackLauncher;
import org.jellyfin.androidtv.ui.playback.PlaybackOverlayActivity;
import org.jellyfin.androidtv.util.Utils;
import org.jellyfin.androidtv.util.apiclient.PlaybackHelper;
Expand All @@ -34,8 +37,6 @@

import timber.log.Timber;

import static org.koin.java.KoinJavaComponent.get;

public class TvApiEventListener extends ApiEventListener {
private final DataRefreshService dataRefreshService;
private final MediaManager mediaManager;
Expand Down Expand Up @@ -179,8 +180,9 @@ public void onResponse(ItemsResult response) {
//peek at first item to see what type it is
switch (response.getItems()[0].getMediaType()) {
case "Video":
Class activity = get(PlaybackLauncher.class).getPlaybackActivityClass(response.getItems()[0].getBaseItemType());
mediaManager.setCurrentVideoQueue(Arrays.asList(response.getItems()));
Intent intent = new Intent(TvApp.getApplication().getCurrentActivity(), TvApp.getApplication().getPlaybackActivityClass(response.getItems()[0].getBaseItemType()));
Intent intent = new Intent(TvApp.getApplication().getCurrentActivity(), activity);
TvApp.getApplication().getCurrentActivity().startActivity(intent);
break;
case "Audio":
Expand Down
13 changes: 13 additions & 0 deletions app/src/main/java/org/jellyfin/androidtv/di/PlaybackModule.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package org.jellyfin.androidtv.di

import org.jellyfin.androidtv.BuildConfig
import org.jellyfin.androidtv.preference.UserPreferences
import org.jellyfin.androidtv.ui.playback.GarbagePlaybackLauncher
import org.jellyfin.androidtv.ui.playback.PlaybackManager
import org.jellyfin.androidtv.ui.playback.RewritePlaybackLauncher
import org.jellyfin.apiclient.interaction.AndroidDevice
import org.jellyfin.apiclient.logging.AndroidLogger
import org.koin.android.ext.koin.androidApplication
Expand All @@ -13,4 +17,13 @@ val playbackModule = module {
AndroidLogger("PlaybackManager")
)
}

factory {
val preferences = get<UserPreferences>()
val useRewrite = preferences[UserPreferences.playbackRewriteEnabled] && BuildConfig.DEVELOPMENT

// TODO Inject PlaybackLauncher for playback rewrite here
if (useRewrite) RewritePlaybackLauncher()
else GarbagePlaybackLauncher(get())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,6 @@ class UserPreferences(context: Context) : SharedPreferenceStore(
*/
var seasonalGreetingsEnabled = Preference.boolean("pref_enable_themes", true)

/**
* Show additional debug information
*/
var debuggingEnabled = Preference.boolean("pref_enable_debug", false)

/* Playback - General*/
/**
* Maximum bitrate in megabit for playback. A value of [MAX_BITRATE_AUTO] is used when
Expand Down Expand Up @@ -139,6 +134,17 @@ class UserPreferences(context: Context) : SharedPreferenceStore(
*/
var shortcutSubtitleTrack = Preference.int("shortcut_subtitle_track", KeyEvent.KEYCODE_CAPTIONS)

/* Developer options */
/**
* Show additional debug information
*/
var debuggingEnabled = Preference.boolean("pref_enable_debug", false)

/**
* Use playback rewrite module
*/
var playbackRewriteEnabled = Preference.boolean("playback_new", false)

/* ACRA */
/**
* Enable ACRA crash reporting
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.jellyfin.androidtv.ui.itemdetail;

import static org.koin.java.KoinJavaComponent.get;
import static org.koin.java.KoinJavaComponent.inject;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
Expand Down Expand Up @@ -53,6 +56,7 @@
import org.jellyfin.androidtv.ui.livetv.TvManager;
import org.jellyfin.androidtv.ui.playback.ExternalPlayerActivity;
import org.jellyfin.androidtv.ui.playback.MediaManager;
import org.jellyfin.androidtv.ui.playback.PlaybackLauncher;
import org.jellyfin.androidtv.ui.presentation.CardPresenter;
import org.jellyfin.androidtv.ui.presentation.CustomListRowPresenter;
import org.jellyfin.androidtv.ui.presentation.InfoCardPresenter;
Expand Down Expand Up @@ -104,9 +108,6 @@
import kotlin.Lazy;
import timber.log.Timber;

import static org.koin.java.KoinJavaComponent.get;
import static org.koin.java.KoinJavaComponent.inject;

public class FullDetailsActivity extends BaseActivity implements IRecordingIndicatorView {

private int BUTTON_SIZE;
Expand Down Expand Up @@ -1566,7 +1567,8 @@ public void onResponse(List<BaseItemDto> response) {
if (item.getBaseItemType() == BaseItemType.MusicArtist) {
mediaManager.getValue().playNow(response);
} else {
Intent intent = new Intent(FullDetailsActivity.this, TvApp.getApplication().getPlaybackActivityClass(item.getBaseItemType()));
Class activity = get(PlaybackLauncher.class).getPlaybackActivityClass(item.getBaseItemType());
Intent intent = new Intent(FullDetailsActivity.this, activity);
mediaManager.getValue().setCurrentVideoQueue(response);
intent.putExtra("Position", pos);
startActivity(intent);
Expand All @@ -1578,7 +1580,8 @@ public void onResponse(List<BaseItemDto> response) {

protected void play(final BaseItemDto[] items, final int pos, final boolean shuffle) {
List<BaseItemDto> itemsToPlay = Arrays.asList(items);
Intent intent = new Intent(this, TvApp.getApplication().getPlaybackActivityClass(items[0].getBaseItemType()));
Class activity = get(PlaybackLauncher.class).getPlaybackActivityClass(items[0].getBaseItemType());
Intent intent = new Intent(this, activity);
if (shuffle) Collections.shuffle(itemsToPlay);
mediaManager.getValue().setCurrentVideoQueue(itemsToPlay);
intent.putExtra("Position", pos);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.jellyfin.androidtv.ui.itemdetail;

import static org.koin.java.KoinJavaComponent.get;
import static org.koin.java.KoinJavaComponent.inject;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
Expand Down Expand Up @@ -38,6 +41,7 @@
import org.jellyfin.androidtv.ui.playback.AudioEventListener;
import org.jellyfin.androidtv.ui.playback.MediaManager;
import org.jellyfin.androidtv.ui.playback.PlaybackController;
import org.jellyfin.androidtv.ui.playback.PlaybackLauncher;
import org.jellyfin.androidtv.util.ImageUtils;
import org.jellyfin.androidtv.util.InfoLayoutHelper;
import org.jellyfin.androidtv.util.MathUtils;
Expand Down Expand Up @@ -65,8 +69,6 @@
import kotlin.Lazy;
import timber.log.Timber;

import static org.koin.java.KoinJavaComponent.inject;

public class ItemListActivity extends FragmentActivity {
private int BUTTON_SIZE;
public static final String FAV_SONGS = "FAV_SONGS";
Expand Down Expand Up @@ -510,7 +512,8 @@ private void addGenres(TextView textView) {

private void play(List<BaseItemDto> items) {
if ("Video".equals(mBaseItem.getMediaType())) {
Intent intent = new Intent(mActivity, TvApp.getApplication().getPlaybackActivityClass(mBaseItem.getBaseItemType()));
Class activity = get(PlaybackLauncher.class).getPlaybackActivityClass(mBaseItem.getBaseItemType());
Intent intent = new Intent(mActivity, activity);
//Resume first item if needed
BaseItemDto first = items.size() > 0 ? items.get(0) : null;
if (first != null && first.getUserData() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.jellyfin.androidtv.ui.itemdetail.PhotoPlayerActivity;
import org.jellyfin.androidtv.ui.livetv.LiveTvGuideActivity;
import org.jellyfin.androidtv.ui.playback.MediaManager;
import org.jellyfin.androidtv.ui.playback.PlaybackLauncher;
import org.jellyfin.androidtv.util.KeyProcessor;
import org.jellyfin.androidtv.util.Utils;
import org.jellyfin.androidtv.util.apiclient.PlaybackHelper;
Expand Down Expand Up @@ -219,7 +220,8 @@ public void onResponse(DisplayPreferences response) {
PlaybackHelper.getItemsToPlay(baseItem, baseItem.getBaseItemType() == BaseItemType.Movie, false, new Response<List<BaseItemDto>>() {
@Override
public void onResponse(List<BaseItemDto> response) {
Intent intent = new Intent(activity, TvApp.getApplication().getPlaybackActivityClass(baseItem.getBaseItemType()));
Class newActivity = get(PlaybackLauncher.class).getPlaybackActivityClass(baseItem.getBaseItemType());
Intent intent = new Intent(activity, newActivity);
get(MediaManager.class).setCurrentVideoQueue(response);
intent.putExtra("Position", 0);
activity.startActivity(intent);
Expand Down Expand Up @@ -252,7 +254,8 @@ public void onResponse(BaseItemDto response) {
List<BaseItemDto> items = new ArrayList<>();
items.add(response);
get(MediaManager.class).setCurrentVideoQueue(items);
Intent intent = new Intent(activity, TvApp.getApplication().getPlaybackActivityClass(response.getBaseItemType()));
Class newActivity = get(PlaybackLauncher.class).getPlaybackActivityClass(response.getBaseItemType());
Intent intent = new Intent(activity, newActivity);
Long start = chapter.getStartPositionTicks() / 10000;
intent.putExtra("Position", start.intValue());
activity.startActivity(intent);
Expand Down Expand Up @@ -326,7 +329,8 @@ public void onError(Exception exception) {
public void onResponse(BaseItemDto response) {
List<BaseItemDto> items = new ArrayList<>();
items.add(response);
Intent intent = new Intent(activity, TvApp.getApplication().getPlaybackActivityClass(response.getBaseItemType()));
Class newActivity = get(PlaybackLauncher.class).getPlaybackActivityClass(response.getBaseItemType());
Intent intent = new Intent(activity, newActivity);
get(MediaManager.class).setCurrentVideoQueue(items);
intent.putExtra("Position", 0);
activity.startActivity(intent);
Expand All @@ -349,7 +353,8 @@ public void onResponse(BaseItemDto response) {
@Override
public void onResponse(List<BaseItemDto> response) {
// TODO Check whether this usage of BaseItemType.valueOf is okay.
Intent intent = new Intent(activity, TvApp.getApplication().getPlaybackActivityClass(BaseItemType.valueOf(channel.getType())));
Class newActivity = get(PlaybackLauncher.class).getPlaybackActivityClass(BaseItemType.valueOf(channel.getType()));
Intent intent = new Intent(activity, newActivity);
get(MediaManager.class).setCurrentVideoQueue(response);
intent.putExtra("Position", 0);
activity.startActivity(intent);
Expand All @@ -376,7 +381,8 @@ public void onResponse(List<BaseItemDto> response) {
get(ApiClient.class).GetItemAsync(rowItem.getRecordingInfo().getId(), TvApp.getApplication().getCurrentUser().getId(), new Response<BaseItemDto>() {
@Override
public void onResponse(BaseItemDto response) {
Intent intent = new Intent(activity, TvApp.getApplication().getPlaybackActivityClass(rowItem.getBaseItemType()));
Class newActivity = get(PlaybackLauncher.class).getPlaybackActivityClass(rowItem.getBaseItemType());
Intent intent = new Intent(activity, newActivity);
List<BaseItemDto> items = new ArrayList<>();
items.add(response);
get(MediaManager.class).setCurrentVideoQueue(items);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.jellyfin.androidtv.ui.playback

import android.app.Activity
import org.jellyfin.androidtv.preference.UserPreferences
import org.jellyfin.androidtv.preference.constant.PreferredVideoPlayer
import org.jellyfin.apiclient.model.dto.BaseItemType

interface PlaybackLauncher {
fun useExternalPlayer(itemType: BaseItemType?): Boolean
fun getPlaybackActivityClass(itemType: BaseItemType?): Class<out Activity>
}

class GarbagePlaybackLauncher(
private val userPreferences: UserPreferences
) : PlaybackLauncher {
override fun useExternalPlayer(itemType: BaseItemType?) = when (itemType) {
BaseItemType.Movie,
BaseItemType.Episode,
BaseItemType.Video,
BaseItemType.Series,
BaseItemType.Recording,
-> userPreferences[UserPreferences.videoPlayer] === PreferredVideoPlayer.EXTERNAL
BaseItemType.TvChannel,
BaseItemType.Program,
-> userPreferences[UserPreferences.liveTvVideoPlayer] === PreferredVideoPlayer.EXTERNAL
else -> false
}

override fun getPlaybackActivityClass(itemType: BaseItemType?) = when {
useExternalPlayer(itemType) -> ExternalPlayerActivity::class.java
else -> PlaybackOverlayActivity::class.java
}
}

// TODO: Move to playback module
class RewritePlaybackLauncher : PlaybackLauncher {
override fun useExternalPlayer(itemType: BaseItemType?) = false
override fun getPlaybackActivityClass(itemType: BaseItemType?) = TODO("Not yet implemented")
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.jellyfin.androidtv.ui.preference.screen

import org.jellyfin.androidtv.BuildConfig
import org.jellyfin.androidtv.R
import org.jellyfin.androidtv.preference.UserPreferences
import org.jellyfin.androidtv.ui.preference.dsl.OptionsFragment
Expand All @@ -21,6 +22,16 @@ class DeveloperPreferencesScreen : OptionsFragment() {
setContent(R.string.desc_debug)
bind(userPreferences, UserPreferences.debuggingEnabled)
}

// Only show in debug mode
if (BuildConfig.DEVELOPMENT) {
checkbox {
setTitle(R.string.enable_playback_module_title)
setContent(R.string.enable_playback_module_description)

bind(userPreferences, UserPreferences.playbackRewriteEnabled)
}
}
}
}
}
Loading

0 comments on commit fe75e4b

Please sign in to comment.