mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Factor out Handler creation in construtor to prevent warning suppression.
Using new Handler(this) in a constructor potentially leaks an uninitialized object. This is mostly not a problem because we don't use the Handler within the constructor. Added a Util method to keep the warning suppression local. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=199605377
This commit is contained in:
parent
cad3de91c9
commit
9f20683a6c
5 changed files with 68 additions and 30 deletions
|
|
@ -19,12 +19,14 @@ import android.os.Handler;
|
||||||
import android.os.Handler.Callback;
|
import android.os.Handler.Callback;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.BaseRenderer;
|
import com.google.android.exoplayer2.BaseRenderer;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||||
import com.google.android.exoplayer2.Format;
|
import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.FormatHolder;
|
import com.google.android.exoplayer2.FormatHolder;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -46,7 +48,7 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
|
||||||
|
|
||||||
private final MetadataDecoderFactory decoderFactory;
|
private final MetadataDecoderFactory decoderFactory;
|
||||||
private final MetadataOutput output;
|
private final MetadataOutput output;
|
||||||
private final Handler outputHandler;
|
private final @Nullable Handler outputHandler;
|
||||||
private final FormatHolder formatHolder;
|
private final FormatHolder formatHolder;
|
||||||
private final MetadataInputBuffer buffer;
|
private final MetadataInputBuffer buffer;
|
||||||
private final Metadata[] pendingMetadata;
|
private final Metadata[] pendingMetadata;
|
||||||
|
|
@ -61,11 +63,11 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
|
||||||
* @param output The output.
|
* @param output The output.
|
||||||
* @param outputLooper The looper associated with the thread on which the output should be called.
|
* @param outputLooper The looper associated with the thread on which the output should be called.
|
||||||
* If the output makes use of standard Android UI components, then this should normally be the
|
* If the output makes use of standard Android UI components, then this should normally be the
|
||||||
* looper associated with the application's main thread, which can be obtained using
|
* looper associated with the application's main thread, which can be obtained using {@link
|
||||||
* {@link android.app.Activity#getMainLooper()}. Null may be passed if the output should be
|
* android.app.Activity#getMainLooper()}. Null may be passed if the output should be called
|
||||||
* called directly on the player's internal rendering thread.
|
* directly on the player's internal rendering thread.
|
||||||
*/
|
*/
|
||||||
public MetadataRenderer(MetadataOutput output, Looper outputLooper) {
|
public MetadataRenderer(MetadataOutput output, @Nullable Looper outputLooper) {
|
||||||
this(output, outputLooper, MetadataDecoderFactory.DEFAULT);
|
this(output, outputLooper, MetadataDecoderFactory.DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,16 +75,17 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
|
||||||
* @param output The output.
|
* @param output The output.
|
||||||
* @param outputLooper The looper associated with the thread on which the output should be called.
|
* @param outputLooper The looper associated with the thread on which the output should be called.
|
||||||
* If the output makes use of standard Android UI components, then this should normally be the
|
* If the output makes use of standard Android UI components, then this should normally be the
|
||||||
* looper associated with the application's main thread, which can be obtained using
|
* looper associated with the application's main thread, which can be obtained using {@link
|
||||||
* {@link android.app.Activity#getMainLooper()}. Null may be passed if the output should be
|
* android.app.Activity#getMainLooper()}. Null may be passed if the output should be called
|
||||||
* called directly on the player's internal rendering thread.
|
* directly on the player's internal rendering thread.
|
||||||
* @param decoderFactory A factory from which to obtain {@link MetadataDecoder} instances.
|
* @param decoderFactory A factory from which to obtain {@link MetadataDecoder} instances.
|
||||||
*/
|
*/
|
||||||
public MetadataRenderer(MetadataOutput output, Looper outputLooper,
|
public MetadataRenderer(
|
||||||
MetadataDecoderFactory decoderFactory) {
|
MetadataOutput output, @Nullable Looper outputLooper, MetadataDecoderFactory decoderFactory) {
|
||||||
super(C.TRACK_TYPE_METADATA);
|
super(C.TRACK_TYPE_METADATA);
|
||||||
this.output = Assertions.checkNotNull(output);
|
this.output = Assertions.checkNotNull(output);
|
||||||
this.outputHandler = outputLooper == null ? null : new Handler(outputLooper, this);
|
this.outputHandler =
|
||||||
|
outputLooper == null ? null : Util.createHandler(outputLooper, /* callback= */ this);
|
||||||
this.decoderFactory = Assertions.checkNotNull(decoderFactory);
|
this.decoderFactory = Assertions.checkNotNull(decoderFactory);
|
||||||
formatHolder = new FormatHolder();
|
formatHolder = new FormatHolder();
|
||||||
buffer = new MetadataInputBuffer();
|
buffer = new MetadataInputBuffer();
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import android.os.Handler.Callback;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.support.annotation.IntDef;
|
import android.support.annotation.IntDef;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.BaseRenderer;
|
import com.google.android.exoplayer2.BaseRenderer;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||||
|
|
@ -27,6 +28,7 @@ import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.FormatHolder;
|
import com.google.android.exoplayer2.FormatHolder;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
import com.google.android.exoplayer2.util.MimeTypes;
|
||||||
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
@ -70,7 +72,7 @@ public final class TextRenderer extends BaseRenderer implements Callback {
|
||||||
|
|
||||||
private static final int MSG_UPDATE_OUTPUT = 0;
|
private static final int MSG_UPDATE_OUTPUT = 0;
|
||||||
|
|
||||||
private final Handler outputHandler;
|
private final @Nullable Handler outputHandler;
|
||||||
private final TextOutput output;
|
private final TextOutput output;
|
||||||
private final SubtitleDecoderFactory decoderFactory;
|
private final SubtitleDecoderFactory decoderFactory;
|
||||||
private final FormatHolder formatHolder;
|
private final FormatHolder formatHolder;
|
||||||
|
|
@ -87,30 +89,31 @@ public final class TextRenderer extends BaseRenderer implements Callback {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param output The output.
|
* @param output The output.
|
||||||
* @param outputLooper The looper associated with the thread on which the output should be
|
* @param outputLooper The looper associated with the thread on which the output should be called.
|
||||||
* called. If the output makes use of standard Android UI components, then this should
|
* If the output makes use of standard Android UI components, then this should normally be the
|
||||||
* normally be the looper associated with the application's main thread, which can be obtained
|
* looper associated with the application's main thread, which can be obtained using {@link
|
||||||
* using {@link android.app.Activity#getMainLooper()}. Null may be passed if the output
|
* android.app.Activity#getMainLooper()}. Null may be passed if the output should be called
|
||||||
* should be called directly on the player's internal rendering thread.
|
* directly on the player's internal rendering thread.
|
||||||
*/
|
*/
|
||||||
public TextRenderer(TextOutput output, Looper outputLooper) {
|
public TextRenderer(TextOutput output, @Nullable Looper outputLooper) {
|
||||||
this(output, outputLooper, SubtitleDecoderFactory.DEFAULT);
|
this(output, outputLooper, SubtitleDecoderFactory.DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param output The output.
|
* @param output The output.
|
||||||
* @param outputLooper The looper associated with the thread on which the output should be
|
* @param outputLooper The looper associated with the thread on which the output should be called.
|
||||||
* called. If the output makes use of standard Android UI components, then this should
|
* If the output makes use of standard Android UI components, then this should normally be the
|
||||||
* normally be the looper associated with the application's main thread, which can be obtained
|
* looper associated with the application's main thread, which can be obtained using {@link
|
||||||
* using {@link android.app.Activity#getMainLooper()}. Null may be passed if the output
|
* android.app.Activity#getMainLooper()}. Null may be passed if the output should be called
|
||||||
* should be called directly on the player's internal rendering thread.
|
* directly on the player's internal rendering thread.
|
||||||
* @param decoderFactory A factory from which to obtain {@link SubtitleDecoder} instances.
|
* @param decoderFactory A factory from which to obtain {@link SubtitleDecoder} instances.
|
||||||
*/
|
*/
|
||||||
public TextRenderer(TextOutput output, Looper outputLooper,
|
public TextRenderer(
|
||||||
SubtitleDecoderFactory decoderFactory) {
|
TextOutput output, @Nullable Looper outputLooper, SubtitleDecoderFactory decoderFactory) {
|
||||||
super(C.TRACK_TYPE_TEXT);
|
super(C.TRACK_TYPE_TEXT);
|
||||||
this.output = Assertions.checkNotNull(output);
|
this.output = Assertions.checkNotNull(output);
|
||||||
this.outputHandler = outputLooper == null ? null : new Handler(outputLooper, this);
|
this.outputHandler =
|
||||||
|
outputLooper == null ? null : Util.createHandler(outputLooper, /* callback= */ this);
|
||||||
this.decoderFactory = decoderFactory;
|
this.decoderFactory = decoderFactory;
|
||||||
formatHolder = new FormatHolder();
|
formatHolder = new FormatHolder();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@ import android.net.ConnectivityManager;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
@ -66,6 +68,7 @@ import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ThreadFactory;
|
import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
|
||||||
import org.checkerframework.checker.nullness.qual.PolyNull;
|
import org.checkerframework.checker.nullness.qual.PolyNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -237,12 +240,41 @@ public final class Util {
|
||||||
* @param length The output array length. Must be less or equal to the length of the input array.
|
* @param length The output array length. Must be less or equal to the length of the input array.
|
||||||
* @return The copied array.
|
* @return The copied array.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("nullness:assignment.type.incompatible")
|
@SuppressWarnings({"nullness:argument.type.incompatible", "nullness:return.type.incompatible"})
|
||||||
public static <T> T[] nullSafeArrayCopy(T[] input, int length) {
|
public static <T> T[] nullSafeArrayCopy(T[] input, int length) {
|
||||||
Assertions.checkArgument(length <= input.length);
|
Assertions.checkArgument(length <= input.length);
|
||||||
return Arrays.copyOf(input, length);
|
return Arrays.copyOf(input, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link Handler} with the specified {@link Handler.Callback} on the current {@link
|
||||||
|
* Looper} thread. The method accepts partially initialized objects as callback under the
|
||||||
|
* assumption that the Handler won't be used to send messages until the callback is fully
|
||||||
|
* initialized.
|
||||||
|
*
|
||||||
|
* @param callback A {@link Handler.Callback}. May be a partially initialized class.
|
||||||
|
* @return A {@link Handler} with the specified callback on the current {@link Looper} thread.
|
||||||
|
*/
|
||||||
|
public static Handler createHandler(Handler.@UnknownInitialization Callback callback) {
|
||||||
|
return createHandler(Looper.myLooper(), callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link Handler} with the specified {@link Handler.Callback} on the specified {@link
|
||||||
|
* Looper} thread. The method accepts partially initialized objects as callback under the
|
||||||
|
* assumption that the Handler won't be used to send messages until the callback is fully
|
||||||
|
* initialized.
|
||||||
|
*
|
||||||
|
* @param looper A {@link Looper} to run the callback on.
|
||||||
|
* @param callback A {@link Handler.Callback}. May be a partially initialized class.
|
||||||
|
* @return A {@link Handler} with the specified callback on the current {@link Looper} thread.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"nullness:argument.type.incompatible", "nullness:return.type.incompatible"})
|
||||||
|
public static Handler createHandler(
|
||||||
|
Looper looper, Handler.@UnknownInitialization Callback callback) {
|
||||||
|
return new Handler(looper, callback);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new single threaded executor whose thread has the specified name.
|
* Instantiates a new single threaded executor whose thread has the specified name.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -291,7 +291,7 @@ public final class VideoFrameReleaseTimeHelper {
|
||||||
sampledVsyncTimeNs = C.TIME_UNSET;
|
sampledVsyncTimeNs = C.TIME_UNSET;
|
||||||
choreographerOwnerThread = new HandlerThread("ChoreographerOwner:Handler");
|
choreographerOwnerThread = new HandlerThread("ChoreographerOwner:Handler");
|
||||||
choreographerOwnerThread.start();
|
choreographerOwnerThread.start();
|
||||||
handler = new Handler(choreographerOwnerThread.getLooper(), this);
|
handler = Util.createHandler(choreographerOwnerThread.getLooper(), /* callback= */ this);
|
||||||
handler.sendEmptyMessage(CREATE_CHOREOGRAPHER);
|
handler.sendEmptyMessage(CREATE_CHOREOGRAPHER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ import com.google.android.exoplayer2.source.chunk.Chunk;
|
||||||
import com.google.android.exoplayer2.source.dash.manifest.DashManifest;
|
import com.google.android.exoplayer2.source.dash.manifest.DashManifest;
|
||||||
import com.google.android.exoplayer2.upstream.Allocator;
|
import com.google.android.exoplayer2.upstream.Allocator;
|
||||||
import com.google.android.exoplayer2.util.ParsableByteArray;
|
import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||||
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -100,7 +101,6 @@ public final class PlayerEmsgHandler implements Handler.Callback {
|
||||||
* messages that generate DASH media source events.
|
* messages that generate DASH media source events.
|
||||||
* @param allocator An {@link Allocator} from which allocations can be obtained.
|
* @param allocator An {@link Allocator} from which allocations can be obtained.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("nullness")
|
|
||||||
public PlayerEmsgHandler(
|
public PlayerEmsgHandler(
|
||||||
DashManifest manifest, PlayerEmsgCallback playerEmsgCallback, Allocator allocator) {
|
DashManifest manifest, PlayerEmsgCallback playerEmsgCallback, Allocator allocator) {
|
||||||
this.manifest = manifest;
|
this.manifest = manifest;
|
||||||
|
|
@ -108,7 +108,7 @@ public final class PlayerEmsgHandler implements Handler.Callback {
|
||||||
this.allocator = allocator;
|
this.allocator = allocator;
|
||||||
|
|
||||||
manifestPublishTimeToExpiryTimeUs = new TreeMap<>();
|
manifestPublishTimeToExpiryTimeUs = new TreeMap<>();
|
||||||
handler = new Handler(this);
|
handler = Util.createHandler(/* callback= */ this);
|
||||||
decoder = new EventMessageDecoder();
|
decoder = new EventMessageDecoder();
|
||||||
lastLoadedChunkEndTimeUs = C.TIME_UNSET;
|
lastLoadedChunkEndTimeUs = C.TIME_UNSET;
|
||||||
lastLoadedChunkEndTimeBeforeRefreshUs = C.TIME_UNSET;
|
lastLoadedChunkEndTimeBeforeRefreshUs = C.TIME_UNSET;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue