Do not specify export flags for protected system broadcasts.

Protected system broadcasts should not specify the export flag.
Marking them as NOT_EXPORTED breaks sticky broadcasts in some
cases.

Issue: google/ExoPlayer#10970

PiperOrigin-RevId: 512020154
(cherry picked from commit 93e117928c157ef338faa46dea25ee114f18d3eb)
This commit is contained in:
tonihei 2023-02-24 10:42:37 +00:00
parent 5ab4223f2a
commit a09bb70053
9 changed files with 100 additions and 77 deletions

View File

@ -1,11 +1,76 @@
# Release notes # Release notes
### Unreleased changes
* Core library:
* Add suppression reason for unsuitable audio route and play when ready
change reason for suppressed too long.
([#15](https://github.com/androidx/media/issues/15)).
* Make the maximum difference of the start time of two segments to be
merged configurable in `SegmentDownloader` and subclasses
([#248](https://github.com/androidx/media/pull/248)).
* Add `ExoPlayer.setVideoEffects()` for using `Effect` during video
playback.
* Update `SampleQueue` to store `sourceId` as a `long` rather than an
`int`. This changes the signatures of public methods
`SampleQueue.sourceId` and `SampleQueue.peekSourceId`.
* Fix network type detection on API 33
([#10970](https://github.com/google/ExoPlayer/issues/10970)).
* Make the maximum difference of the start time of two segments to be
merged configurable in `SegmentDownloader` and subclasses
([#248](https://github.com/androidx/media/pull/248)).
* Extractors:
* Fix `NullPointerException` when calling `ExoPlayer.isTunnelingEnabled`
([#10977](https://github.com/google/ExoPlayer/issues/10977)).
* Audio:
* Fix bug where some playbacks fail when tunneling is enabled and
`AudioProcessors` are active, e.g. for gapless trimming
([#10847](https://github.com/google/ExoPlayer/issues/10847)).
* Encapsulate Opus frames in Ogg packets in direct playbacks (offload).
* Video:
* Map HEVC HDR10 format to `HEVCProfileMain10HDR10` instead of
`HEVCProfileMain10`.
* DASH:
* Add full parsing for image adaptation sets, including tile counts
([#3752](https://github.com/google/ExoPlayer/issues/3752)).
* RTSP:
* Catch the IllegalArgumentException thrown in parsing of invalid RTSP
Describe response messages
([#10971](https://github.com/google/ExoPlayer/issues/10971)).
* Session:
* Fix a bug where notification play/pause button doesn't update with
player state ([#192](https://github.com/androidx/media/issues/192)).
* Fix a bug where notification play/pause button doesn't update with
player state ([#192](https://github.com/androidx/media/issues/192)).
* RTSP:
* Catch the IllegalArgumentException thrown in parsing of invalid RTSP
Describe response messages
([#10971](https://github.com/google/ExoPlayer/issues/10971)).
* Metadata:
* Parse multiple null-separated values from ID3 frames, as permitted by
ID3 v2.4.
* Add `MediaMetadata.mediaType` to denote the type of content or the type
of folder described by the metadata.
* Add `MediaMetadata.isBrowsable` as a replacement for
`MediaMetadata.folderType`. The folder type will be deprecated in the
next release.
* Transformer:
* Remove `Transformer.Builder.setMediaSourceFactory(MediaSource.Factory)`.
Use `ExoPlayerAssetLoader.Factory(MediaSource.Factory)` and
`Transformer.Builder.setAssetLoaderFactory(AssetLoader.Factory)`
instead.
* Remove `Transformer.startTransformation(MediaItem,
ParcelFileDescriptor)`.
* Remove deprecated symbols:
* Remove `DefaultAudioSink` constructors, use `DefaultAudioSink.Builder`
instead.
### 1.0.0-rc01 (2023-02-16) ### 1.0.0-rc01 (2023-02-16)
This release corresponds to the This release corresponds to the
[ExoPlayer 2.18.3 release](https://github.com/google/ExoPlayer/releases/tag/r2.18.3). [ExoPlayer 2.18.3 release](https://github.com/google/ExoPlayer/releases/tag/r2.18.3).
* Core library: * Core library:
* Tweak the renderer's decoder ordering logic to uphold the * Tweak the renderer's decoder ordering logic to uphold the
`MediaCodecSelector`'s preferences, even if a decoder reports it may not `MediaCodecSelector`'s preferences, even if a decoder reports it may not
be able to play the media performantly. For example with default be able to play the media performantly. For example with default
@ -20,35 +85,29 @@ This release corresponds to the
for seeking. for seeking.
* Use theme when loading drawables on API 21+ * Use theme when loading drawables on API 21+
([#220](https://github.com/androidx/media/issues/220)). ([#220](https://github.com/androidx/media/issues/220)).
* Make the maximum difference of the start time of two segments to be
merged configurable in `SegmentDownloader` and subclasses
([#248](https://github.com/androidx/media/pull/248)).
* Add `ConcatenatingMediaSource2` that allows combining multiple media * Add `ConcatenatingMediaSource2` that allows combining multiple media
items into a single window items into a single window
([#247](https://github.com/androidx/media/issues/247)). ([#247](https://github.com/androidx/media/issues/247)).
* Extractors: * Extractors:
* Throw a `ParserException` instead of a `NullPointerException` if the * Throw a `ParserException` instead of a `NullPointerException` if the
sample table (stbl) is missing a required sample description (stsd) when sample table (stbl) is missing a required sample description (stsd) when
parsing trak atoms. parsing trak atoms.
* Correctly skip samples when seeking directly to a sync frame in fMP4 * Correctly skip samples when seeking directly to a sync frame in fMP4
([#10941](https://github.com/google/ExoPlayer/issues/10941)). ([#10941](https://github.com/google/ExoPlayer/issues/10941)).
* Fix `NullPointerException` when calling `ExoPlayer.isTunnelingEnabled` * Fix `NullPointerException` when calling `ExoPlayer.isTunnelingEnabled`
([#10977](https://github.com/google/ExoPlayer/issues/10977)). ([#10977](https://github.com/google/ExoPlayer/issues/10977)).
* Audio: * Audio:
* Use the compressed audio format bitrate to calculate the min buffer size * Use the compressed audio format bitrate to calculate the min buffer size
for `AudioTrack` in direct playbacks (passthrough). for `AudioTrack` in direct playbacks (passthrough).
* Fix bug where some playbacks fail when tunneling is enabled and * Fix bug where some playbacks fail when tunneling is enabled and
`AudioProcessors` are active, e.g. for gapless trimming `AudioProcessors` are active, e.g. for gapless trimming
([#10847](https://github.com/google/ExoPlayer/issues/10847)). ([#10847](https://github.com/google/ExoPlayer/issues/10847)).
* Video: * Text:
* Map HEVC HDR10 format to `HEVCProfileMain10HDR10` instead of
`HEVCProfileMain10`.
* Text:
* Fix `TextRenderer` passing an invalid (negative) index to * Fix `TextRenderer` passing an invalid (negative) index to
`Subtitle.getEventTime` if a subtitle file contains no cues. `Subtitle.getEventTime` if a subtitle file contains no cues.
* SubRip: Add support for UTF-16 files if they start with a byte order * SubRip: Add support for UTF-16 files if they start with a byte order
mark. mark.
* Metadata: * Metadata:
* Parse multiple null-separated values from ID3 frames, as permitted by * Parse multiple null-separated values from ID3 frames, as permitted by
ID3 v2.4. ID3 v2.4.
* Add `MediaMetadata.mediaType` to denote the type of content or the type * Add `MediaMetadata.mediaType` to denote the type of content or the type
@ -56,10 +115,10 @@ This release corresponds to the
* Add `MediaMetadata.isBrowsable` as a replacement for * Add `MediaMetadata.isBrowsable` as a replacement for
`MediaMetadata.folderType`. The folder type will be deprecated in the `MediaMetadata.folderType`. The folder type will be deprecated in the
next release. next release.
* DASH: * DASH:
* Add full parsing for image adaptation sets, including tile counts * Add full parsing for image adaptation sets, including tile counts
([#3752](https://github.com/google/ExoPlayer/issues/3752)). ([#3752](https://github.com/google/ExoPlayer/issues/3752)).
* UI: * UI:
* Fix the deprecated * Fix the deprecated
`PlayerView.setControllerVisibilityListener(PlayerControlView.VisibilityListener)` `PlayerView.setControllerVisibilityListener(PlayerControlView.VisibilityListener)`
to ensure visibility changes are passed to the registered listener to ensure visibility changes are passed to the registered listener
@ -67,7 +126,7 @@ This release corresponds to the
* Fix the ordering of the center player controls in `PlayerView` when * Fix the ordering of the center player controls in `PlayerView` when
using a right-to-left (RTL) layout using a right-to-left (RTL) layout
([#227](https://github.com/androidx/media/issues/227)). ([#227](https://github.com/androidx/media/issues/227)).
* Session: * Session:
* Add abstract `SimpleBasePlayer` to help implement the `Player` interface * Add abstract `SimpleBasePlayer` to help implement the `Player` interface
for custom players. for custom players.
* Add helper method to convert platform session token to Media3 * Add helper method to convert platform session token to Media3
@ -84,26 +143,12 @@ This release corresponds to the
([#233](https://github.com/androidx/media/issues/233)). ([#233](https://github.com/androidx/media/issues/233)).
* Make `QueueTimeline` more robust in case of a shady legacy session state * Make `QueueTimeline` more robust in case of a shady legacy session state
([#241](https://github.com/androidx/media/issues/241)). ([#241](https://github.com/androidx/media/issues/241)).
* Fix a bug where notification play/pause button doesn't update with * Cast extension:
player state ([#192](https://github.com/androidx/media/issues/192)).
* RTSP:
* Catch the IllegalArgumentException thrown in parsing of invalid RTSP
Describe response messages
([#10971](https://github.com/google/ExoPlayer/issues/10971)).
* Metadata:
* Parse multiple null-separated values from ID3 frames, as permitted by
ID3 v2.4.
* Add `MediaMetadata.mediaType` to denote the type of content or the type
of folder described by the metadata.
* Add `MediaMetadata.isBrowsable` as a replacement for
`MediaMetadata.folderType`. The folder type will be deprecated in the
next release.
* Cast extension:
* Bump Cast SDK version to 21.2.0. * Bump Cast SDK version to 21.2.0.
* IMA extension: * IMA extension:
* Map `PLAYER_STATE_LOADING` to `STATE_BUFFERING` * Map `PLAYER_STATE_LOADING` to `STATE_BUFFERING`
([#245](\(https://github.com/androidx/media/issues/245\)). ([#245](\(https://github.com/androidx/media/issues/245\)).
* IMA extension * IMA extension
* Remove player listener of the `ImaServerSideAdInsertionMediaSource` on * Remove player listener of the `ImaServerSideAdInsertionMediaSource` on
the application thread to avoid threading issues. the application thread to avoid threading issues.
* Add a property `focusSkipButtonWhenAvailable` to the * Add a property `focusSkipButtonWhenAvailable` to the
@ -115,7 +160,7 @@ This release corresponds to the
* Fix a bug which prevented playback from starting for a DAI stream * Fix a bug which prevented playback from starting for a DAI stream
without any ads. without any ads.
* Bump IMA SDK version to 3.29.0. * Bump IMA SDK version to 3.29.0.
* Demo app: * Demo app:
* Request notification permission for download notifications at runtime * Request notification permission for download notifications at runtime
([#10884](https://github.com/google/ExoPlayer/issues/10884)). ([#10884](https://github.com/google/ExoPlayer/issues/10884)).

View File

@ -94,7 +94,7 @@ public final class NetworkTypeObserver {
networkType = C.NETWORK_TYPE_UNKNOWN; networkType = C.NETWORK_TYPE_UNKNOWN;
IntentFilter filter = new IntentFilter(); IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
Util.registerReceiverNotExported(context, new Receiver(), filter); context.registerReceiver(new Receiver(), filter);
} }
/** /**

View File

@ -206,6 +206,10 @@ public final class Util {
* apps. This will be enforced by specifying {@link Context#RECEIVER_NOT_EXPORTED} if {@link * apps. This will be enforced by specifying {@link Context#RECEIVER_NOT_EXPORTED} if {@link
* #SDK_INT} is 33 or above. * #SDK_INT} is 33 or above.
* *
* <p>Do not use this method if registering a receiver for a <a
* href="https://android.googlesource.com/platform/frameworks/base/+/master/core/res/AndroidManifest.xml">protected
* system broadcast</a>.
*
* @param context The context on which {@link Context#registerReceiver} will be called. * @param context The context on which {@link Context#registerReceiver} will be called.
* @param receiver The {@link BroadcastReceiver} to register. This value may be null. * @param receiver The {@link BroadcastReceiver} to register. This value may be null.
* @param filter Selects the Intent broadcasts to be received. * @param filter Selects the Intent broadcasts to be received.
@ -222,33 +226,6 @@ public final class Util {
} }
} }
/**
* Registers a {@link BroadcastReceiver} that's not intended to receive broadcasts from other
* apps. This will be enforced by specifying {@link Context#RECEIVER_NOT_EXPORTED} if {@link
* #SDK_INT} is 33 or above.
*
* @param context The context on which {@link Context#registerReceiver} will be called.
* @param receiver The {@link BroadcastReceiver} to register. This value may be null.
* @param filter Selects the Intent broadcasts to be received.
* @param handler Handler identifying the thread that will receive the Intent.
* @return The first sticky intent found that matches {@code filter}, or null if there are none.
*/
@UnstableApi
@Nullable
public static Intent registerReceiverNotExported(
Context context, BroadcastReceiver receiver, IntentFilter filter, Handler handler) {
if (SDK_INT < 33) {
return context.registerReceiver(receiver, filter, /* broadcastPermission= */ null, handler);
} else {
return context.registerReceiver(
receiver,
filter,
/* broadcastPermission= */ null,
handler,
Context.RECEIVER_NOT_EXPORTED);
}
}
/** /**
* Calls {@link Context#startForegroundService(Intent)} if {@link #SDK_INT} is 26 or higher, or * Calls {@link Context#startForegroundService(Intent)} if {@link #SDK_INT} is 26 or higher, or
* {@link Context#startService(Intent)} otherwise. * {@link Context#startService(Intent)} otherwise.

View File

@ -21,7 +21,6 @@ import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.media.AudioManager; import android.media.AudioManager;
import android.os.Handler; import android.os.Handler;
import androidx.media3.common.util.Util;
/* package */ final class AudioBecomingNoisyManager { /* package */ final class AudioBecomingNoisyManager {
@ -47,8 +46,8 @@ import androidx.media3.common.util.Util;
*/ */
public void setEnabled(boolean enabled) { public void setEnabled(boolean enabled) {
if (enabled && !receiverRegistered) { if (enabled && !receiverRegistered) {
Util.registerReceiverNotExported( context.registerReceiver(
context, receiver, new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY)); receiver, new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
receiverRegistered = true; receiverRegistered = true;
} else if (!enabled && receiverRegistered) { } else if (!enabled && receiverRegistered) {
context.unregisterReceiver(receiver); context.unregisterReceiver(receiver);

View File

@ -75,7 +75,7 @@ import androidx.media3.common.util.Util;
VolumeChangeReceiver receiver = new VolumeChangeReceiver(); VolumeChangeReceiver receiver = new VolumeChangeReceiver();
IntentFilter filter = new IntentFilter(VOLUME_CHANGED_ACTION); IntentFilter filter = new IntentFilter(VOLUME_CHANGED_ACTION);
try { try {
Util.registerReceiverNotExported(applicationContext, receiver, filter); applicationContext.registerReceiver(receiver, filter);
this.receiver = receiver; this.receiver = receiver;
} catch (RuntimeException e) { } catch (RuntimeException e) {
Log.w(TAG, "Error registering stream volume receiver", e); Log.w(TAG, "Error registering stream volume receiver", e);

View File

@ -88,8 +88,8 @@ public final class AudioCapabilities {
@SuppressWarnings("InlinedApi") @SuppressWarnings("InlinedApi")
public static AudioCapabilities getCapabilities(Context context) { public static AudioCapabilities getCapabilities(Context context) {
Intent intent = Intent intent =
Util.registerReceiverNotExported( context.registerReceiver(
context, /* receiver= */ null, new IntentFilter(AudioManager.ACTION_HDMI_AUDIO_PLUG)); /* receiver= */ null, new IntentFilter(AudioManager.ACTION_HDMI_AUDIO_PLUG));
return getCapabilities(context, intent); return getCapabilities(context, intent);
} }

View File

@ -93,7 +93,9 @@ public final class AudioCapabilitiesReceiver {
@Nullable Intent stickyIntent = null; @Nullable Intent stickyIntent = null;
if (receiver != null) { if (receiver != null) {
IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_HDMI_AUDIO_PLUG); IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_HDMI_AUDIO_PLUG);
stickyIntent = Util.registerReceiverNotExported(context, receiver, intentFilter, handler); stickyIntent =
context.registerReceiver(
receiver, intentFilter, /* broadcastPermission= */ null, handler);
} }
audioCapabilities = AudioCapabilities.getCapabilities(context, stickyIntent); audioCapabilities = AudioCapabilities.getCapabilities(context, stickyIntent);
return audioCapabilities; return audioCapabilities;

View File

@ -184,8 +184,8 @@ public final class Requirements implements Parcelable {
private boolean isDeviceCharging(Context context) { private boolean isDeviceCharging(Context context) {
@Nullable @Nullable
Intent batteryStatus = Intent batteryStatus =
Util.registerReceiverNotExported( context.registerReceiver(
context, /* receiver= */ null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); /* receiver= */ null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
if (batteryStatus == null) { if (batteryStatus == null) {
return false; return false;
} }
@ -203,8 +203,8 @@ public final class Requirements implements Parcelable {
} }
private boolean isStorageNotLow(Context context) { private boolean isStorageNotLow(Context context) {
return Util.registerReceiverNotExported( return context.registerReceiver(
context, /* receiver= */ null, new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW)) /* receiver= */ null, new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW))
== null; == null;
} }

View File

@ -111,7 +111,7 @@ public final class RequirementsWatcher {
filter.addAction(Intent.ACTION_DEVICE_STORAGE_OK); filter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
} }
receiver = new DeviceStatusChangeReceiver(); receiver = new DeviceStatusChangeReceiver();
Util.registerReceiverNotExported(context, receiver, filter, handler); context.registerReceiver(receiver, filter, /* broadcastPermission= */ null, handler);
return notMetRequirements; return notMetRequirements;
} }