Skip to content

Commit b2530f5

Browse files
[video_player] Separate texture ID on Android (#10029)
Cleans up the tech debt of having two different methods of generating player IDs on Andoird, as was recently done on iOS. The current code was a result of adding non-texture-based players without refactoring the Dart<->Java communication, and relied on knowing that the engine assigned texture IDs by increasing an incrementing value. This fully separates texture IDs from player IDs, so that the plugin can fully control player ID management without relying on engine internals. This also brings the Android and iOS implementations into better alignment, so that they don't have differences that aren't related to the platforms themselves. Follow-up to work done for flutter/flutter#86613 Prep for flutter/flutter#172763 ## Pre-Review Checklist [^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
1 parent 0158ffb commit b2530f5

File tree

10 files changed

+527
-289
lines changed

10 files changed

+527
-289
lines changed

packages/video_player/video_player_android/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 2.8.14
2+
3+
* Restructures internal logic for player creation and tracking.
4+
15
## 2.8.13
26

37
* Bumps com.android.tools.build:gradle to 8.12.1.

packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java

Lines changed: 145 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -65,18 +65,6 @@ protected static ArrayList<Object> wrapError(@NonNull Throwable exception) {
6565
@Retention(CLASS)
6666
@interface CanIgnoreReturnValue {}
6767

68-
/** Pigeon equivalent of VideoViewType. */
69-
public enum PlatformVideoViewType {
70-
TEXTURE_VIEW(0),
71-
PLATFORM_VIEW(1);
72-
73-
final int index;
74-
75-
PlatformVideoViewType(final int index) {
76-
this.index = index;
77-
}
78-
}
79-
8068
/** Pigeon equivalent of video_platform_interface's VideoFormat. */
8169
public enum PlatformVideoFormat {
8270
DASH(0),
@@ -163,7 +151,7 @@ ArrayList<Object> toList() {
163151
}
164152

165153
/** Generated class from Pigeon that represents data sent in messages. */
166-
public static final class CreateMessage {
154+
public static final class CreationOptions {
167155
private @NonNull String uri;
168156

169157
public @NonNull String getUri() {
@@ -210,18 +198,8 @@ public void setUserAgent(@Nullable String setterArg) {
210198
this.userAgent = setterArg;
211199
}
212200

213-
private @Nullable PlatformVideoViewType viewType;
214-
215-
public @Nullable PlatformVideoViewType getViewType() {
216-
return viewType;
217-
}
218-
219-
public void setViewType(@Nullable PlatformVideoViewType setterArg) {
220-
this.viewType = setterArg;
221-
}
222-
223201
/** Constructor is non-public to enforce null safety; use Builder. */
224-
CreateMessage() {}
202+
CreationOptions() {}
225203

226204
@Override
227205
public boolean equals(Object o) {
@@ -231,17 +209,16 @@ public boolean equals(Object o) {
231209
if (o == null || getClass() != o.getClass()) {
232210
return false;
233211
}
234-
CreateMessage that = (CreateMessage) o;
212+
CreationOptions that = (CreationOptions) o;
235213
return uri.equals(that.uri)
236214
&& Objects.equals(formatHint, that.formatHint)
237215
&& httpHeaders.equals(that.httpHeaders)
238-
&& Objects.equals(userAgent, that.userAgent)
239-
&& Objects.equals(viewType, that.viewType);
216+
&& Objects.equals(userAgent, that.userAgent);
240217
}
241218

242219
@Override
243220
public int hashCode() {
244-
return Objects.hash(uri, formatHint, httpHeaders, userAgent, viewType);
221+
return Objects.hash(uri, formatHint, httpHeaders, userAgent);
245222
}
246223

247224
public static final class Builder {
@@ -278,38 +255,28 @@ public static final class Builder {
278255
return this;
279256
}
280257

281-
private @Nullable PlatformVideoViewType viewType;
282-
283-
@CanIgnoreReturnValue
284-
public @NonNull Builder setViewType(@Nullable PlatformVideoViewType setterArg) {
285-
this.viewType = setterArg;
286-
return this;
287-
}
288-
289-
public @NonNull CreateMessage build() {
290-
CreateMessage pigeonReturn = new CreateMessage();
258+
public @NonNull CreationOptions build() {
259+
CreationOptions pigeonReturn = new CreationOptions();
291260
pigeonReturn.setUri(uri);
292261
pigeonReturn.setFormatHint(formatHint);
293262
pigeonReturn.setHttpHeaders(httpHeaders);
294263
pigeonReturn.setUserAgent(userAgent);
295-
pigeonReturn.setViewType(viewType);
296264
return pigeonReturn;
297265
}
298266
}
299267

300268
@NonNull
301269
ArrayList<Object> toList() {
302-
ArrayList<Object> toListResult = new ArrayList<>(5);
270+
ArrayList<Object> toListResult = new ArrayList<>(4);
303271
toListResult.add(uri);
304272
toListResult.add(formatHint);
305273
toListResult.add(httpHeaders);
306274
toListResult.add(userAgent);
307-
toListResult.add(viewType);
308275
return toListResult;
309276
}
310277

311-
static @NonNull CreateMessage fromList(@NonNull ArrayList<Object> pigeonVar_list) {
312-
CreateMessage pigeonResult = new CreateMessage();
278+
static @NonNull CreationOptions fromList(@NonNull ArrayList<Object> pigeonVar_list) {
279+
CreationOptions pigeonResult = new CreationOptions();
313280
Object uri = pigeonVar_list.get(0);
314281
pigeonResult.setUri((String) uri);
315282
Object formatHint = pigeonVar_list.get(1);
@@ -318,8 +285,98 @@ ArrayList<Object> toList() {
318285
pigeonResult.setHttpHeaders((Map<String, String>) httpHeaders);
319286
Object userAgent = pigeonVar_list.get(3);
320287
pigeonResult.setUserAgent((String) userAgent);
321-
Object viewType = pigeonVar_list.get(4);
322-
pigeonResult.setViewType((PlatformVideoViewType) viewType);
288+
return pigeonResult;
289+
}
290+
}
291+
292+
/** Generated class from Pigeon that represents data sent in messages. */
293+
public static final class TexturePlayerIds {
294+
private @NonNull Long playerId;
295+
296+
public @NonNull Long getPlayerId() {
297+
return playerId;
298+
}
299+
300+
public void setPlayerId(@NonNull Long setterArg) {
301+
if (setterArg == null) {
302+
throw new IllegalStateException("Nonnull field \"playerId\" is null.");
303+
}
304+
this.playerId = setterArg;
305+
}
306+
307+
private @NonNull Long textureId;
308+
309+
public @NonNull Long getTextureId() {
310+
return textureId;
311+
}
312+
313+
public void setTextureId(@NonNull Long setterArg) {
314+
if (setterArg == null) {
315+
throw new IllegalStateException("Nonnull field \"textureId\" is null.");
316+
}
317+
this.textureId = setterArg;
318+
}
319+
320+
/** Constructor is non-public to enforce null safety; use Builder. */
321+
TexturePlayerIds() {}
322+
323+
@Override
324+
public boolean equals(Object o) {
325+
if (this == o) {
326+
return true;
327+
}
328+
if (o == null || getClass() != o.getClass()) {
329+
return false;
330+
}
331+
TexturePlayerIds that = (TexturePlayerIds) o;
332+
return playerId.equals(that.playerId) && textureId.equals(that.textureId);
333+
}
334+
335+
@Override
336+
public int hashCode() {
337+
return Objects.hash(playerId, textureId);
338+
}
339+
340+
public static final class Builder {
341+
342+
private @Nullable Long playerId;
343+
344+
@CanIgnoreReturnValue
345+
public @NonNull Builder setPlayerId(@NonNull Long setterArg) {
346+
this.playerId = setterArg;
347+
return this;
348+
}
349+
350+
private @Nullable Long textureId;
351+
352+
@CanIgnoreReturnValue
353+
public @NonNull Builder setTextureId(@NonNull Long setterArg) {
354+
this.textureId = setterArg;
355+
return this;
356+
}
357+
358+
public @NonNull TexturePlayerIds build() {
359+
TexturePlayerIds pigeonReturn = new TexturePlayerIds();
360+
pigeonReturn.setPlayerId(playerId);
361+
pigeonReturn.setTextureId(textureId);
362+
return pigeonReturn;
363+
}
364+
}
365+
366+
@NonNull
367+
ArrayList<Object> toList() {
368+
ArrayList<Object> toListResult = new ArrayList<>(2);
369+
toListResult.add(playerId);
370+
toListResult.add(textureId);
371+
return toListResult;
372+
}
373+
374+
static @NonNull TexturePlayerIds fromList(@NonNull ArrayList<Object> pigeonVar_list) {
375+
TexturePlayerIds pigeonResult = new TexturePlayerIds();
376+
Object playerId = pigeonVar_list.get(0);
377+
pigeonResult.setPlayerId((Long) playerId);
378+
Object textureId = pigeonVar_list.get(1);
379+
pigeonResult.setTextureId((Long) textureId);
323380
return pigeonResult;
324381
}
325382
}
@@ -427,19 +484,16 @@ private PigeonCodec() {}
427484
protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) {
428485
switch (type) {
429486
case (byte) 129:
430-
{
431-
Object value = readValue(buffer);
432-
return value == null ? null : PlatformVideoViewType.values()[((Long) value).intValue()];
433-
}
434-
case (byte) 130:
435487
{
436488
Object value = readValue(buffer);
437489
return value == null ? null : PlatformVideoFormat.values()[((Long) value).intValue()];
438490
}
439-
case (byte) 131:
491+
case (byte) 130:
440492
return PlatformVideoViewCreationParams.fromList((ArrayList<Object>) readValue(buffer));
493+
case (byte) 131:
494+
return CreationOptions.fromList((ArrayList<Object>) readValue(buffer));
441495
case (byte) 132:
442-
return CreateMessage.fromList((ArrayList<Object>) readValue(buffer));
496+
return TexturePlayerIds.fromList((ArrayList<Object>) readValue(buffer));
443497
case (byte) 133:
444498
return PlaybackState.fromList((ArrayList<Object>) readValue(buffer));
445499
default:
@@ -449,18 +503,18 @@ protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) {
449503

450504
@Override
451505
protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) {
452-
if (value instanceof PlatformVideoViewType) {
506+
if (value instanceof PlatformVideoFormat) {
453507
stream.write(129);
454-
writeValue(stream, value == null ? null : ((PlatformVideoViewType) value).index);
455-
} else if (value instanceof PlatformVideoFormat) {
456-
stream.write(130);
457508
writeValue(stream, value == null ? null : ((PlatformVideoFormat) value).index);
458509
} else if (value instanceof PlatformVideoViewCreationParams) {
459-
stream.write(131);
510+
stream.write(130);
460511
writeValue(stream, ((PlatformVideoViewCreationParams) value).toList());
461-
} else if (value instanceof CreateMessage) {
512+
} else if (value instanceof CreationOptions) {
513+
stream.write(131);
514+
writeValue(stream, ((CreationOptions) value).toList());
515+
} else if (value instanceof TexturePlayerIds) {
462516
stream.write(132);
463-
writeValue(stream, ((CreateMessage) value).toList());
517+
writeValue(stream, ((TexturePlayerIds) value).toList());
464518
} else if (value instanceof PlaybackState) {
465519
stream.write(133);
466520
writeValue(stream, ((PlaybackState) value).toList());
@@ -476,7 +530,10 @@ public interface AndroidVideoPlayerApi {
476530
void initialize();
477531

478532
@NonNull
479-
Long create(@NonNull CreateMessage msg);
533+
Long createForPlatformView(@NonNull CreationOptions options);
534+
535+
@NonNull
536+
TexturePlayerIds createForTextureView(@NonNull CreationOptions options);
480537

481538
void dispose(@NonNull Long playerId);
482539

@@ -530,17 +587,42 @@ static void setUp(
530587
BasicMessageChannel<Object> channel =
531588
new BasicMessageChannel<>(
532589
binaryMessenger,
533-
"dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.create"
590+
"dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.createForPlatformView"
591+
+ messageChannelSuffix,
592+
getCodec());
593+
if (api != null) {
594+
channel.setMessageHandler(
595+
(message, reply) -> {
596+
ArrayList<Object> wrapped = new ArrayList<>();
597+
ArrayList<Object> args = (ArrayList<Object>) message;
598+
CreationOptions optionsArg = (CreationOptions) args.get(0);
599+
try {
600+
Long output = api.createForPlatformView(optionsArg);
601+
wrapped.add(0, output);
602+
} catch (Throwable exception) {
603+
wrapped = wrapError(exception);
604+
}
605+
reply.reply(wrapped);
606+
});
607+
} else {
608+
channel.setMessageHandler(null);
609+
}
610+
}
611+
{
612+
BasicMessageChannel<Object> channel =
613+
new BasicMessageChannel<>(
614+
binaryMessenger,
615+
"dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.createForTextureView"
534616
+ messageChannelSuffix,
535617
getCodec());
536618
if (api != null) {
537619
channel.setMessageHandler(
538620
(message, reply) -> {
539621
ArrayList<Object> wrapped = new ArrayList<>();
540622
ArrayList<Object> args = (ArrayList<Object>) message;
541-
CreateMessage msgArg = (CreateMessage) args.get(0);
623+
CreationOptions optionsArg = (CreationOptions) args.get(0);
542624
try {
543-
Long output = api.create(msgArg);
625+
TexturePlayerIds output = api.createForTextureView(optionsArg);
544626
wrapped.add(0, output);
545627
} catch (Throwable exception) {
546628
wrapped = wrapError(exception);

0 commit comments

Comments
 (0)