diff --git a/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java b/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java index ac113f3ab8..246c69e8da 100644 --- a/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java +++ b/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java @@ -24,6 +24,7 @@ import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.TextureView; +import androidx.annotation.IntRange; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import com.google.android.exoplayer2.BasePlayer; @@ -190,8 +191,8 @@ public final class CastPlayer extends BasePlayer { public CastPlayer( CastContext castContext, MediaItemConverter mediaItemConverter, - long seekBackIncrementMs, - long seekForwardIncrementMs) { + @IntRange(from = 1) long seekBackIncrementMs, + @IntRange(from = 1) long seekForwardIncrementMs) { checkArgument(seekBackIncrementMs > 0 && seekForwardIncrementMs > 0); this.castContext = castContext; this.mediaItemConverter = mediaItemConverter; diff --git a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java index f77a5a0aa6..7f52005b68 100644 --- a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java +++ b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java @@ -26,6 +26,7 @@ import android.content.Context; import android.os.Looper; import android.view.View; import android.view.ViewGroup; +import androidx.annotation.IntRange; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import com.google.ads.interactivemedia.v3.api.AdDisplayContainer; @@ -276,7 +277,7 @@ public final class ImaAdsLoader implements Player.Listener, AdsLoader { * @return This builder, for convenience. * @see AdsRequest#setVastLoadTimeout(float) */ - public Builder setVastLoadTimeoutMs(int vastLoadTimeoutMs) { + public Builder setVastLoadTimeoutMs(@IntRange(from = 1) int vastLoadTimeoutMs) { checkArgument(vastLoadTimeoutMs > 0); this.vastLoadTimeoutMs = vastLoadTimeoutMs; return this; @@ -289,7 +290,7 @@ public final class ImaAdsLoader implements Player.Listener, AdsLoader { * @return This builder, for convenience. * @see AdsRenderingSettings#setLoadVideoTimeout(int) */ - public Builder setMediaLoadTimeoutMs(int mediaLoadTimeoutMs) { + public Builder setMediaLoadTimeoutMs(@IntRange(from = 1) int mediaLoadTimeoutMs) { checkArgument(mediaLoadTimeoutMs > 0); this.mediaLoadTimeoutMs = mediaLoadTimeoutMs; return this; @@ -302,7 +303,7 @@ public final class ImaAdsLoader implements Player.Listener, AdsLoader { * @return This builder, for convenience. * @see AdsRenderingSettings#setBitrateKbps(int) */ - public Builder setMaxMediaBitrate(int bitrate) { + public Builder setMaxMediaBitrate(@IntRange(from = 1) int bitrate) { checkArgument(bitrate > 0); this.mediaBitrate = bitrate; return this; diff --git a/library/common/src/main/java/com/google/android/exoplayer2/MediaItem.java b/library/common/src/main/java/com/google/android/exoplayer2/MediaItem.java index e8373532a1..568a9b97ca 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/MediaItem.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/MediaItem.java @@ -21,6 +21,7 @@ import static com.google.android.exoplayer2.util.Assertions.checkState; import android.net.Uri; import android.os.Bundle; import androidx.annotation.IntDef; +import androidx.annotation.IntRange; import androidx.annotation.Nullable; import com.google.android.exoplayer2.offline.StreamKey; import com.google.android.exoplayer2.util.Assertions; @@ -197,7 +198,7 @@ public final class MediaItem implements Bundleable { * Sets the optional start position in milliseconds which must be a value larger than or equal * to zero (Default: 0). */ - public Builder setClipStartPositionMs(long startPositionMs) { + public Builder setClipStartPositionMs(@IntRange(from = 0) long startPositionMs) { Assertions.checkArgument(startPositionMs >= 0); this.clipStartPositionMs = startPositionMs; return this; diff --git a/library/common/src/main/java/com/google/android/exoplayer2/PlaybackParameters.java b/library/common/src/main/java/com/google/android/exoplayer2/PlaybackParameters.java index 806bf11064..8034944e17 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/PlaybackParameters.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/PlaybackParameters.java @@ -17,6 +17,7 @@ package com.google.android.exoplayer2; import android.os.Bundle; import androidx.annotation.CheckResult; +import androidx.annotation.FloatRange; import androidx.annotation.IntDef; import androidx.annotation.Nullable; import com.google.android.exoplayer2.util.Assertions; @@ -57,7 +58,9 @@ public final class PlaybackParameters implements Bundleable { * zero. Useful values are {@code 1} (to time-stretch audio) and the same value as passed in * as the {@code speed} (to resample audio, which is useful for slow-motion videos). */ - public PlaybackParameters(float speed, float pitch) { + public PlaybackParameters( + @FloatRange(from = 0, fromInclusive = false) float speed, + @FloatRange(from = 0, fromInclusive = false) float pitch) { Assertions.checkArgument(speed > 0); Assertions.checkArgument(pitch > 0); this.speed = speed; @@ -79,11 +82,11 @@ public final class PlaybackParameters implements Bundleable { /** * Returns a copy with the given speed. * - * @param speed The new speed. + * @param speed The new speed. Must be greater than zero. * @return The copied playback parameters. */ @CheckResult - public PlaybackParameters withSpeed(float speed) { + public PlaybackParameters withSpeed(@FloatRange(from = 0, fromInclusive = false) float speed) { return new PlaybackParameters(speed, pitch); } diff --git a/library/common/src/main/java/com/google/android/exoplayer2/Player.java b/library/common/src/main/java/com/google/android/exoplayer2/Player.java index c8d5ad88c5..591f67288f 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/Player.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/Player.java @@ -21,7 +21,9 @@ import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.TextureView; +import androidx.annotation.FloatRange; import androidx.annotation.IntDef; +import androidx.annotation.IntRange; import androidx.annotation.Nullable; import com.google.android.exoplayer2.audio.AudioAttributes; import com.google.android.exoplayer2.metadata.Metadata; @@ -429,7 +431,7 @@ public interface Player { * @throws IndexOutOfBoundsException If index is outside the allowed range. */ @Event - public int get(int index) { + public int get(@IntRange(from = 0) int index) { return flags.get(index); } @@ -800,7 +802,7 @@ public interface Player { * @throws IndexOutOfBoundsException If index is outside the allowed range. */ @Command - public int get(int index) { + public int get(@IntRange(from = 0) int index) { return flags.get(index); } @@ -1498,7 +1500,7 @@ public interface Player { * the playlist, the media item is added to the end of the playlist. * @param mediaItem The {@link MediaItem} to add. */ - void addMediaItem(int index, MediaItem mediaItem); + void addMediaItem(@IntRange(from = 0) int index, MediaItem mediaItem); /** * Adds a list of media items to the end of the playlist. @@ -1514,7 +1516,7 @@ public interface Player { * the playlist, the media items are added to the end of the playlist. * @param mediaItems The {@link MediaItem MediaItems} to add. */ - void addMediaItems(int index, List mediaItems); + void addMediaItems(@IntRange(from = 0) int index, List mediaItems); /** * Moves the media item at the current index to the new index. @@ -1523,7 +1525,7 @@ public interface Player { * @param newIndex The new index of the media item. If the new index is larger than the size of * the playlist the item is moved to the end of the playlist. */ - void moveMediaItem(int currentIndex, int newIndex); + void moveMediaItem(@IntRange(from = 0) int currentIndex, @IntRange(from = 0) int newIndex); /** * Moves the media item range to the new index. @@ -1534,14 +1536,17 @@ public interface Player { * than the size of the remaining playlist after removing the range, the range is moved to the * end of the playlist. */ - void moveMediaItems(int fromIndex, int toIndex, int newIndex); + void moveMediaItems( + @IntRange(from = 0) int fromIndex, + @IntRange(from = 0) int toIndex, + @IntRange(from = 0) int newIndex); /** * Removes the media item at the given index of the playlist. * * @param index The index at which to remove the media item. */ - void removeMediaItem(int index); + void removeMediaItem(@IntRange(from = 0) int index); /** * Removes a range of media items from the playlist. @@ -1550,7 +1555,7 @@ public interface Player { * @param toIndex The index of the first item to be kept (exclusive). If the index is larger than * the size of the playlist, media items to the end of the playlist are removed. */ - void removeMediaItems(int fromIndex, int toIndex); + void removeMediaItems(@IntRange(from = 0) int fromIndex, @IntRange(from = 0) int toIndex); /** Clears the playlist. */ void clearMediaItems(); @@ -1728,7 +1733,7 @@ public interface Player { * @throws IllegalSeekPositionException If the player has a non-empty timeline and the provided * {@code windowIndex} is not within the bounds of the current timeline. */ - void seekToDefaultPosition(int windowIndex); + void seekToDefaultPosition(@IntRange(from = 0) int windowIndex); /** * Seeks to a position specified in milliseconds in the current window. @@ -1747,7 +1752,7 @@ public interface Player { * @throws IllegalSeekPositionException If the player has a non-empty timeline and the provided * {@code windowIndex} is not within the bounds of the current timeline. */ - void seekTo(int windowIndex, long positionMs); + void seekTo(@IntRange(from = 0) int windowIndex, long positionMs); /** * Returns the {@link #seekBack()} increment. @@ -1892,7 +1897,7 @@ public interface Player { * @param speed The linear factor by which playback will be sped up. Must be higher than 0. 1 is * normal speed, 2 is twice as fast, 0.5 is half normal speed... */ - void setPlaybackSpeed(float speed); + void setPlaybackSpeed(@FloatRange(from = 0, fromInclusive = false) float speed); /** * Returns the currently active playback parameters. @@ -2032,7 +2037,7 @@ public interface Player { int getMediaItemCount(); /** Returns the {@link MediaItem} at the given index. */ - MediaItem getMediaItemAt(int index); + MediaItem getMediaItemAt(@IntRange(from = 0) int index); /** * Returns the duration of the current content window or ad in milliseconds, or {@link @@ -2145,7 +2150,7 @@ public interface Player { * * @param audioVolume Linear output gain to apply to all audio channels. */ - void setVolume(float audioVolume); + void setVolume(@FloatRange(from = 0) float audioVolume); /** * Returns the audio volume, with 0 being silence and 1 being unity gain (signal unchanged). diff --git a/library/common/src/main/java/com/google/android/exoplayer2/source/ads/AdPlaybackState.java b/library/common/src/main/java/com/google/android/exoplayer2/source/ads/AdPlaybackState.java index cc6e6f1332..319b5cc12d 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/source/ads/AdPlaybackState.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/source/ads/AdPlaybackState.java @@ -23,6 +23,7 @@ import android.net.Uri; import android.os.Bundle; import androidx.annotation.CheckResult; import androidx.annotation.IntDef; +import androidx.annotation.IntRange; import androidx.annotation.Nullable; import com.google.android.exoplayer2.Bundleable; import com.google.android.exoplayer2.C; @@ -119,7 +120,7 @@ public final class AdPlaybackState implements Bundleable { * Returns the index of the next ad in the ad group that should be played after playing {@code * lastPlayedAdIndex}, or {@link #count} if no later ads should be played. */ - public int getNextAdIndexToPlay(int lastPlayedAdIndex) { + public int getNextAdIndexToPlay(@IntRange(from = 0) int lastPlayedAdIndex) { int nextAdIndexToPlay = lastPlayedAdIndex + 1; while (nextAdIndexToPlay < states.length) { if (isServerSideInserted @@ -204,7 +205,7 @@ public final class AdPlaybackState implements Bundleable { * marked as {@link #AD_STATE_AVAILABLE}. */ @CheckResult - public AdGroup withAdUri(Uri uri, int index) { + public AdGroup withAdUri(Uri uri, @IntRange(from = 0) int index) { @AdState int[] states = copyStatesWithSpaceForAdCount(this.states, index + 1); long[] durationsUs = this.durationsUs.length == states.length @@ -226,7 +227,7 @@ public final class AdPlaybackState implements Bundleable { * ad count specified later. Otherwise, {@code index} must be less than the current ad count. */ @CheckResult - public AdGroup withAdState(@AdState int state, int index) { + public AdGroup withAdState(@AdState int state, @IntRange(from = 0) int index) { checkArgument(count == C.LENGTH_UNSET || index < count); @AdState int[] states = copyStatesWithSpaceForAdCount(this.states, index + 1); checkArgument( @@ -477,7 +478,7 @@ public final class AdPlaybackState implements Bundleable { } /** Returns the specified {@link AdGroup}. */ - public AdGroup getAdGroup(int adGroupIndex) { + public AdGroup getAdGroup(@IntRange(from = 0) int adGroupIndex) { return adGroupIndex < removedAdGroupCount ? REMOVED_AD_GROUP : adGroups[adGroupIndex - removedAdGroupCount]; @@ -534,7 +535,8 @@ public final class AdPlaybackState implements Bundleable { } /** Returns whether the specified ad has been marked as in {@link #AD_STATE_ERROR}. */ - public boolean isAdInErrorState(int adGroupIndex, int adIndexInAdGroup) { + public boolean isAdInErrorState( + @IntRange(from = 0) int adGroupIndex, @IntRange(from = 0) int adIndexInAdGroup) { if (adGroupIndex >= adGroupCount) { return false; } @@ -554,7 +556,8 @@ public final class AdPlaybackState implements Bundleable { * @return The updated ad playback state. */ @CheckResult - public AdPlaybackState withAdGroupTimeUs(int adGroupIndex, long adGroupTimeUs) { + public AdPlaybackState withAdGroupTimeUs( + @IntRange(from = 0) int adGroupIndex, long adGroupTimeUs) { int adjustedIndex = adGroupIndex - removedAdGroupCount; AdGroup[] adGroups = Util.nullSafeArrayCopy(this.adGroups, this.adGroups.length); adGroups[adjustedIndex] = this.adGroups[adjustedIndex].withTimeUs(adGroupTimeUs); @@ -571,7 +574,7 @@ public final class AdPlaybackState implements Bundleable { * @return The updated ad playback state. */ @CheckResult - public AdPlaybackState withNewAdGroup(int adGroupIndex, long adGroupTimeUs) { + public AdPlaybackState withNewAdGroup(@IntRange(from = 0) int adGroupIndex, long adGroupTimeUs) { int adjustedIndex = adGroupIndex - removedAdGroupCount; AdGroup newAdGroup = new AdGroup(adGroupTimeUs); AdGroup[] adGroups = Util.nullSafeArrayAppend(this.adGroups, newAdGroup); @@ -591,7 +594,8 @@ public final class AdPlaybackState implements Bundleable { * The ad count must be greater than zero. */ @CheckResult - public AdPlaybackState withAdCount(int adGroupIndex, int adCount) { + public AdPlaybackState withAdCount( + @IntRange(from = 0) int adGroupIndex, @IntRange(from = 1) int adCount) { checkArgument(adCount > 0); int adjustedIndex = adGroupIndex - removedAdGroupCount; if (adGroups[adjustedIndex].count == adCount) { @@ -605,7 +609,8 @@ public final class AdPlaybackState implements Bundleable { /** Returns an instance with the specified ad URI. */ @CheckResult - public AdPlaybackState withAdUri(int adGroupIndex, int adIndexInAdGroup, Uri uri) { + public AdPlaybackState withAdUri( + @IntRange(from = 0) int adGroupIndex, @IntRange(from = 0) int adIndexInAdGroup, Uri uri) { int adjustedIndex = adGroupIndex - removedAdGroupCount; AdGroup[] adGroups = Util.nullSafeArrayCopy(this.adGroups, this.adGroups.length); adGroups[adjustedIndex] = adGroups[adjustedIndex].withAdUri(uri, adIndexInAdGroup); @@ -615,7 +620,8 @@ public final class AdPlaybackState implements Bundleable { /** Returns an instance with the specified ad marked as played. */ @CheckResult - public AdPlaybackState withPlayedAd(int adGroupIndex, int adIndexInAdGroup) { + public AdPlaybackState withPlayedAd( + @IntRange(from = 0) int adGroupIndex, @IntRange(from = 0) int adIndexInAdGroup) { int adjustedIndex = adGroupIndex - removedAdGroupCount; AdGroup[] adGroups = Util.nullSafeArrayCopy(this.adGroups, this.adGroups.length); adGroups[adjustedIndex] = @@ -626,7 +632,8 @@ public final class AdPlaybackState implements Bundleable { /** Returns an instance with the specified ad marked as skipped. */ @CheckResult - public AdPlaybackState withSkippedAd(int adGroupIndex, int adIndexInAdGroup) { + public AdPlaybackState withSkippedAd( + @IntRange(from = 0) int adGroupIndex, @IntRange(from = 0) int adIndexInAdGroup) { int adjustedIndex = adGroupIndex - removedAdGroupCount; AdGroup[] adGroups = Util.nullSafeArrayCopy(this.adGroups, this.adGroups.length); adGroups[adjustedIndex] = @@ -637,7 +644,8 @@ public final class AdPlaybackState implements Bundleable { /** Returns an instance with the specified ad marked as having a load error. */ @CheckResult - public AdPlaybackState withAdLoadError(int adGroupIndex, int adIndexInAdGroup) { + public AdPlaybackState withAdLoadError( + @IntRange(from = 0) int adGroupIndex, @IntRange(from = 0) int adIndexInAdGroup) { int adjustedIndex = adGroupIndex - removedAdGroupCount; AdGroup[] adGroups = Util.nullSafeArrayCopy(this.adGroups, this.adGroups.length); adGroups[adjustedIndex] = adGroups[adjustedIndex].withAdState(AD_STATE_ERROR, adIndexInAdGroup); @@ -650,7 +658,7 @@ public final class AdPlaybackState implements Bundleable { * marked as played or in the error state). */ @CheckResult - public AdPlaybackState withSkippedAdGroup(int adGroupIndex) { + public AdPlaybackState withSkippedAdGroup(@IntRange(from = 0) int adGroupIndex) { int adjustedIndex = adGroupIndex - removedAdGroupCount; AdGroup[] adGroups = Util.nullSafeArrayCopy(this.adGroups, this.adGroups.length); adGroups[adjustedIndex] = adGroups[adjustedIndex].withAllAdsSkipped(); @@ -679,7 +687,8 @@ public final class AdPlaybackState implements Bundleable { * group. */ @CheckResult - public AdPlaybackState withAdDurationsUs(int adGroupIndex, long... adDurationsUs) { + public AdPlaybackState withAdDurationsUs( + @IntRange(from = 0) int adGroupIndex, long... adDurationsUs) { int adjustedIndex = adGroupIndex - removedAdGroupCount; AdGroup[] adGroups = Util.nullSafeArrayCopy(this.adGroups, this.adGroups.length); adGroups[adjustedIndex] = adGroups[adjustedIndex].withAdDurationsUs(adDurationsUs); @@ -720,7 +729,7 @@ public final class AdPlaybackState implements Bundleable { * (exclusive) will be empty and must not be modified by any of the {@code with*} methods. */ @CheckResult - public AdPlaybackState withRemovedAdGroupCount(int removedAdGroupCount) { + public AdPlaybackState withRemovedAdGroupCount(@IntRange(from = 0) int removedAdGroupCount) { if (this.removedAdGroupCount == removedAdGroupCount) { return this; } else { @@ -742,7 +751,8 @@ public final class AdPlaybackState implements Bundleable { * for the specified ad group. */ @CheckResult - public AdPlaybackState withContentResumeOffsetUs(int adGroupIndex, long contentResumeOffsetUs) { + public AdPlaybackState withContentResumeOffsetUs( + @IntRange(from = 0) int adGroupIndex, long contentResumeOffsetUs) { int adjustedIndex = adGroupIndex - removedAdGroupCount; if (adGroups[adjustedIndex].contentResumeOffsetUs == contentResumeOffsetUs) { return this; @@ -759,7 +769,8 @@ public final class AdPlaybackState implements Bundleable { * specified ad group. */ @CheckResult - public AdPlaybackState withIsServerSideInserted(int adGroupIndex, boolean isServerSideInserted) { + public AdPlaybackState withIsServerSideInserted( + @IntRange(from = 0) int adGroupIndex, boolean isServerSideInserted) { int adjustedIndex = adGroupIndex - removedAdGroupCount; if (adGroups[adjustedIndex].isServerSideInserted == isServerSideInserted) { return this; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java index 95705a9caa..e957a39fc7 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java @@ -33,6 +33,7 @@ import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import androidx.annotation.CheckResult; +import androidx.annotation.IntRange; import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.database.DatabaseProvider; @@ -378,7 +379,7 @@ public final class DownloadManager { * * @param maxParallelDownloads The maximum number of parallel downloads. Must be greater than 0. */ - public void setMaxParallelDownloads(int maxParallelDownloads) { + public void setMaxParallelDownloads(@IntRange(from = 1) int maxParallelDownloads) { Assertions.checkArgument(maxParallelDownloads > 0); if (this.maxParallelDownloads == maxParallelDownloads) { return; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/SilenceMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/SilenceMediaSource.java index 725100b583..93f3d7ac1a 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/SilenceMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/SilenceMediaSource.java @@ -18,6 +18,7 @@ package com.google.android.exoplayer2.source; import static java.lang.Math.min; import android.net.Uri; +import androidx.annotation.IntRange; import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.Format; @@ -49,7 +50,7 @@ public final class SilenceMediaSource extends BaseMediaSource { * @param durationUs The duration of silent audio to output, in microseconds. * @return This factory, for convenience. */ - public Factory setDurationUs(long durationUs) { + public Factory setDurationUs(@IntRange(from = 1) long durationUs) { this.durationUs = durationUs; return this; } diff --git a/library/ui/src/main/java/com/google/android/exoplayer2/ui/PlayerNotificationManager.java b/library/ui/src/main/java/com/google/android/exoplayer2/ui/PlayerNotificationManager.java index f6ccf5a77a..409fb16263 100644 --- a/library/ui/src/main/java/com/google/android/exoplayer2/ui/PlayerNotificationManager.java +++ b/library/ui/src/main/java/com/google/android/exoplayer2/ui/PlayerNotificationManager.java @@ -46,6 +46,7 @@ import android.os.Message; import android.support.v4.media.session.MediaSessionCompat; import androidx.annotation.DrawableRes; import androidx.annotation.IntDef; +import androidx.annotation.IntRange; import androidx.annotation.Nullable; import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationManagerCompat; @@ -348,7 +349,7 @@ public class PlayerNotificationManager { * @param notificationId The id of the notification to be posted. Must be greater than 0. * @param channelId The id of the notification channel. */ - public Builder(Context context, int notificationId, String channelId) { + public Builder(Context context, @IntRange(from = 1) int notificationId, String channelId) { checkArgument(notificationId > 0); this.context = context; this.notificationId = notificationId;