Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 49f51ab

Browse files
author
Emmanuel Garcia
committed
document code
1 parent 21bb48c commit 49f51ab

File tree

1 file changed

+55
-44
lines changed

1 file changed

+55
-44
lines changed

shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java

Lines changed: 55 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@
5151
public class PlatformViewsController implements PlatformViewsAccessibilityDelegate {
5252
private static final String TAG = "PlatformViewsController";
5353

54-
// These view types allow to issue drawing commands directly without
55-
// notifying the Android view hierarchy that a change was made.
54+
// These view types allow out-of-band drawing operation that don't notify the Android view
55+
// hierarchy.
5656
// To support these cases, Flutter hosts the embedded view in a VirtualDisplay,
5757
// and binds the VirtualDisplay to a GL texture that is then composed by the engine.
5858
// Related issue: https://github.com/flutter/flutter/issues/103630
@@ -238,8 +238,15 @@ public long createForTextureLayer(
238238

239239
final int physicalWidth = toPhysicalPixels(request.logicalWidth);
240240
final int physicalHeight = toPhysicalPixels(request.logicalHeight);
241+
242+
// Case 1. Add the view to a virtual display if the embedded view contains any of the
243+
// VIEW_TYPES_REQUIRE_VD view types.
244+
// These views allow out-of-band graphics operations that aren't notified to the Android
245+
// view hierarchy via callbacks such as ViewParent#onDescendantInvalidated().
246+
// The virtual display is wired up to a GL texture that is composed by the Flutter engine.
241247
final boolean shouldUseVirtualDisplay =
242248
ViewUtils.hasChildViewOfType(embeddedView, VIEW_TYPES_REQUIRE_VD);
249+
243250
if (!usesSoftwareRendering && shouldUseVirtualDisplay) {
244251
Log.i(TAG, "Hosting view in a virtual display for platform view: " + viewId);
245252
// API level 20 is required to use VirtualDisplay#setSurface.
@@ -281,43 +288,42 @@ public long createForTextureLayer(
281288
return textureEntry.id();
282289
}
283290

291+
// Case 2. Attach the view to the Android view hierarchy and record their drawing
292+
// operations, so they can be forwarded to a GL texture that is composed by the
293+
// Flutter engine.
294+
284295
// API level 23 is required to use Surface#lockHardwareCanvas().
285296
ensureValidAndroidVersion(23);
286297
Log.i(TAG, "Hosting view in view hierarchy for platform view: " + viewId);
287298

288-
PlatformViewWrapper wrapperView;
299+
PlatformViewWrapper viewWrapper;
289300
long txId;
290301
if (usesSoftwareRendering) {
291-
wrapperView = new PlatformViewWrapper(context);
302+
viewWrapper = new PlatformViewWrapper(context);
292303
txId = -1;
293304
} else {
294305
final TextureRegistry.SurfaceTextureEntry textureEntry =
295306
textureRegistry.createSurfaceTexture();
296-
wrapperView = new PlatformViewWrapper(context, textureEntry);
307+
viewWrapper = new PlatformViewWrapper(context, textureEntry);
297308
txId = textureEntry.id();
298309
}
299-
wrapperView.setTouchProcessor(androidTouchProcessor);
300-
wrapperView.setBufferSize(physicalWidth, physicalHeight);
310+
viewWrapper.setTouchProcessor(androidTouchProcessor);
311+
viewWrapper.setBufferSize(physicalWidth, physicalHeight);
301312

302-
final FrameLayout.LayoutParams layoutParams =
313+
final FrameLayout.LayoutParams viewWrapperLayoutParams =
303314
new FrameLayout.LayoutParams(physicalWidth, physicalHeight);
304315

316+
// Size and position the view wrapper.
305317
final int physicalTop = toPhysicalPixels(request.logicalTop);
306318
final int physicalLeft = toPhysicalPixels(request.logicalLeft);
307-
layoutParams.topMargin = physicalTop;
308-
layoutParams.leftMargin = physicalLeft;
309-
wrapperView.setLayoutParams(layoutParams);
319+
viewWrapperLayoutParams.topMargin = physicalTop;
320+
viewWrapperLayoutParams.leftMargin = physicalLeft;
321+
viewWrapper.setLayoutParams(viewWrapperLayoutParams);
310322

311-
final View embeddedView = platformView.getView();
312-
if (embeddedView == null) {
313-
throw new IllegalStateException(
314-
"PlatformView#getView() returned null, but an Android view reference was expected.");
315-
} else if (embeddedView.getParent() != null) {
316-
throw new IllegalStateException(
317-
"The Android view returned from PlatformView#getView() was already added to a parent view.");
318-
}
323+
// Size the embedded view.
324+
// This isn't needed when the virtual display is used because the virtual display itself
325+
// is sized.
319326
embeddedView.setLayoutParams(new FrameLayout.LayoutParams(physicalWidth, physicalHeight));
320-
embeddedView.setLayoutDirection(request.direction);
321327

322328
// Accessibility in the embedded view is initially disabled because if a Flutter app
323329
// disabled accessibility in the first frame, the embedding won't receive an update to
@@ -329,17 +335,21 @@ public long createForTextureLayer(
329335
embeddedView.setImportantForAccessibility(
330336
View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
331337

332-
wrapperView.addView(embeddedView);
333-
wrapperView.setOnDescendantFocusChangeListener(
338+
// Add the embedded view to the wrapper.
339+
viewWrapper.addView(embeddedView);
340+
341+
// Listen for focus changed in any subview, so the framework is notified when the platform
342+
// view is focused.
343+
viewWrapper.setOnDescendantFocusChangeListener(
334344
(v, hasFocus) -> {
335345
if (hasFocus) {
336346
platformViewsChannel.invokeViewFocused(viewId);
337347
} else if (textInputPlugin != null) {
338348
textInputPlugin.clearPlatformViewClient(viewId);
339349
}
340350
});
341-
flutterView.addView(wrapperView);
342-
viewWrappers.append(viewId, wrapperView);
351+
flutterView.addView(viewWrapper);
352+
viewWrappers.append(viewId, viewWrapper);
343353
return txId;
344354
}
345355

@@ -404,18 +414,18 @@ public void offset(int viewId, double top, double left) {
404414
// texture
405415
// is positioned by the Flutter engine, which knows where to position different types of
406416
// layers.
407-
final PlatformViewWrapper wrapper = viewWrappers.get(viewId);
408-
if (wrapper == null) {
417+
final PlatformViewWrapper viewWrapper = viewWrappers.get(viewId);
418+
if (viewWrapper == null) {
409419
Log.e(TAG, "Setting offset for unknown platform view with id: " + viewId);
410420
return;
411421
}
412422
final int physicalTop = toPhysicalPixels(top);
413423
final int physicalLeft = toPhysicalPixels(left);
414424
final FrameLayout.LayoutParams layoutParams =
415-
(FrameLayout.LayoutParams) wrapper.getLayoutParams();
425+
(FrameLayout.LayoutParams) viewWrapper.getLayoutParams();
416426
layoutParams.topMargin = physicalTop;
417427
layoutParams.leftMargin = physicalLeft;
418-
wrapper.setLayoutParams(layoutParams);
428+
viewWrapper.setLayoutParams(layoutParams);
419429
}
420430

421431
@Override
@@ -446,8 +456,8 @@ public void resize(
446456
}
447457

448458
final PlatformView platformView = platformViews.get(viewId);
449-
final PlatformViewWrapper view = viewWrappers.get(viewId);
450-
if (platformView == null || view == null) {
459+
final PlatformViewWrapper viewWrapper = viewWrappers.get(viewId);
460+
if (platformView == null || viewWrapper == null) {
451461
Log.e(TAG, "Resizing unknown platform view with id: " + viewId);
452462
return;
453463
}
@@ -459,20 +469,21 @@ public void resize(
459469
// Resizing the texture causes pixel stretching since the size of the GL texture used in
460470
// the engine
461471
// is set by the framework, but the texture buffer size is set by the platform down below.
462-
if (physicalWidth > view.getBufferWidth() || physicalHeight > view.getBufferHeight()) {
463-
view.setBufferSize(physicalWidth, physicalHeight);
472+
if (physicalWidth > viewWrapper.getBufferWidth()
473+
|| physicalHeight > viewWrapper.getBufferHeight()) {
474+
viewWrapper.setBufferSize(physicalWidth, physicalHeight);
464475
}
465476

466-
final ViewGroup.LayoutParams viewWrapperLayoutParams = view.getLayoutParams();
467-
viewWrapperLayoutParams.width = newWidth;
468-
viewWrapperLayoutParams.height = newHeight;
469-
view.setLayoutParams(viewWrapperLayoutParams);
477+
final ViewGroup.LayoutParams viewWrapperLayoutParams = viewWrapper.getLayoutParams();
478+
viewWrapperLayoutParams.width = physicalWidth;
479+
viewWrapperLayoutParams.height = physicalHeight;
480+
viewWrapper.setLayoutParams(viewWrapperLayoutParams);
470481

471482
final View embeddedView = platformView.getView();
472483
if (embeddedView != null) {
473484
final ViewGroup.LayoutParams embeddedViewLayoutParams = embeddedView.getLayoutParams();
474-
embeddedViewLayoutParams.width = newWidth;
475-
embeddedViewLayoutParams.height = newHeight;
485+
embeddedViewLayoutParams.width = physicalWidth;
486+
embeddedViewLayoutParams.height = physicalHeight;
476487
embeddedView.setLayoutParams(embeddedViewLayoutParams);
477488
}
478489
onComplete.run(
@@ -520,12 +531,12 @@ public void setDirection(int viewId, int direction) {
520531
Log.e(TAG, "Setting direction to an unknown view with id: " + viewId);
521532
return;
522533
}
523-
final View view = platformView.getView();
524-
if (view == null) {
534+
final View embeddedView = platformView.getView();
535+
if (embeddedView == null) {
525536
Log.e(TAG, "Setting direction to a null view with id: " + viewId);
526537
return;
527538
}
528-
view.setLayoutDirection(direction);
539+
embeddedView.setLayoutDirection(direction);
529540
}
530541

531542
@Override
@@ -535,12 +546,12 @@ public void clearFocus(int viewId) {
535546
Log.e(TAG, "Clearing focus on an unknown view with id: " + viewId);
536547
return;
537548
}
538-
final View view = platformView.getView();
539-
if (view == null) {
549+
final View embeddedView = platformView.getView();
550+
if (embeddedView == null) {
540551
Log.e(TAG, "Clearing focus on a null view with id: " + viewId);
541552
return;
542553
}
543-
view.clearFocus();
554+
embeddedView.clearFocus();
544555
}
545556

546557
private void ensureValidAndroidVersion(int minSdkVersion) {

0 commit comments

Comments
 (0)