Increase minSdkVersion to 16

The combination of pre-16 API levels accounting for ~0.5% of the device
population, and that the most important components in ExoPlayer (e.g.
the MediaCodec renderers) have always required API level 16, mean it's
very unlikely this will negatively impact on anyone.

PiperOrigin-RevId: 230701808
This commit is contained in:
olly 2019-01-24 13:01:36 +00:00 committed by Oliver Woodman
parent 2c54b83464
commit 355b3d6334
34 changed files with 39 additions and 122 deletions

View File

@ -2,6 +2,7 @@
### dev-v2 (not yet released) ###
* Increase `minSdkVersion` to 16 (Jellybean).
* Support for playing spherical videos on Daydream.
* Improve decoder re-use between playbacks. TODO: Write and link a blog post
here ([#2826](https://github.com/google/ExoPlayer/issues/2826)).

View File

@ -15,11 +15,7 @@ project.ext {
// ExoPlayer version and version code.
releaseVersion = '2.9.4'
releaseVersionCode = 2009004
// Important: ExoPlayer specifies a minSdkVersion of 14 because various
// components provided by the library may be of use on older devices.
// However, please note that the core media playback functionality provided
// by the library requires API level 16 or greater.
minSdkVersion = 14
minSdkVersion = 16
targetSdkVersion = 28
compileSdkVersion = 28
buildToolsVersion = '28.0.2'

View File

@ -26,7 +26,7 @@ android {
defaultConfig {
versionName project.ext.releaseVersion
versionCode project.ext.releaseVersionCode
minSdkVersion 16
minSdkVersion project.ext.minSdkVersion
targetSdkVersion project.ext.targetSdkVersion
}

View File

@ -26,7 +26,7 @@ android {
defaultConfig {
versionName project.ext.releaseVersion
versionCode project.ext.releaseVersionCode
minSdkVersion 16
minSdkVersion project.ext.minSdkVersion
targetSdkVersion project.ext.targetSdkVersion
}

View File

@ -26,7 +26,7 @@ android {
defaultConfig {
versionName project.ext.releaseVersion
versionCode project.ext.releaseVersionCode
minSdkVersion 16
minSdkVersion project.ext.minSdkVersion
targetSdkVersion project.ext.targetSdkVersion
}

View File

@ -24,7 +24,7 @@ android {
}
defaultConfig {
minSdkVersion 14
minSdkVersion project.ext.minSdkVersion
targetSdkVersion project.ext.targetSdkVersion
consumerProguardFiles 'proguard-rules.txt'
}

View File

@ -19,7 +19,7 @@ android {
buildToolsVersion project.ext.buildToolsVersion
defaultConfig {
minSdkVersion 16
minSdkVersion project.ext.minSdkVersion
targetSdkVersion project.ext.targetSdkVersion
}

View File

@ -24,7 +24,7 @@ android {
}
defaultConfig {
minSdkVersion 15
minSdkVersion project.ext.minSdkVersion
targetSdkVersion project.ext.targetSdkVersion
}
}

View File

@ -63,7 +63,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
* An {@link ExoPlayer} implementation that uses default {@link Renderer} components. Instances can
* be obtained from {@link ExoPlayerFactory}.
*/
@TargetApi(16)
public class SimpleExoPlayer extends BasePlayer
implements ExoPlayer,
Player.AudioComponent,

View File

@ -16,7 +16,6 @@
package com.google.android.exoplayer2.audio;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.media.MediaCodec;
import android.media.MediaCrypto;
@ -66,7 +65,6 @@ import java.util.List;
* underlying audio track.
* </ul>
*/
@TargetApi(16)
public class MediaCodecAudioRenderer extends MediaCodecRenderer implements MediaClock {
/**

View File

@ -62,7 +62,7 @@ public final class CryptoInfo {
private final PatternHolderV24 patternHolder;
public CryptoInfo() {
frameworkCryptoInfo = Util.SDK_INT >= 16 ? newFrameworkCryptoInfoV16() : null;
frameworkCryptoInfo = new android.media.MediaCodec.CryptoInfo();
patternHolder = Util.SDK_INT >= 24 ? new PatternHolderV24(frameworkCryptoInfo) : null;
}
@ -79,34 +79,8 @@ public final class CryptoInfo {
this.mode = mode;
this.encryptedBlocks = encryptedBlocks;
this.clearBlocks = clearBlocks;
if (Util.SDK_INT >= 16) {
updateFrameworkCryptoInfoV16();
}
}
/**
* Returns an equivalent {@link android.media.MediaCodec.CryptoInfo} instance.
* <p>
* Successive calls to this method on a single {@link CryptoInfo} will return the same instance.
* Changes to the {@link CryptoInfo} will be reflected in the returned object. The return object
* should not be modified directly.
*
* @return The equivalent {@link android.media.MediaCodec.CryptoInfo} instance.
*/
@TargetApi(16)
public android.media.MediaCodec.CryptoInfo getFrameworkCryptoInfoV16() {
return frameworkCryptoInfo;
}
@TargetApi(16)
private android.media.MediaCodec.CryptoInfo newFrameworkCryptoInfoV16() {
return new android.media.MediaCodec.CryptoInfo();
}
@TargetApi(16)
private void updateFrameworkCryptoInfoV16() {
// Update fields directly because the framework's CryptoInfo.set performs an unnecessary object
// allocation on Android N.
// Update frameworkCryptoInfo fields directly because CryptoInfo.set performs an unnecessary
// object allocation on Android N.
frameworkCryptoInfo.numSubSamples = numSubSamples;
frameworkCryptoInfo.numBytesOfClearData = numBytesOfClearData;
frameworkCryptoInfo.numBytesOfEncryptedData = numBytesOfEncryptedData;
@ -118,6 +92,25 @@ public final class CryptoInfo {
}
}
/**
* Returns an equivalent {@link android.media.MediaCodec.CryptoInfo} instance.
*
* <p>Successive calls to this method on a single {@link CryptoInfo} will return the same
* instance. Changes to the {@link CryptoInfo} will be reflected in the returned object. The
* return object should not be modified directly.
*
* @return The equivalent {@link android.media.MediaCodec.CryptoInfo} instance.
*/
public android.media.MediaCodec.CryptoInfo getFrameworkCryptoInfo() {
return frameworkCryptoInfo;
}
/** @deprecated Use {@link #getFrameworkCryptoInfo()}. */
@Deprecated
public android.media.MediaCodec.CryptoInfo getFrameworkCryptoInfoV16() {
return getFrameworkCryptoInfo();
}
@TargetApi(24)
private static final class PatternHolderV24 {

View File

@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.drm;
import android.annotation.TargetApi;
import android.media.MediaDrm;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
@ -27,7 +26,6 @@ import java.util.Map;
/**
* A DRM session.
*/
@TargetApi(16)
public interface DrmSession<T extends ExoMediaCrypto> {
/**

View File

@ -15,14 +15,12 @@
*/
package com.google.android.exoplayer2.drm;
import android.annotation.TargetApi;
import android.os.Looper;
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
/**
* Manages a DRM session.
*/
@TargetApi(16)
public interface DrmSessionManager<T extends ExoMediaCrypto> {
/**

View File

@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.drm;
import android.annotation.TargetApi;
import android.media.MediaCrypto;
import java.util.UUID;
@ -23,7 +22,6 @@ import java.util.UUID;
* An {@link ExoMediaCrypto} implementation that contains the necessary information to build or
* update a framework {@link MediaCrypto}.
*/
@TargetApi(16)
public final class FrameworkMediaCrypto implements ExoMediaCrypto {
/** The DRM scheme UUID. */

View File

@ -31,7 +31,6 @@ import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util;
/** Information about a {@link MediaCodec} for a given mime type. */
@TargetApi(16)
@SuppressWarnings("InlinedApi")
public final class MediaCodecInfo {

View File

@ -58,7 +58,6 @@ import java.util.List;
/**
* An abstract renderer that uses {@link MediaCodec} to decode samples for rendering.
*/
@TargetApi(16)
public abstract class MediaCodecRenderer extends BaseRenderer {
/**
@ -366,7 +365,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
boolean playClearSamplesWithoutKeys,
float assumedMinimumCodecOperatingRate) {
super(trackType);
Assertions.checkState(Util.SDK_INT >= 16);
this.mediaCodecSelector = Assertions.checkNotNull(mediaCodecSelector);
this.drmSessionManager = drmSessionManager;
this.playClearSamplesWithoutKeys = playClearSamplesWithoutKeys;
@ -1662,7 +1660,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
private static MediaCodec.CryptoInfo getFrameworkCryptoInfo(
DecoderInputBuffer buffer, int adaptiveReconfigurationBytes) {
MediaCodec.CryptoInfo cryptoInfo = buffer.cryptoInfo.getFrameworkCryptoInfoV16();
MediaCodec.CryptoInfo cryptoInfo = buffer.cryptoInfo.getFrameworkCryptoInfo();
if (adaptiveReconfigurationBytes == 0) {
return cryptoInfo;
}

View File

@ -39,7 +39,6 @@ import java.util.regex.Pattern;
/**
* A utility class for querying the available codecs.
*/
@TargetApi(16)
@SuppressLint("InlinedApi")
public final class MediaCodecUtil {

View File

@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.mediacodec;
import android.annotation.TargetApi;
import android.media.MediaFormat;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.Format;
@ -24,7 +23,6 @@ import java.nio.ByteBuffer;
import java.util.List;
/** Helper class for configuring {@link MediaFormat} instances. */
@TargetApi(16)
public final class MediaFormatUtil {
private MediaFormatUtil() {}

View File

@ -200,7 +200,7 @@ public final class Requirements {
logd("Roaming: " + roaming);
return !roaming;
}
boolean activeNetworkMetered = isActiveNetworkMetered(connectivityManager, networkInfo);
boolean activeNetworkMetered = connectivityManager.isActiveNetworkMetered();
logd("Metered network: " + activeNetworkMetered);
if (networkRequirement == NETWORK_TYPE_UNMETERED) {
return !activeNetworkMetered;
@ -255,17 +255,6 @@ public final class Requirements {
return !validated;
}
private static boolean isActiveNetworkMetered(
ConnectivityManager connectivityManager, NetworkInfo networkInfo) {
if (Util.SDK_INT >= 16) {
return connectivityManager.isActiveNetworkMetered();
}
int type = networkInfo.getType();
return type != ConnectivityManager.TYPE_WIFI
&& type != ConnectivityManager.TYPE_BLUETOOTH
&& type != ConnectivityManager.TYPE_ETHERNET;
}
private static void logd(String message) {
if (Scheduler.DEBUG) {
Log.d(TAG, message);

View File

@ -17,7 +17,6 @@ package com.google.android.exoplayer2.util;
import static android.opengl.GLU.gluErrorString;
import android.annotation.TargetApi;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;
import android.text.TextUtils;
@ -114,7 +113,6 @@ public final class GlUtil {
* Creates a GL_TEXTURE_EXTERNAL_OES with default configuration of GL_LINEAR filtering and
* GL_CLAMP_TO_EDGE wrapping.
*/
@TargetApi(15)
public static int createExternalTexture() {
int[] texId = new int[1];
GLES20.glGenTextures(1, IntBuffer.wrap(texId));

View File

@ -1844,10 +1844,8 @@ public final class Util {
getDisplaySizeV23(display, displaySize);
} else if (Util.SDK_INT >= 17) {
getDisplaySizeV17(display, displaySize);
} else if (Util.SDK_INT >= 16) {
getDisplaySizeV16(display, displaySize);
} else {
getDisplaySizeV9(display, displaySize);
getDisplaySizeV16(display, displaySize);
}
return displaySize;
}
@ -1903,17 +1901,10 @@ public final class Util {
display.getRealSize(outSize);
}
@TargetApi(16)
private static void getDisplaySizeV16(Display display, Point outSize) {
display.getSize(outSize);
}
@SuppressWarnings("deprecation")
private static void getDisplaySizeV9(Display display, Point outSize) {
outSize.x = display.getWidth();
outSize.y = display.getHeight();
}
private static @C.NetworkType int getMobileNetworkType(NetworkInfo networkInfo) {
switch (networkInfo.getSubtype()) {
case TelephonyManager.NETWORK_TYPE_EDGE:

View File

@ -68,7 +68,6 @@ import java.util.List;
* a {@link android.view.SurfaceView}.
* </ul>
*/
@TargetApi(16)
public class MediaCodecVideoRenderer extends MediaCodecRenderer {
private static final String TAG = "MediaCodecVideoRenderer";

View File

@ -32,7 +32,6 @@ import com.google.android.exoplayer2.util.Util;
/**
* Makes a best effort to adjust frame release timestamps for a smoother visual result.
*/
@TargetApi(16)
public final class VideoFrameReleaseTimeHelper {
private static final long CHOREOGRAPHER_SAMPLE_DELAY_MILLIS = 500;

View File

@ -15,14 +15,12 @@
*/
package com.google.android.exoplayer2.extractor.mp4;
import android.annotation.TargetApi;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link Mp4Extractor}. */
@TargetApi(16)
@RunWith(RobolectricTestRunner.class)
public final class Mp4ExtractorTest {

View File

@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.extractor.rawcc;
import android.annotation.TargetApi;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import com.google.android.exoplayer2.util.MimeTypes;
@ -24,7 +23,6 @@ import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link RawCcExtractor}. */
@TargetApi(16)
@RunWith(RobolectricTestRunner.class)
public final class RawCcExtractorTest {

View File

@ -319,8 +319,8 @@ public class DefaultTimeBar extends View implements TimeBar {
keyTimeIncrement = C.TIME_UNSET;
keyCountIncrement = DEFAULT_INCREMENT_COUNT;
setFocusable(true);
if (Util.SDK_INT >= 16) {
maybeSetImportantForAccessibilityV16();
if (getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
}
}
@ -611,13 +611,12 @@ public class DefaultTimeBar extends View implements TimeBar {
if (Util.SDK_INT >= 21) {
info.addAction(AccessibilityAction.ACTION_SCROLL_FORWARD);
info.addAction(AccessibilityAction.ACTION_SCROLL_BACKWARD);
} else if (Util.SDK_INT >= 16) {
} else {
info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
}
}
@TargetApi(16)
@Override
public boolean performAccessibilityAction(int action, @Nullable Bundle args) {
if (super.performAccessibilityAction(action, args)) {
@ -643,13 +642,6 @@ public class DefaultTimeBar extends View implements TimeBar {
// Internal methods.
@TargetApi(16)
private void maybeSetImportantForAccessibilityV16() {
if (getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
}
}
private void startScrubbing() {
scrubbing = true;
setPressed(true);

View File

@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.ui;
import android.annotation.TargetApi;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@ -25,7 +24,6 @@ import com.google.android.exoplayer2.SimpleExoPlayer;
/** @deprecated Use {@link PlayerView}. */
@Deprecated
@TargetApi(16)
public final class SimpleExoPlayerView extends PlayerView {
public SimpleExoPlayerView(Context context) {

View File

@ -18,7 +18,6 @@ package com.google.android.exoplayer2.ui.spherical;
import static com.google.android.exoplayer2.util.GlUtil.checkGlError;
import android.annotation.TargetApi;
import android.graphics.Canvas;
import android.graphics.PointF;
import android.graphics.Rect;
@ -39,7 +38,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
* <p>A CanvasRenderer can be created on any thread, but {@link #init()} needs to be called on the
* GL thread before it can be rendered.
*/
@TargetApi(15)
public final class CanvasRenderer {
private static final float WIDTH_UNIT = 0.8f;

View File

@ -17,7 +17,6 @@ package com.google.android.exoplayer2.ui.spherical;
import static com.google.android.exoplayer2.util.GlUtil.checkGlError;
import android.annotation.TargetApi;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;
import com.google.android.exoplayer2.C;
@ -30,7 +29,6 @@ import org.checkerframework.checker.nullness.qual.Nullable;
* Utility class to render spherical meshes for video or images. Call {@link #init()} on the GL
* thread when ready.
*/
@TargetApi(15)
/* package */ final class ProjectionRenderer {
/**

View File

@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.ui.spherical;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.PointF;
import android.graphics.SurfaceTexture;
@ -52,7 +51,6 @@ import javax.microedition.khronos.opengles.GL10;
* apply the touch and sensor rotations in the correct order or the user's touch manipulations won't
* match what they expect.
*/
@TargetApi(15)
public final class SphericalSurfaceView extends GLSurfaceView {
/**

View File

@ -89,10 +89,6 @@ public final class DashDownloadTest {
@Test
public void testDownload() throws Exception {
if (Util.SDK_INT < 16) {
return; // Pass.
}
DashDownloader dashDownloader = downloadContent();
dashDownloader.download();

View File

@ -103,10 +103,6 @@ public final class DashStreamingTest {
@Test
public void testH264Fixed() {
if (Util.SDK_INT < 16) {
// Pass.
return;
}
testRunner
.setStreamName("test_h264_fixed")
.setManifestUrl(DashTestData.H264_MANIFEST)
@ -118,7 +114,7 @@ public final class DashStreamingTest {
@Test
public void testH264Adaptive() throws DecoderQueryException {
if (Util.SDK_INT < 16 || shouldSkipAdaptiveTest(MimeTypes.VIDEO_H264)) {
if (shouldSkipAdaptiveTest(MimeTypes.VIDEO_H264)) {
// Pass.
return;
}
@ -134,7 +130,7 @@ public final class DashStreamingTest {
@Test
public void testH264AdaptiveWithSeeking() throws DecoderQueryException {
if (Util.SDK_INT < 16 || shouldSkipAdaptiveTest(MimeTypes.VIDEO_H264)) {
if (shouldSkipAdaptiveTest(MimeTypes.VIDEO_H264)) {
// Pass.
return;
}
@ -152,7 +148,7 @@ public final class DashStreamingTest {
@Test
public void testH264AdaptiveWithRendererDisabling() throws DecoderQueryException {
if (Util.SDK_INT < 16 || shouldSkipAdaptiveTest(MimeTypes.VIDEO_H264)) {
if (shouldSkipAdaptiveTest(MimeTypes.VIDEO_H264)) {
// Pass.
return;
}
@ -633,10 +629,6 @@ public final class DashStreamingTest {
@Test
public void testDecoderInfoH264() throws DecoderQueryException {
if (Util.SDK_INT < 16) {
// Pass.
return;
}
MediaCodecInfo decoderInfo = MediaCodecUtil.getDecoderInfo(MimeTypes.VIDEO_H264, false);
assertThat(decoderInfo).isNotNull();
assertThat(Util.SDK_INT < 21 || decoderInfo.adaptive).isTrue();

View File

@ -205,7 +205,6 @@ public final class DashTestRunner {
/**
* A {@link HostedTest} for DASH playback tests.
*/
@TargetApi(16)
private static final class DashHostedTest extends ExoHostedTest {
private final String streamName;

View File

@ -39,7 +39,6 @@ import java.util.ArrayList;
* A debug extension of {@link DefaultRenderersFactory}. Provides a video renderer that performs
* video buffer timestamp assertions.
*/
@TargetApi(16)
public class DebugRenderersFactory extends DefaultRenderersFactory {
public DebugRenderersFactory(Context context) {