Skip to content

Commit f17e846

Browse files
authored
Merge pull request #251 from androidx/release-1.0.0-rc01
1.0.0 rc01
2 parents c2cbb63 + 98bf30d commit f17e846

File tree

347 files changed

+27478
-6091
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

347 files changed

+27478
-6091
lines changed

.github/ISSUE_TEMPLATE/bug.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ body:
1717
label: Media3 Version
1818
description: What version of Media3 are you using?
1919
options:
20+
- 1.0.0-rc01
2021
- 1.0.0-beta03
2122
- 1.0.0-beta02
2223
- 1.0.0-beta01

README.md

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,13 @@ Android, including local playback (via ExoPlayer) and media sessions.
55

66
## Current status
77

8-
AndroidX Media is currently in beta and we welcome your feedback via the
9-
[issue tracker][]. Please consult the [release notes][] for more details about
10-
the beta release.
8+
AndroidX Media is currently in release candidate and we welcome your feedback
9+
via the [issue tracker][]. Please consult the [release notes][] for more details
10+
about the current release.
1111

1212
ExoPlayer's new home will be in AndroidX Media, but for now we are publishing it
13-
both in AndroidX Media and via the existing [ExoPlayer project][]. While
14-
AndroidX Media is in beta we recommend that production apps using ExoPlayer
15-
continue to depend on the existing ExoPlayer project. We are still handling
16-
ExoPlayer issues on the [ExoPlayer issue tracker][].
13+
both in AndroidX Media and via the existing [ExoPlayer project][] and we are
14+
still handling ExoPlayer issues on the [ExoPlayer issue tracker][].
1715

1816
You'll find some [Media3 documentation on developer.android.com][], including a
1917
[migration guide for existing ExoPlayer and MediaSession users][].

RELEASENOTES.md

Lines changed: 101 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,101 @@
1-
Release notes
1+
# Release notes
2+
3+
### 1.0.0-rc01 (2023-02-16)
4+
5+
This release corresponds to the
6+
[ExoPlayer 2.18.3 release](https://github.com/google/ExoPlayer/releases/tag/r2.18.3).
7+
8+
* Core library:
9+
* Tweak the renderer's decoder ordering logic to uphold the
10+
`MediaCodecSelector`'s preferences, even if a decoder reports it may not
11+
be able to play the media performantly. For example with default
12+
selector, hardware decoder with only functional support will be
13+
preferred over software decoder that fully supports the format
14+
([#10604](https://github.com/google/ExoPlayer/issues/10604)).
15+
* Add `ExoPlayer.Builder.setPlaybackLooper` that sets a pre-existing
16+
playback thread for a new ExoPlayer instance.
17+
* Allow download manager helpers to be cleared
18+
([#10776](https://github.com/google/ExoPlayer/issues/10776)).
19+
* Add parameter to `BasePlayer.seekTo` to also indicate the command used
20+
for seeking.
21+
* Use theme when loading drawables on API 21+
22+
([#220](https://github.com/androidx/media/issues/220)).
23+
* Add `ConcatenatingMediaSource2` that allows combining multiple media
24+
items into a single window
25+
([#247](https://github.com/androidx/media/issues/247)).
26+
* Extractors:
27+
* Throw a `ParserException` instead of a `NullPointerException` if the
28+
sample table (stbl) is missing a required sample description (stsd) when
29+
parsing trak atoms.
30+
* Correctly skip samples when seeking directly to a sync frame in fMP4
31+
([#10941](https://github.com/google/ExoPlayer/issues/10941)).
32+
* Audio:
33+
* Use the compressed audio format bitrate to calculate the min buffer size
34+
for `AudioTrack` in direct playbacks (passthrough).
35+
* Text:
36+
* Fix `TextRenderer` passing an invalid (negative) index to
37+
`Subtitle.getEventTime` if a subtitle file contains no cues.
38+
* SubRip: Add support for UTF-16 files if they start with a byte order
39+
mark.
40+
* Metadata:
41+
* Parse multiple null-separated values from ID3 frames, as permitted by
42+
ID3 v2.4.
43+
* Add `MediaMetadata.mediaType` to denote the type of content or the type
44+
of folder described by the metadata.
45+
* Add `MediaMetadata.isBrowsable` as a replacement for
46+
`MediaMetadata.folderType`. The folder type will be deprecated in the
47+
next release.
48+
* DASH:
49+
* Add full parsing for image adaptation sets, including tile counts
50+
([#3752](https://github.com/google/ExoPlayer/issues/3752)).
51+
* UI:
52+
* Fix the deprecated
53+
`PlayerView.setControllerVisibilityListener(PlayerControlView.VisibilityListener)`
54+
to ensure visibility changes are passed to the registered listener
55+
([#229](https://github.com/androidx/media/issues/229)).
56+
* Fix the ordering of the center player controls in `PlayerView` when
57+
using a right-to-left (RTL) layout
58+
([#227](https://github.com/androidx/media/issues/227)).
59+
* Session:
60+
* Add abstract `SimpleBasePlayer` to help implement the `Player` interface
61+
for custom players.
62+
* Add helper method to convert platform session token to Media3
63+
`SessionToken` ([#171](https://github.com/androidx/media/issues/171)).
64+
* Use `onMediaMetadataChanged` to trigger updates of the platform media
65+
session ([#219](https://github.com/androidx/media/issues/219)).
66+
* Add the media session as an argument of `getMediaButtons()` of the
67+
`DefaultMediaNotificationProvider` and use immutable lists for clarity
68+
([#216](https://github.com/androidx/media/issues/216)).
69+
* Add `onSetMediaItems` callback listener to provide means to modify/set
70+
`MediaItem` list, starting index and position by session before setting
71+
onto Player ([#156](https://github.com/androidx/media/issues/156)).
72+
* Avoid double tap detection for non-Bluetooth media button events
73+
([#233](https://github.com/androidx/media/issues/233)).
74+
* Make `QueueTimeline` more robust in case of a shady legacy session state
75+
([#241](https://github.com/androidx/media/issues/241)).
76+
* Metadata:
77+
* Parse multiple null-separated values from ID3 frames, as permitted by
78+
ID3 v2.4.
79+
* Add `MediaMetadata.mediaType` to denote the type of content or the type
80+
of folder described by the metadata.
81+
* Add `MediaMetadata.isBrowsable` as a replacement for
82+
`MediaMetadata.folderType`. The folder type will be deprecated in the
83+
next release.
84+
* Cast extension:
85+
* Bump Cast SDK version to 21.2.0.
86+
* IMA extension:
87+
* Remove player listener of the `ImaServerSideAdInsertionMediaSource` on
88+
the application thread to avoid threading issues.
89+
* Add a property `focusSkipButtonWhenAvailable` to the
90+
`ImaServerSideAdInsertionMediaSource.AdsLoader.Builder` to request
91+
focusing the skip button on TV devices and set it to true by default.
92+
* Add a method `focusSkipButton()` to the
93+
`ImaServerSideAdInsertionMediaSource.AdsLoader` to programmatically
94+
request to focus the skip button.
95+
* Bump IMA SDK version to 3.29.0.
96+
* Demo app:
97+
* Request notification permission for download notifications at runtime
98+
([#10884](https://github.com/google/ExoPlayer/issues/10884)).
299

3100
### 1.0.0-beta03 (2022-11-22)
4101

@@ -259,15 +356,15 @@ This release corresponds to the
259356
* Query the platform (API 29+) or assume the audio encoding channel count
260357
for audio passthrough when the format audio channel count is unset,
261358
which occurs with HLS chunkless preparation
262-
([10204](https://github.com/google/ExoPlayer/issues/10204)).
359+
([#10204](https://github.com/google/ExoPlayer/issues/10204)).
263360
* Configure `AudioTrack` with channel mask
264361
`AudioFormat.CHANNEL_OUT_7POINT1POINT4` if the decoder outputs 12
265362
channel PCM audio
266-
([#10322](#https://github.com/google/ExoPlayer/pull/10322).
363+
([#10322](#https://github.com/google/ExoPlayer/pull/10322)).
267364
* DRM
268365
* Ensure the DRM session is always correctly updated when seeking
269366
immediately after a format change
270-
([10274](https://github.com/google/ExoPlayer/issues/10274)).
367+
([#10274](https://github.com/google/ExoPlayer/issues/10274)).
271368
* Text:
272369
* Change `Player.getCurrentCues()` to return `CueGroup` instead of
273370
`List<Cue>`.

constants.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414
project.ext {
15-
releaseVersion = '1.0.0-beta03'
16-
releaseVersionCode = 1_000_000_1_03
15+
releaseVersion = '1.0.0-rc01'
16+
releaseVersionCode = 1_000_000_2_01
1717
minSdkVersion = 16
1818
appTargetSdkVersion = 33
1919
// API version before restricting local file access.

demos/main/src/main/AndroidManifest.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
2424
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
2525
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
26+
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
2627

2728
<uses-feature android:name="android.software.leanback" android:required="false"/>
2829
<uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
@@ -35,6 +36,7 @@
3536
android:largeHeap="true"
3637
android:allowBackup="false"
3738
android:requestLegacyExternalStorage="true"
39+
android:supportsRtl="true"
3840
android:name="androidx.multidex.MultiDexApplication"
3941
tools:targetApi="29">
4042

demos/main/src/main/java/androidx/media3/demo/main/SampleChooserActivity.java

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static com.google.common.base.Preconditions.checkNotNull;
2020
import static com.google.common.base.Preconditions.checkState;
2121

22+
import android.Manifest;
2223
import android.content.Context;
2324
import android.content.Intent;
2425
import android.content.SharedPreferences;
@@ -41,8 +42,10 @@
4142
import android.widget.ImageButton;
4243
import android.widget.TextView;
4344
import android.widget.Toast;
45+
import androidx.annotation.DoNotInline;
4446
import androidx.annotation.Nullable;
4547
import androidx.annotation.OptIn;
48+
import androidx.annotation.RequiresApi;
4649
import androidx.appcompat.app.AppCompatActivity;
4750
import androidx.media3.common.MediaItem;
4851
import androidx.media3.common.MediaItem.ClippingConfiguration;
@@ -76,13 +79,16 @@ public class SampleChooserActivity extends AppCompatActivity
7679
private static final String TAG = "SampleChooserActivity";
7780
private static final String GROUP_POSITION_PREFERENCE_KEY = "sample_chooser_group_position";
7881
private static final String CHILD_POSITION_PREFERENCE_KEY = "sample_chooser_child_position";
82+
private static final int POST_NOTIFICATION_PERMISSION_REQUEST_CODE = 100;
7983

8084
private String[] uris;
8185
private boolean useExtensionRenderers;
8286
private DownloadTracker downloadTracker;
8387
private SampleAdapter sampleAdapter;
8488
private MenuItem preferExtensionDecodersMenuItem;
8589
private ExpandableListView sampleListView;
90+
@Nullable private MediaItem downloadMediaItemWaitingForNotificationPermission;
91+
private boolean notificationPermissionToastShown;
8692

8793
@Override
8894
public void onCreate(Bundle savedInstanceState) {
@@ -172,12 +178,34 @@ public void onDownloadsChanged() {
172178
public void onRequestPermissionsResult(
173179
int requestCode, String[] permissions, int[] grantResults) {
174180
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
181+
if (requestCode == POST_NOTIFICATION_PERMISSION_REQUEST_CODE) {
182+
handlePostNotificationPermissionGrantResults(grantResults);
183+
} else {
184+
handleExternalStoragePermissionGrantResults(grantResults);
185+
}
186+
}
187+
188+
private void handlePostNotificationPermissionGrantResults(int[] grantResults) {
189+
if (!notificationPermissionToastShown
190+
&& (grantResults.length == 0 || grantResults[0] != PackageManager.PERMISSION_GRANTED)) {
191+
Toast.makeText(
192+
getApplicationContext(), R.string.post_notification_not_granted, Toast.LENGTH_LONG)
193+
.show();
194+
notificationPermissionToastShown = true;
195+
}
196+
if (downloadMediaItemWaitingForNotificationPermission != null) {
197+
// Download with or without permission to post notifications.
198+
toggleDownload(downloadMediaItemWaitingForNotificationPermission);
199+
downloadMediaItemWaitingForNotificationPermission = null;
200+
}
201+
}
202+
203+
private void handleExternalStoragePermissionGrantResults(int[] grantResults) {
175204
if (grantResults.length == 0) {
176205
// Empty results are triggered if a permission is requested while another request was already
177206
// pending and can be safely ignored in this case.
178207
return;
179-
}
180-
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
208+
} else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
181209
loadSample();
182210
} else {
183211
Toast.makeText(getApplicationContext(), R.string.sample_list_load_error, Toast.LENGTH_LONG)
@@ -244,15 +272,26 @@ private void onSampleDownloadButtonClicked(PlaylistHolder playlistHolder) {
244272
if (downloadUnsupportedStringId != 0) {
245273
Toast.makeText(getApplicationContext(), downloadUnsupportedStringId, Toast.LENGTH_LONG)
246274
.show();
275+
} else if (!notificationPermissionToastShown
276+
&& Util.SDK_INT >= 33
277+
&& checkSelfPermission(Api33.getPostNotificationPermissionString())
278+
!= PackageManager.PERMISSION_GRANTED) {
279+
downloadMediaItemWaitingForNotificationPermission = playlistHolder.mediaItems.get(0);
280+
requestPermissions(
281+
new String[] {Api33.getPostNotificationPermissionString()},
282+
/* requestCode= */ POST_NOTIFICATION_PERMISSION_REQUEST_CODE);
247283
} else {
248-
RenderersFactory renderersFactory =
249-
DemoUtil.buildRenderersFactory(
250-
/* context= */ this, isNonNullAndChecked(preferExtensionDecodersMenuItem));
251-
downloadTracker.toggleDownload(
252-
getSupportFragmentManager(), playlistHolder.mediaItems.get(0), renderersFactory);
284+
toggleDownload(playlistHolder.mediaItems.get(0));
253285
}
254286
}
255287

288+
private void toggleDownload(MediaItem mediaItem) {
289+
RenderersFactory renderersFactory =
290+
DemoUtil.buildRenderersFactory(
291+
/* context= */ this, isNonNullAndChecked(preferExtensionDecodersMenuItem));
292+
downloadTracker.toggleDownload(getSupportFragmentManager(), mediaItem, renderersFactory);
293+
}
294+
256295
private int getDownloadUnsupportedStringId(PlaylistHolder playlistHolder) {
257296
if (playlistHolder.mediaItems.size() > 1) {
258297
return R.string.download_playlist_unsupported;
@@ -630,4 +669,13 @@ public PlaylistGroup(String title) {
630669
this.playlists = new ArrayList<>();
631670
}
632671
}
672+
673+
@RequiresApi(33)
674+
private static class Api33 {
675+
676+
@DoNotInline
677+
public static String getPostNotificationPermissionString() {
678+
return Manifest.permission.POST_NOTIFICATIONS;
679+
}
680+
}
633681
}

demos/main/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545

4646
<string name="sample_list_load_error">One or more sample lists failed to load</string>
4747

48+
<string name="post_notification_not_granted">Notifications suppressed. Grant permission to see download notifications.</string>
49+
4850
<string name="download_start_error">Failed to start download</string>
4951

5052
<string name="download_start_error_offline_license">Failed to obtain offline license</string>

demos/session/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ android {
3131
versionName project.ext.releaseVersion
3232
versionCode project.ext.releaseVersionCode
3333
minSdkVersion project.ext.minSdkVersion
34-
targetSdkVersion project.ext.targetSdkVersion
34+
targetSdkVersion project.ext.appTargetSdkVersion
3535
multiDexEnabled true
3636
}
3737

demos/session/src/main/java/androidx/media3/demo/session/MainActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import com.google.common.util.concurrent.ListenableFuture
3838
class MainActivity : AppCompatActivity() {
3939
private lateinit var browserFuture: ListenableFuture<MediaBrowser>
4040
private val browser: MediaBrowser?
41-
get() = if (browserFuture.isDone) browserFuture.get() else null
41+
get() = if (browserFuture.isDone && !browserFuture.isCancelled) browserFuture.get() else null
4242

4343
private lateinit var mediaListAdapter: FolderMediaItemArrayAdapter
4444
private lateinit var mediaListView: ListView

0 commit comments

Comments
 (0)