Update StartDownloadDialogHelper to use TrackSelectionView.
This is now possible as the download helper uses a track selector. PiperOrigin-RevId: 225014517
This commit is contained in:
parent
8d137c2e61
commit
defbd04675
@ -19,13 +19,17 @@ import android.app.Activity;
|
|||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
|
import android.content.res.Resources;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.util.Pair;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ImageButton;
|
||||||
import android.widget.ListView;
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.RenderersFactory;
|
import com.google.android.exoplayer2.RenderersFactory;
|
||||||
@ -37,20 +41,21 @@ import com.google.android.exoplayer2.offline.DownloadManager.TaskState;
|
|||||||
import com.google.android.exoplayer2.offline.DownloadService;
|
import com.google.android.exoplayer2.offline.DownloadService;
|
||||||
import com.google.android.exoplayer2.offline.ProgressiveDownloadHelper;
|
import com.google.android.exoplayer2.offline.ProgressiveDownloadHelper;
|
||||||
import com.google.android.exoplayer2.offline.StreamKey;
|
import com.google.android.exoplayer2.offline.StreamKey;
|
||||||
import com.google.android.exoplayer2.offline.TrackKey;
|
|
||||||
import com.google.android.exoplayer2.source.TrackGroup;
|
|
||||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||||
import com.google.android.exoplayer2.source.dash.offline.DashDownloadHelper;
|
import com.google.android.exoplayer2.source.dash.offline.DashDownloadHelper;
|
||||||
import com.google.android.exoplayer2.source.hls.offline.HlsDownloadHelper;
|
import com.google.android.exoplayer2.source.hls.offline.HlsDownloadHelper;
|
||||||
import com.google.android.exoplayer2.source.smoothstreaming.offline.SsDownloadHelper;
|
import com.google.android.exoplayer2.source.smoothstreaming.offline.SsDownloadHelper;
|
||||||
|
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||||
|
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
|
||||||
|
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||||
import com.google.android.exoplayer2.ui.DefaultTrackNameProvider;
|
import com.google.android.exoplayer2.ui.DefaultTrackNameProvider;
|
||||||
import com.google.android.exoplayer2.ui.TrackNameProvider;
|
import com.google.android.exoplayer2.ui.TrackNameProvider;
|
||||||
|
import com.google.android.exoplayer2.ui.TrackSelectionView;
|
||||||
import com.google.android.exoplayer2.upstream.DataSource;
|
import com.google.android.exoplayer2.upstream.DataSource;
|
||||||
import com.google.android.exoplayer2.util.Log;
|
import com.google.android.exoplayer2.util.Log;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -126,10 +131,8 @@ public class DownloadTracker implements DownloadManager.Listener {
|
|||||||
getDownloadHelper(uri, extension, renderersFactory).getRemoveAction();
|
getDownloadHelper(uri, extension, renderersFactory).getRemoveAction();
|
||||||
startServiceWithAction(removeAction);
|
startServiceWithAction(removeAction);
|
||||||
} else {
|
} else {
|
||||||
StartDownloadDialogHelper helper =
|
new StartDownloadDialogHelper(
|
||||||
new StartDownloadDialogHelper(
|
activity, getDownloadHelper(uri, extension, renderersFactory), name);
|
||||||
activity, getDownloadHelper(uri, extension, renderersFactory), name);
|
|
||||||
helper.prepare();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,61 +220,56 @@ public class DownloadTracker implements DownloadManager.Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("UngroupedOverloads")
|
||||||
private final class StartDownloadDialogHelper
|
private final class StartDownloadDialogHelper
|
||||||
implements DownloadHelper.Callback, DialogInterface.OnClickListener {
|
implements DownloadHelper.Callback,
|
||||||
|
DialogInterface.OnClickListener,
|
||||||
|
View.OnClickListener,
|
||||||
|
TrackSelectionView.DialogCallback {
|
||||||
|
|
||||||
private final DownloadHelper<?> downloadHelper;
|
private final DownloadHelper<?> downloadHelper;
|
||||||
private final String name;
|
private final String name;
|
||||||
|
private final LayoutInflater dialogInflater;
|
||||||
|
private final AlertDialog dialog;
|
||||||
|
private final LinearLayout selectionList;
|
||||||
|
|
||||||
private final AlertDialog.Builder builder;
|
private MappedTrackInfo mappedTrackInfo;
|
||||||
private final View dialogView;
|
private DefaultTrackSelector.Parameters parameters;
|
||||||
private final List<TrackKey> trackKeys;
|
|
||||||
private final ArrayAdapter<String> trackTitles;
|
|
||||||
private final ListView representationList;
|
|
||||||
|
|
||||||
public StartDownloadDialogHelper(
|
private StartDownloadDialogHelper(
|
||||||
Activity activity, DownloadHelper<?> downloadHelper, String name) {
|
Activity activity, DownloadHelper<?> downloadHelper, String name) {
|
||||||
this.downloadHelper = downloadHelper;
|
this.downloadHelper = downloadHelper;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
builder =
|
AlertDialog.Builder builder =
|
||||||
new AlertDialog.Builder(activity)
|
new AlertDialog.Builder(activity)
|
||||||
.setTitle(R.string.exo_download_description)
|
.setTitle(R.string.download_preparing)
|
||||||
.setPositiveButton(android.R.string.ok, this)
|
.setPositiveButton(android.R.string.ok, this)
|
||||||
.setNegativeButton(android.R.string.cancel, null);
|
.setNegativeButton(android.R.string.cancel, null);
|
||||||
|
|
||||||
// Inflate with the builder's context to ensure the correct style is used.
|
// Inflate with the builder's context to ensure the correct style is used.
|
||||||
LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext());
|
dialogInflater = LayoutInflater.from(builder.getContext());
|
||||||
dialogView = dialogInflater.inflate(R.layout.start_download_dialog, null);
|
selectionList = (LinearLayout) dialogInflater.inflate(R.layout.start_download_dialog, null);
|
||||||
|
builder.setView(selectionList);
|
||||||
|
dialog = builder.create();
|
||||||
|
dialog.show();
|
||||||
|
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
|
||||||
|
|
||||||
trackKeys = new ArrayList<>();
|
parameters = DownloadHelper.DEFAULT_TRACK_SELECTOR_PARAMETERS;
|
||||||
trackTitles =
|
|
||||||
new ArrayAdapter<>(
|
|
||||||
builder.getContext(), android.R.layout.simple_list_item_multiple_choice);
|
|
||||||
representationList = dialogView.findViewById(R.id.representation_list);
|
|
||||||
representationList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
|
|
||||||
representationList.setAdapter(trackTitles);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void prepare() {
|
|
||||||
downloadHelper.prepare(this);
|
downloadHelper.prepare(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DownloadHelper.Callback implementation.
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPrepared(DownloadHelper<?> helper) {
|
public void onPrepared(DownloadHelper<?> helper) {
|
||||||
for (int i = 0; i < downloadHelper.getPeriodCount(); i++) {
|
if (helper.getPeriodCount() < 1) {
|
||||||
TrackGroupArray trackGroups = downloadHelper.getTrackGroups(i);
|
onPrepareError(downloadHelper, new IOException("Content is empty."));
|
||||||
for (int j = 0; j < trackGroups.length; j++) {
|
return;
|
||||||
TrackGroup trackGroup = trackGroups.get(j);
|
|
||||||
for (int k = 0; k < trackGroup.length; k++) {
|
|
||||||
trackKeys.add(new TrackKey(i, j, k));
|
|
||||||
trackTitles.add(trackNameProvider.getTrackName(trackGroup.getFormat(k)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!trackKeys.isEmpty()) {
|
mappedTrackInfo = downloadHelper.getMappedTrackInfo(/* periodIndex= */ 0);
|
||||||
builder.setView(dialogView);
|
updateSelectionList();
|
||||||
}
|
dialog.setTitle(R.string.exo_download_description);
|
||||||
builder.create().show();
|
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -280,21 +278,107 @@ public class DownloadTracker implements DownloadManager.Listener {
|
|||||||
context.getApplicationContext(), R.string.download_start_error, Toast.LENGTH_LONG)
|
context.getApplicationContext(), R.string.download_start_error, Toast.LENGTH_LONG)
|
||||||
.show();
|
.show();
|
||||||
Log.e(TAG, "Failed to start download", e);
|
Log.e(TAG, "Failed to start download", e);
|
||||||
|
dialog.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// View.OnClickListener implementation.
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Integer rendererIndex = (Integer) v.getTag();
|
||||||
|
String dialogTitle = getTrackTypeString(mappedTrackInfo.getRendererType(rendererIndex));
|
||||||
|
Pair<AlertDialog, TrackSelectionView> dialogPair =
|
||||||
|
TrackSelectionView.getDialog(
|
||||||
|
dialog.getContext(),
|
||||||
|
dialogTitle,
|
||||||
|
mappedTrackInfo,
|
||||||
|
rendererIndex,
|
||||||
|
parameters,
|
||||||
|
/* callback= */ this);
|
||||||
|
dialogPair.second.setShowDisableOption(true);
|
||||||
|
dialogPair.second.setAllowAdaptiveSelections(false);
|
||||||
|
dialogPair.first.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TrackSelectionView.DialogCallback implementation.
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTracksSelected(DefaultTrackSelector.Parameters parameters) {
|
||||||
|
for (int i = 0; i < downloadHelper.getPeriodCount(); i++) {
|
||||||
|
downloadHelper.replaceTrackSelections(/* periodIndex= */ i, parameters);
|
||||||
|
}
|
||||||
|
this.parameters = parameters;
|
||||||
|
updateSelectionList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// DialogInterface.OnClickListener implementation.
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
ArrayList<TrackKey> selectedTrackKeys = new ArrayList<>();
|
DownloadAction downloadAction = downloadHelper.getDownloadAction(Util.getUtf8Bytes(name));
|
||||||
for (int i = 0; i < representationList.getChildCount(); i++) {
|
startDownload(downloadAction);
|
||||||
if (representationList.isItemChecked(i)) {
|
}
|
||||||
selectedTrackKeys.add(trackKeys.get(i));
|
|
||||||
|
// Internal methods.
|
||||||
|
|
||||||
|
private void updateSelectionList() {
|
||||||
|
selectionList.removeAllViews();
|
||||||
|
for (int i = 0; i < mappedTrackInfo.getRendererCount(); i++) {
|
||||||
|
TrackGroupArray trackGroupArray = mappedTrackInfo.getTrackGroups(i);
|
||||||
|
if (trackGroupArray.length == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String trackTypeString =
|
||||||
|
getTrackTypeString(mappedTrackInfo.getRendererType(/* rendererIndex= */ i));
|
||||||
|
if (trackTypeString == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String trackSelectionsString = getTrackSelectionString(/* rendererIndex= */ i);
|
||||||
|
View view = dialogInflater.inflate(R.layout.download_track_item, selectionList, false);
|
||||||
|
TextView trackTitleView = view.findViewById(R.id.track_title);
|
||||||
|
TextView trackDescView = view.findViewById(R.id.track_desc);
|
||||||
|
ImageButton editButton = view.findViewById(R.id.edit_button);
|
||||||
|
trackTitleView.setText(trackTypeString);
|
||||||
|
trackDescView.setText(trackSelectionsString);
|
||||||
|
editButton.setTag(i);
|
||||||
|
editButton.setOnClickListener(this);
|
||||||
|
selectionList.addView(view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getTrackSelectionString(int rendererIndex) {
|
||||||
|
List<TrackSelection> trackSelections =
|
||||||
|
downloadHelper.getTrackSelections(/* periodIndex= */ 0, rendererIndex);
|
||||||
|
String selectedTracks = "";
|
||||||
|
Resources resources = selectionList.getResources();
|
||||||
|
for (int i = 0; i < trackSelections.size(); i++) {
|
||||||
|
TrackSelection selection = trackSelections.get(i);
|
||||||
|
for (int j = 0; j < selection.length(); j++) {
|
||||||
|
String trackName = trackNameProvider.getTrackName(selection.getFormat(j));
|
||||||
|
if (i == 0 && j == 0) {
|
||||||
|
selectedTracks = trackName;
|
||||||
|
} else {
|
||||||
|
selectedTracks = resources.getString(R.string.exo_item_list, selectedTracks, trackName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!selectedTrackKeys.isEmpty() || trackKeys.isEmpty()) {
|
return selectedTracks.isEmpty()
|
||||||
// We have selected keys, or we're dealing with single stream content.
|
? resources.getString(R.string.exo_track_selection_none)
|
||||||
DownloadAction downloadAction =
|
: selectedTracks;
|
||||||
downloadHelper.getDownloadAction(Util.getUtf8Bytes(name), selectedTrackKeys);
|
}
|
||||||
startDownload(downloadAction);
|
|
||||||
|
@Nullable
|
||||||
|
private String getTrackTypeString(int trackType) {
|
||||||
|
Resources resources = selectionList.getResources();
|
||||||
|
switch (trackType) {
|
||||||
|
case C.TRACK_TYPE_VIDEO:
|
||||||
|
return resources.getString(R.string.exo_track_selection_title_video);
|
||||||
|
case C.TRACK_TYPE_AUDIO:
|
||||||
|
return resources.getString(R.string.exo_track_selection_title_audio);
|
||||||
|
case C.TRACK_TYPE_TEXT:
|
||||||
|
return resources.getString(R.string.exo_track_selection_title_text);
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BIN
demos/main/src/main/res/drawable-hdpi/ic_edit.png
Executable file
BIN
demos/main/src/main/res/drawable-hdpi/ic_edit.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 304 B |
BIN
demos/main/src/main/res/drawable-mdpi/ic_edit.png
Executable file
BIN
demos/main/src/main/res/drawable-mdpi/ic_edit.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 242 B |
BIN
demos/main/src/main/res/drawable-xhdpi/ic_edit.png
Executable file
BIN
demos/main/src/main/res/drawable-xhdpi/ic_edit.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 299 B |
BIN
demos/main/src/main/res/drawable-xxhdpi/ic_edit.png
Executable file
BIN
demos/main/src/main/res/drawable-xxhdpi/ic_edit.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 413 B |
BIN
demos/main/src/main/res/drawable-xxxhdpi/ic_edit.png
Executable file
BIN
demos/main/src/main/res/drawable-xxxhdpi/ic_edit.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 449 B |
53
demos/main/src/main/res/layout/download_track_item.xml
Normal file
53
demos/main/src/main/res/layout/download_track_item.xml
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2018 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingStart="12dp"
|
||||||
|
android:paddingEnd="12dp"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/track_title"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingTop="4dp"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/track_desc"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingBottom="4dp"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/edit_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:contentDescription="@string/download_edit_track"
|
||||||
|
android:src="@drawable/ic_edit"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -13,7 +13,8 @@
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/representation_list"
|
android:id="@+id/selection_list"
|
||||||
|
android:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"/>
|
android:layout_height="match_parent"/>
|
||||||
|
@ -51,6 +51,10 @@
|
|||||||
|
|
||||||
<string name="ima_not_loaded">Playing sample without ads, as the IMA extension was not loaded</string>
|
<string name="ima_not_loaded">Playing sample without ads, as the IMA extension was not loaded</string>
|
||||||
|
|
||||||
|
<string name="download_edit_track">Edit selection</string>
|
||||||
|
|
||||||
|
<string name="download_preparing">Preparing download…</string>
|
||||||
|
|
||||||
<string name="download_start_error">Failed to start download</string>
|
<string name="download_start_error">Failed to start download</string>
|
||||||
|
|
||||||
<string name="download_playlist_unsupported">This demo app does not support downloading playlists</string>
|
<string name="download_playlist_unsupported">This demo app does not support downloading playlists</string>
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.ui;
|
package com.google.android.exoplayer2.ui;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@ -33,13 +32,25 @@ import com.google.android.exoplayer2.source.TrackGroup;
|
|||||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride;
|
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride;
|
||||||
import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
|
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
|
|
||||||
/** A view for making track selections. */
|
/** A view for making track selections. */
|
||||||
public class TrackSelectionView extends LinearLayout {
|
public class TrackSelectionView extends LinearLayout {
|
||||||
|
|
||||||
|
/** Callback which is invoked when a track selection has been made. */
|
||||||
|
public interface DialogCallback {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when track are selected.
|
||||||
|
*
|
||||||
|
* @param parameters The {@link DefaultTrackSelector.Parameters} for the selected tracks.
|
||||||
|
*/
|
||||||
|
void onTracksSelected(DefaultTrackSelector.Parameters parameters);
|
||||||
|
}
|
||||||
|
|
||||||
private final int selectableItemBackgroundResourceId;
|
private final int selectableItemBackgroundResourceId;
|
||||||
private final LayoutInflater inflater;
|
private final LayoutInflater inflater;
|
||||||
private final CheckedTextView disableView;
|
private final CheckedTextView disableView;
|
||||||
@ -51,35 +62,64 @@ public class TrackSelectionView extends LinearLayout {
|
|||||||
private TrackNameProvider trackNameProvider;
|
private TrackNameProvider trackNameProvider;
|
||||||
private CheckedTextView[][] trackViews;
|
private CheckedTextView[][] trackViews;
|
||||||
|
|
||||||
private DefaultTrackSelector trackSelector;
|
private @MonotonicNonNull MappedTrackInfo mappedTrackInfo;
|
||||||
private int rendererIndex;
|
private int rendererIndex;
|
||||||
|
private DefaultTrackSelector.Parameters parameters;
|
||||||
private TrackGroupArray trackGroups;
|
private TrackGroupArray trackGroups;
|
||||||
private boolean isDisabled;
|
private boolean isDisabled;
|
||||||
private @Nullable SelectionOverride override;
|
@Nullable private SelectionOverride override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a pair consisting of a dialog and the {@link TrackSelectionView} that will be shown by it.
|
* Gets a pair consisting of a dialog and the {@link TrackSelectionView} that will be shown by it.
|
||||||
*
|
*
|
||||||
* @param activity The parent activity.
|
* <p>The dialog shows the current configuration of the provided {@code TrackSelector} and updates
|
||||||
|
* the parameters when closing the dialog.
|
||||||
|
*
|
||||||
|
* @param context The parent context.
|
||||||
* @param title The dialog's title.
|
* @param title The dialog's title.
|
||||||
* @param trackSelector The track selector.
|
* @param trackSelector The track selector.
|
||||||
* @param rendererIndex The index of the renderer.
|
* @param rendererIndex The index of the renderer.
|
||||||
* @return The dialog and the {@link TrackSelectionView} that will be shown by it.
|
* @return The dialog and the {@link TrackSelectionView} that will be shown by it.
|
||||||
*/
|
*/
|
||||||
public static Pair<AlertDialog, TrackSelectionView> getDialog(
|
public static Pair<AlertDialog, TrackSelectionView> getDialog(
|
||||||
Activity activity,
|
Context context, CharSequence title, DefaultTrackSelector trackSelector, int rendererIndex) {
|
||||||
|
return getDialog(
|
||||||
|
context,
|
||||||
|
title,
|
||||||
|
Assertions.checkNotNull(trackSelector.getCurrentMappedTrackInfo()),
|
||||||
|
rendererIndex,
|
||||||
|
trackSelector.getParameters(),
|
||||||
|
trackSelector::setParameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a pair consisting of a dialog and the {@link TrackSelectionView} that will be shown by it.
|
||||||
|
*
|
||||||
|
* @param context The parent context.
|
||||||
|
* @param title The dialog's title.
|
||||||
|
* @param mappedTrackInfo The {@link MappedTrackInfo}.
|
||||||
|
* @param rendererIndex The index of the renderer.
|
||||||
|
* @param parameters The {@link DefaultTrackSelector.Parameters}.
|
||||||
|
* @param callback The {@link DialogCallback} invoked when the dialog is closed successfully.
|
||||||
|
* @return The dialog and the {@link TrackSelectionView} that will be shown by it.
|
||||||
|
*/
|
||||||
|
public static Pair<AlertDialog, TrackSelectionView> getDialog(
|
||||||
|
Context context,
|
||||||
CharSequence title,
|
CharSequence title,
|
||||||
DefaultTrackSelector trackSelector,
|
MappedTrackInfo mappedTrackInfo,
|
||||||
int rendererIndex) {
|
int rendererIndex,
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
DefaultTrackSelector.Parameters parameters,
|
||||||
|
DialogCallback callback) {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||||
|
|
||||||
// Inflate with the builder's context to ensure the correct style is used.
|
// Inflate with the builder's context to ensure the correct style is used.
|
||||||
LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext());
|
LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext());
|
||||||
View dialogView = dialogInflater.inflate(R.layout.exo_track_selection_dialog, null);
|
View dialogView = dialogInflater.inflate(R.layout.exo_track_selection_dialog, null);
|
||||||
|
|
||||||
final TrackSelectionView selectionView = dialogView.findViewById(R.id.exo_track_selection_view);
|
TrackSelectionView selectionView = dialogView.findViewById(R.id.exo_track_selection_view);
|
||||||
selectionView.init(trackSelector, rendererIndex);
|
selectionView.init(mappedTrackInfo, rendererIndex, parameters);
|
||||||
Dialog.OnClickListener okClickListener = (dialog, which) -> selectionView.applySelection();
|
Dialog.OnClickListener okClickListener =
|
||||||
|
(dialog, which) -> callback.onTracksSelected(selectionView.getSelectionParameters());
|
||||||
|
|
||||||
AlertDialog dialog =
|
AlertDialog dialog =
|
||||||
builder
|
builder
|
||||||
@ -113,6 +153,8 @@ public class TrackSelectionView extends LinearLayout {
|
|||||||
inflater = LayoutInflater.from(context);
|
inflater = LayoutInflater.from(context);
|
||||||
componentListener = new ComponentListener();
|
componentListener = new ComponentListener();
|
||||||
trackNameProvider = new DefaultTrackNameProvider(getResources());
|
trackNameProvider = new DefaultTrackNameProvider(getResources());
|
||||||
|
parameters = DefaultTrackSelector.Parameters.DEFAULT;
|
||||||
|
trackGroups = TrackGroupArray.EMPTY;
|
||||||
|
|
||||||
// View for disabling the renderer.
|
// View for disabling the renderer.
|
||||||
disableView =
|
disableView =
|
||||||
@ -176,18 +218,35 @@ public class TrackSelectionView extends LinearLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the view to select tracks for a specified renderer using a {@link
|
* Initialize the view to select tracks for a specified renderer using {@link MappedTrackInfo} and
|
||||||
* DefaultTrackSelector}.
|
* a set of {@link DefaultTrackSelector.Parameters}.
|
||||||
*
|
*
|
||||||
* @param trackSelector The {@link DefaultTrackSelector}.
|
* @param mappedTrackInfo The {@link MappedTrackInfo}.
|
||||||
* @param rendererIndex The index of the renderer.
|
* @param rendererIndex The index of the renderer.
|
||||||
|
* @param parameters The {@link DefaultTrackSelector.Parameters}.
|
||||||
*/
|
*/
|
||||||
public void init(DefaultTrackSelector trackSelector, int rendererIndex) {
|
public void init(
|
||||||
this.trackSelector = trackSelector;
|
MappedTrackInfo mappedTrackInfo,
|
||||||
|
int rendererIndex,
|
||||||
|
DefaultTrackSelector.Parameters parameters) {
|
||||||
|
this.mappedTrackInfo = mappedTrackInfo;
|
||||||
this.rendererIndex = rendererIndex;
|
this.rendererIndex = rendererIndex;
|
||||||
|
this.parameters = parameters;
|
||||||
updateViews();
|
updateViews();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns the {@link DefaultTrackSelector.Parameters} for the current selection. */
|
||||||
|
public DefaultTrackSelector.Parameters getSelectionParameters() {
|
||||||
|
DefaultTrackSelector.ParametersBuilder parametersBuilder = parameters.buildUpon();
|
||||||
|
parametersBuilder.setRendererDisabled(rendererIndex, isDisabled);
|
||||||
|
if (override != null) {
|
||||||
|
parametersBuilder.setSelectionOverride(rendererIndex, trackGroups, override);
|
||||||
|
} else {
|
||||||
|
parametersBuilder.clearSelectionOverrides(rendererIndex);
|
||||||
|
}
|
||||||
|
return parametersBuilder.build();
|
||||||
|
}
|
||||||
|
|
||||||
// Private methods.
|
// Private methods.
|
||||||
|
|
||||||
private void updateViews() {
|
private void updateViews() {
|
||||||
@ -196,9 +255,7 @@ public class TrackSelectionView extends LinearLayout {
|
|||||||
removeViewAt(i);
|
removeViewAt(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
MappingTrackSelector.MappedTrackInfo trackInfo =
|
if (mappedTrackInfo == null) {
|
||||||
trackSelector == null ? null : trackSelector.getCurrentMappedTrackInfo();
|
|
||||||
if (trackSelector == null || trackInfo == null) {
|
|
||||||
// The view is not initialized.
|
// The view is not initialized.
|
||||||
disableView.setEnabled(false);
|
disableView.setEnabled(false);
|
||||||
defaultView.setEnabled(false);
|
defaultView.setEnabled(false);
|
||||||
@ -207,9 +264,8 @@ public class TrackSelectionView extends LinearLayout {
|
|||||||
disableView.setEnabled(true);
|
disableView.setEnabled(true);
|
||||||
defaultView.setEnabled(true);
|
defaultView.setEnabled(true);
|
||||||
|
|
||||||
trackGroups = trackInfo.getTrackGroups(rendererIndex);
|
trackGroups = mappedTrackInfo.getTrackGroups(rendererIndex);
|
||||||
|
|
||||||
DefaultTrackSelector.Parameters parameters = trackSelector.getParameters();
|
|
||||||
isDisabled = parameters.getRendererDisabled(rendererIndex);
|
isDisabled = parameters.getRendererDisabled(rendererIndex);
|
||||||
override = parameters.getSelectionOverride(rendererIndex, trackGroups);
|
override = parameters.getSelectionOverride(rendererIndex, trackGroups);
|
||||||
|
|
||||||
@ -220,7 +276,7 @@ public class TrackSelectionView extends LinearLayout {
|
|||||||
boolean enableAdaptiveSelections =
|
boolean enableAdaptiveSelections =
|
||||||
allowAdaptiveSelections
|
allowAdaptiveSelections
|
||||||
&& trackGroups.get(groupIndex).length > 1
|
&& trackGroups.get(groupIndex).length > 1
|
||||||
&& trackInfo.getAdaptiveSupport(rendererIndex, groupIndex, false)
|
&& mappedTrackInfo.getAdaptiveSupport(rendererIndex, groupIndex, false)
|
||||||
!= RendererCapabilities.ADAPTIVE_NOT_SUPPORTED;
|
!= RendererCapabilities.ADAPTIVE_NOT_SUPPORTED;
|
||||||
trackViews[groupIndex] = new CheckedTextView[group.length];
|
trackViews[groupIndex] = new CheckedTextView[group.length];
|
||||||
for (int trackIndex = 0; trackIndex < group.length; trackIndex++) {
|
for (int trackIndex = 0; trackIndex < group.length; trackIndex++) {
|
||||||
@ -235,7 +291,7 @@ public class TrackSelectionView extends LinearLayout {
|
|||||||
(CheckedTextView) inflater.inflate(trackViewLayoutId, this, false);
|
(CheckedTextView) inflater.inflate(trackViewLayoutId, this, false);
|
||||||
trackView.setBackgroundResource(selectableItemBackgroundResourceId);
|
trackView.setBackgroundResource(selectableItemBackgroundResourceId);
|
||||||
trackView.setText(trackNameProvider.getTrackName(group.getFormat(trackIndex)));
|
trackView.setText(trackNameProvider.getTrackName(group.getFormat(trackIndex)));
|
||||||
if (trackInfo.getTrackSupport(rendererIndex, groupIndex, trackIndex)
|
if (mappedTrackInfo.getTrackSupport(rendererIndex, groupIndex, trackIndex)
|
||||||
== RendererCapabilities.FORMAT_HANDLED) {
|
== RendererCapabilities.FORMAT_HANDLED) {
|
||||||
trackView.setFocusable(true);
|
trackView.setFocusable(true);
|
||||||
trackView.setTag(Pair.create(groupIndex, trackIndex));
|
trackView.setTag(Pair.create(groupIndex, trackIndex));
|
||||||
@ -263,17 +319,6 @@ public class TrackSelectionView extends LinearLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applySelection() {
|
|
||||||
DefaultTrackSelector.ParametersBuilder parametersBuilder = trackSelector.buildUponParameters();
|
|
||||||
parametersBuilder.setRendererDisabled(rendererIndex, isDisabled);
|
|
||||||
if (override != null) {
|
|
||||||
parametersBuilder.setSelectionOverride(rendererIndex, trackGroups, override);
|
|
||||||
} else {
|
|
||||||
parametersBuilder.clearSelectionOverrides(rendererIndex);
|
|
||||||
}
|
|
||||||
trackSelector.setParameters(parametersBuilder);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onClick(View view) {
|
private void onClick(View view) {
|
||||||
if (view == disableView) {
|
if (view == disableView) {
|
||||||
onDisableViewClicked();
|
onDisableViewClicked();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user