mirror of
https://github.com/samsonjs/media.git
synced 2026-04-16 13:05:46 +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.Looper;
|
||||
import android.os.Message;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.BaseRenderer;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.FormatHolder;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
|
|
@ -46,7 +48,7 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
|
|||
|
||||
private final MetadataDecoderFactory decoderFactory;
|
||||
private final MetadataOutput output;
|
||||
private final Handler outputHandler;
|
||||
private final @Nullable Handler outputHandler;
|
||||
private final FormatHolder formatHolder;
|
||||
private final MetadataInputBuffer buffer;
|
||||
private final Metadata[] pendingMetadata;
|
||||
|
|
@ -61,11 +63,11 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
|
|||
* @param output The output.
|
||||
* @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
|
||||
* looper associated with the application's main thread, which can be obtained using
|
||||
* {@link android.app.Activity#getMainLooper()}. Null may be passed if the output should be
|
||||
* called directly on the player's internal rendering thread.
|
||||
* looper associated with the application's main thread, which can be obtained using {@link
|
||||
* android.app.Activity#getMainLooper()}. Null may be passed if the output should be called
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
|
@ -73,16 +75,17 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
|
|||
* @param output The output.
|
||||
* @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
|
||||
* looper associated with the application's main thread, which can be obtained using
|
||||
* {@link android.app.Activity#getMainLooper()}. Null may be passed if the output should be
|
||||
* called directly on the player's internal rendering thread.
|
||||
* looper associated with the application's main thread, which can be obtained using {@link
|
||||
* android.app.Activity#getMainLooper()}. Null may be passed if the output should be called
|
||||
* directly on the player's internal rendering thread.
|
||||
* @param decoderFactory A factory from which to obtain {@link MetadataDecoder} instances.
|
||||
*/
|
||||
public MetadataRenderer(MetadataOutput output, Looper outputLooper,
|
||||
MetadataDecoderFactory decoderFactory) {
|
||||
public MetadataRenderer(
|
||||
MetadataOutput output, @Nullable Looper outputLooper, MetadataDecoderFactory decoderFactory) {
|
||||
super(C.TRACK_TYPE_METADATA);
|
||||
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);
|
||||
formatHolder = new FormatHolder();
|
||||
buffer = new MetadataInputBuffer();
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import android.os.Handler.Callback;
|
|||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.BaseRenderer;
|
||||
import com.google.android.exoplayer2.C;
|
||||
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.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
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 final Handler outputHandler;
|
||||
private final @Nullable Handler outputHandler;
|
||||
private final TextOutput output;
|
||||
private final SubtitleDecoderFactory decoderFactory;
|
||||
private final FormatHolder formatHolder;
|
||||
|
|
@ -87,30 +89,31 @@ public final class TextRenderer extends BaseRenderer implements Callback {
|
|||
|
||||
/**
|
||||
* @param output The output.
|
||||
* @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 looper associated with the application's main thread, which can be obtained
|
||||
* using {@link android.app.Activity#getMainLooper()}. Null may be passed if the output
|
||||
* should be called directly on the player's internal rendering thread.
|
||||
* @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
|
||||
* looper associated with the application's main thread, which can be obtained using {@link
|
||||
* android.app.Activity#getMainLooper()}. Null may be passed if the output should be called
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param output The output.
|
||||
* @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 looper associated with the application's main thread, which can be obtained
|
||||
* using {@link android.app.Activity#getMainLooper()}. Null may be passed if the output
|
||||
* should be called directly on the player's internal rendering thread.
|
||||
* @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
|
||||
* looper associated with the application's main thread, which can be obtained using {@link
|
||||
* android.app.Activity#getMainLooper()}. Null may be passed if the output should be called
|
||||
* directly on the player's internal rendering thread.
|
||||
* @param decoderFactory A factory from which to obtain {@link SubtitleDecoder} instances.
|
||||
*/
|
||||
public TextRenderer(TextOutput output, Looper outputLooper,
|
||||
SubtitleDecoderFactory decoderFactory) {
|
||||
public TextRenderer(
|
||||
TextOutput output, @Nullable Looper outputLooper, SubtitleDecoderFactory decoderFactory) {
|
||||
super(C.TRACK_TYPE_TEXT);
|
||||
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;
|
||||
formatHolder = new FormatHolder();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ import android.net.ConnectivityManager;
|
|||
import android.net.NetworkInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Parcel;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
|
@ -66,6 +68,7 @@ import java.util.concurrent.Executors;
|
|||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
|
||||
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.
|
||||
* @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) {
|
||||
Assertions.checkArgument(length <= 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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -291,7 +291,7 @@ public final class VideoFrameReleaseTimeHelper {
|
|||
sampledVsyncTimeNs = C.TIME_UNSET;
|
||||
choreographerOwnerThread = new HandlerThread("ChoreographerOwner:Handler");
|
||||
choreographerOwnerThread.start();
|
||||
handler = new Handler(choreographerOwnerThread.getLooper(), this);
|
||||
handler = Util.createHandler(choreographerOwnerThread.getLooper(), /* callback= */ this);
|
||||
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.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
|
@ -100,7 +101,6 @@ public final class PlayerEmsgHandler implements Handler.Callback {
|
|||
* messages that generate DASH media source events.
|
||||
* @param allocator An {@link Allocator} from which allocations can be obtained.
|
||||
*/
|
||||
@SuppressWarnings("nullness")
|
||||
public PlayerEmsgHandler(
|
||||
DashManifest manifest, PlayerEmsgCallback playerEmsgCallback, Allocator allocator) {
|
||||
this.manifest = manifest;
|
||||
|
|
@ -108,7 +108,7 @@ public final class PlayerEmsgHandler implements Handler.Callback {
|
|||
this.allocator = allocator;
|
||||
|
||||
manifestPublishTimeToExpiryTimeUs = new TreeMap<>();
|
||||
handler = new Handler(this);
|
||||
handler = Util.createHandler(/* callback= */ this);
|
||||
decoder = new EventMessageDecoder();
|
||||
lastLoadedChunkEndTimeUs = C.TIME_UNSET;
|
||||
lastLoadedChunkEndTimeBeforeRefreshUs = C.TIME_UNSET;
|
||||
|
|
|
|||
Loading…
Reference in a new issue