Util { public static int binarySearchFloor( int[] array, int value, boolean inclusive, boolean stayInBounds) { int index = Arrays.binarySearch(array, value); if (index < 0) { index = -(index + 2); } else { while (--index >= 0 && array[index] == value) {} if (inclusive) { index++; } } return stayInBounds ? Math.max(0, index) : index; } private  Util(); static byte[] toByteArray(InputStream inputStream); @Nullable static ComponentName startForegroundService(Context context, Intent intent); @TargetApi(23) static boolean maybeRequestReadExternalStoragePermission(Activity activity, Uri... uris); @TargetApi(24) static boolean checkCleartextTrafficPermitted(Uri... uris); static boolean isLocalFileUri(Uri uri); static boolean areEqual(@Nullable Object o1, @Nullable Object o2); static boolean contains(@NullableType Object[] items, @Nullable Object item); static void removeRange(List<T> list, int fromIndex, int toIndex); @SuppressWarnings({"contracts.postcondition.not.satisfied", "return.type.incompatible"}) @EnsuresNonNull("#1") static T castNonNull(@Nullable T value); @SuppressWarnings({"contracts.postcondition.not.satisfied", "return.type.incompatible"}) @EnsuresNonNull("#1") static T[] castNonNullTypeArray(@NullableType T[] value); @SuppressWarnings({"nullness:argument.type.incompatible", "nullness:return.type.incompatible"}) static T[] nullSafeArrayCopy(T[] input, int length); @SuppressWarnings({"nullness:argument.type.incompatible", "nullness:return.type.incompatible"}) static T[] nullSafeArrayCopyOfRange(T[] input, int from, int to); static T[] nullSafeArrayAppend(T[] original, T newElement); @SuppressWarnings({"nullness:assignment.type.incompatible"}) static T[] nullSafeArrayConcatenation(T[] first, T[] second); static Handler createHandler(Handler.@UnknownInitialization Callback callback); @SuppressWarnings({"nullness:argument.type.incompatible", "nullness:return.type.incompatible"}) static Handler createHandler(
      Looper looper, Handler.@UnknownInitialization Callback callback); static Looper getLooper(); static ExecutorService newSingleThreadExecutor(final String threadName); static void closeQuietly(@Nullable DataSource dataSource); static void closeQuietly(@Nullable Closeable closeable); static boolean readBoolean(Parcel parcel); static void writeBoolean(Parcel parcel, boolean value); static String getLocaleLanguageTag(Locale locale); static @PolyNull String normalizeLanguageCode(@PolyNull String language); static String fromUtf8Bytes(byte[] bytes); static String fromUtf8Bytes(byte[] bytes, int offset, int length); static byte[] getUtf8Bytes(String value); static String[] split(String value, String regex); static String[] splitAtFirst(String value, String regex); static boolean isLinebreak(int c); static @PolyNull String toLowerInvariant(@PolyNull String text); static @PolyNull String toUpperInvariant(@PolyNull String text); static String formatInvariant(String format, Object... args); static int ceilDivide(int numerator, int denominator); static long ceilDivide(long numerator, long denominator); static int constrainValue(int value, int min, int max); static long constrainValue(long value, long min, long max); static float constrainValue(float value, float min, float max); static long addWithOverflowDefault(long x, long y, long overflowResult); static long subtractWithOverflowDefault(long x, long y, long overflowResult); static int linearSearch(int[] array, int value); static int binarySearchFloor(
      int[] array, int value, boolean inclusive, boolean stayInBounds); static int binarySearchFloor(long[] array, long value, boolean inclusive,
      boolean stayInBounds); static int binarySearchFloor(
      List<? extends Comparable<? super T>> list,
      T value,
      boolean inclusive,
      boolean stayInBounds); static int binarySearchCeil(
      int[] array, int value, boolean inclusive, boolean stayInBounds); static int binarySearchCeil(
      long[] array, long value, boolean inclusive, boolean stayInBounds); static int binarySearchCeil(
      List<? extends Comparable<? super T>> list,
      T value,
      boolean inclusive,
      boolean stayInBounds); static int compareLong(long left, long right); static long parseXsDuration(String value); static long parseXsDateTime(String value); static long scaleLargeTimestamp(long timestamp, long multiplier, long divisor); static long[] scaleLargeTimestamps(List<Long> timestamps, long multiplier, long divisor); static void scaleLargeTimestampsInPlace(long[] timestamps, long multiplier, long divisor); static long getMediaDurationForPlayoutDuration(long playoutDuration, float speed); static long getPlayoutDurationForMediaDuration(long mediaDuration, float speed); static long resolveSeekPositionUs(
      long positionUs, SeekParameters seekParameters, long firstSyncUs, long secondSyncUs); static int @PolyNull [] toArray(@PolyNull List<Integer> list); static int getIntegerCodeForString(String string); static long toUnsignedLong(int x); static long toLong(int mostSignificantBits, int leastSignificantBits); static byte[] getBytesFromHexString(String hexString); static String getCommaDelimitedSimpleClassNames(Object[] objects); static String getUserAgent(Context context, String applicationName); static @Nullable String getCodecsOfType(@Nullable String codecs, int trackType); static String[] splitCodecs(@Nullable String codecs); @C.PcmEncoding static int getPcmEncoding(int bitDepth); static boolean isEncodingLinearPcm(@C.Encoding int encoding); static boolean isEncodingHighResolutionIntegerPcm(@C.PcmEncoding int encoding); static int getAudioTrackChannelConfig(int channelCount); static int getPcmFrameSize(@C.PcmEncoding int pcmEncoding, int channelCount); @C.AudioUsage static int getAudioUsageForStreamType(@C.StreamType int streamType); @C.AudioContentType static int getAudioContentTypeForStreamType(@C.StreamType int streamType); @C.StreamType static int getStreamTypeForAudioUsage(@C.AudioUsage int usage); static @Nullable UUID getDrmUuid(String drmScheme); @C.ContentType static int inferContentType(Uri uri, @Nullable String overrideExtension); @C.ContentType static int inferContentType(Uri uri); @C.ContentType static int inferContentType(String fileName); static String getStringForTime(StringBuilder builder, Formatter formatter, long timeMs); static String escapeFileName(String fileName); static @Nullable String unescapeFileName(String fileName); static void sneakyThrow(Throwable t); static void recursiveDelete(File fileOrDirectory); static File createTempDirectory(Context context, String prefix); static File createTempFile(Context context, String prefix); static int crc32(byte[] bytes, int start, int end, int initialValue); static int crc8(byte[] bytes, int start, int end, int initialValue); @C.NetworkType static int getNetworkType(Context context); static String getCountryCode(@Nullable Context context); static String[] getSystemLanguageCodes(); static boolean inflate(
      ParsableByteArray input, ParsableByteArray output, @Nullable Inflater inflater); static boolean isTv(Context context); static Point getCurrentDisplayModeSize(Context context); static Point getCurrentDisplayModeSize(Context context, Display display); static RendererCapabilities[] getRendererCapabilities(RenderersFactory renderersFactory); static String getTrackTypeString(int trackType); static final int SDK_INT; static final String DEVICE; static final String MANUFACTURER; static final String MODEL; static final String DEVICE_DEBUG_INFO; static final byte[] EMPTY_BYTE_ARRAY; }
@Test public void testArrayBinarySearchFloor() { long[] values = new long[0]; assertThat(binarySearchFloor(values, 0, false, false)).isEqualTo(-1); assertThat(binarySearchFloor(values, 0, false, true)).isEqualTo(0); values = new long[] {1, 3, 5}; assertThat(binarySearchFloor(values, 0, false, false)).isEqualTo(-1); assertThat(binarySearchFloor(values, 0, true, false)).isEqualTo(-1); assertThat(binarySearchFloor(values, 0, false, true)).isEqualTo(0); assertThat(binarySearchFloor(values, 0, true, true)).isEqualTo(0); assertThat(binarySearchFloor(values, 1, false, false)).isEqualTo(-1); assertThat(binarySearchFloor(values, 1, true, false)).isEqualTo(0); assertThat(binarySearchFloor(values, 1, false, true)).isEqualTo(0); assertThat(binarySearchFloor(values, 1, true, true)).isEqualTo(0); assertThat(binarySearchFloor(values, 4, false, false)).isEqualTo(1); assertThat(binarySearchFloor(values, 4, true, false)).isEqualTo(1); assertThat(binarySearchFloor(values, 5, false, false)).isEqualTo(1); assertThat(binarySearchFloor(values, 5, true, false)).isEqualTo(2); assertThat(binarySearchFloor(values, 6, false, false)).isEqualTo(2); assertThat(binarySearchFloor(values, 6, true, false)).isEqualTo(2); }
@Test public void testListBinarySearchFloor() { List<Integer> values = new ArrayList<>(); assertThat(binarySearchFloor(values, 0, false, false)).isEqualTo(-1); assertThat(binarySearchFloor(values, 0, false, true)).isEqualTo(0); values.add(1); values.add(3); values.add(5); assertThat(binarySearchFloor(values, 0, false, false)).isEqualTo(-1); assertThat(binarySearchFloor(values, 0, true, false)).isEqualTo(-1); assertThat(binarySearchFloor(values, 0, false, true)).isEqualTo(0); assertThat(binarySearchFloor(values, 0, true, true)).isEqualTo(0); assertThat(binarySearchFloor(values, 1, false, false)).isEqualTo(-1); assertThat(binarySearchFloor(values, 1, true, false)).isEqualTo(0); assertThat(binarySearchFloor(values, 1, false, true)).isEqualTo(0); assertThat(binarySearchFloor(values, 1, true, true)).isEqualTo(0); assertThat(binarySearchFloor(values, 4, false, false)).isEqualTo(1); assertThat(binarySearchFloor(values, 4, true, false)).isEqualTo(1); assertThat(binarySearchFloor(values, 5, false, false)).isEqualTo(1); assertThat(binarySearchFloor(values, 5, true, false)).isEqualTo(2); assertThat(binarySearchFloor(values, 6, false, false)).isEqualTo(2); assertThat(binarySearchFloor(values, 6, true, false)).isEqualTo(2); }