Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ios platform view] fix overlay zPosition #29930

Merged
merged 8 commits into from
Dec 8, 2021

Conversation

cyanglaz
Copy link
Contributor

Explicitly set every platform view and overlay view's zPosition so we are sure the overlays are on top of the platform views.

Fixes: flutter/flutter#86787

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide and the C++, Objective-C, Java style guides.
  • I listed at least one issue that this PR fixes in the description above.
  • I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test-exempt. See testing the engine for instructions on
    writing and running engine tests.
  • I updated/added relevant documentation (doc comments with ///).
  • I signed the CLA.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

Comment on lines 569 to 570
// Clear the `active_composition_order_`, which will be populated down below.
active_composition_order_.clear();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mistaken edits?

@@ -765,6 +765,84 @@ class TwoPlatformViewsWithOtherBackDropFilter extends Scenario with _BasePlatfor
}
}

/// Builds a scenario where many platform views are scrolling and pass under a widget
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: there's no concept of widget in these tests

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

PlatformViewScrollingUnderWidget(PlatformDispatcher dispatcher, {required this.minId, required this.maxId})
: assert(dispatcher != null),
super(dispatcher) {
for (int i = minId; i < maxId+1; i ++) {
Copy link

@blasten blasten Nov 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for (int i = minId; i < maxId+1; i ++) {
for (int i = minId; i <= maxId; i++) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}

/// The platform view identifier to use for the first platform view.
final int minId;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not starting with 0?

}

@override
void onDrawFrame() {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you found an minimal sequence of events that yields into the issue? If possible, it would be preferred.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only time I can repro this issue is scroll very fast.

}

// Wait and let the scenario app scroll a bit.
sleep(5);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not sleep the main thread, even in XCUITests where it's running in a different process than the app. It may cause strange timeout behavior.

Instead, leverage the XCTest wait: https://stackoverflow.com/a/50248104

}

/// The platform view identifier to use for the first platform view.
final int minId;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you name these better instead of putting the important info in the comment? firstPlatformViewId?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


void _buildOneFrame(double offset) {
const double cellWidth = 1000;
print(offset);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove print.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -765,6 +765,84 @@ class TwoPlatformViewsWithOtherBackDropFilter extends Scenario with _BasePlatfor
}
}

/// Builds a scenario where many platform views are scrolling and pass under a widget
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

PlatformViewScrollingUnderWidget(PlatformDispatcher dispatcher, {required this.minId, required this.maxId})
: assert(dispatcher != null),
super(dispatcher) {
for (int i = minId; i < maxId+1; i ++) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}

/// The platform view identifier to use for the first platform view.
final int minId;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}

/// The platform view identifier to use for the first platform view.
final int minId;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}

@override
void onDrawFrame() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only time I can repro this issue is scroll very fast.


void _buildOneFrame(double offset) {
const double cellWidth = 1000;
print(offset);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -32,7 +32,7 @@ class PlatformViewScenario extends Scenario with _BasePlatformViewScenarioMixin
/// Creates the PlatformView scenario.
///
/// The [dispatcher] parameter must not be null.
PlatformViewScenario(PlatformDispatcher dispatcher, String text, { required this.id })
PlatformViewScenario(PlatformDispatcher dispatcher, String text, {required this.id})
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My formatter just did some auto formatting, which I think is good.

@cyanglaz
Copy link
Contributor Author

Updated per comments.

Copy link
Member

@jmagman jmagman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@cyanglaz
Copy link
Contributor Author

cyanglaz commented Dec 2, 2021

@blasten PTAL :)


XCUIElement* platformView = app.textViews.firstMatch;
BOOL exists = [platformView waitForExistenceWithTimeout:kSecondsToWaitForPlatformView];
if (!exists) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can it also check for the zPosition since that seems to be the bug?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK, XCUITest doesn't have access to the actual layers. I also did a light research and couldn't find anything online. :(

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, these integration tests are black box, you don't have access to the app layers, just the accessibility hooks. A verification like that would need to happen in a XCTest unit test.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right. If the bug is that the zPosition was miscalculated, then the test would need to ensure the correct values.

I did something similar with the UIView in https://github.com/flutter/engine/blob/104e21d941fc8aed1073c6caaae71cf944837256/testing/scenario_app/ios/Scenarios/ScenariosUITests/UnobstructedPlatformViewTests.m

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, XCUITest can access the frame (I believe it is the accessiblyElement's frame, not UIView's frame, they are the same value by default but could actually be different depending on the implementation). I believe accessiblyElement doesn't have any knowledge on the zIndex.

The current test we have will crash if the zIndex is incorrect because of the DCHECK that I added (only on debug_unopt build, which is the one we use on CI)

I agree a better test would involve directly examine the zIndex value. This will require an XCTest. We then need to create a fake where the RTree thinks there's a picture layer on top of platform views. I don't think there's a way to do so in the current API set up?

One way to do it might be refactor the PlatformViewsController's implementation, introduce a mockable API, so we can mock and force to create overlays.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought an incorrect z index will make the tests fail in https://github.com/flutter/engine/blob/104e21d941fc8aed1073c6caaae71cf944837256/testing/scenario_app/ios/Scenarios/ScenariosUITests/UnobstructedPlatformViewTests.m

If you don't set zPosition, are there any test failures?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which test would fail? I might be missing something but the tests in https://github.com/flutter/engine/blob/104e21d941fc8aed1073c6caaae71cf944837256/testing/scenario_app/ios/Scenarios/ScenariosUITests/UnobstructedPlatformViewTests.m are not checking zPosition or anything related to it right?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There’s a comment about z index in that file. I remember the index being determined from the position of the layer in the tree I believe

@cyanglaz cyanglaz requested a review from blasten December 6, 2021 18:04
Copy link

@blasten blasten left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@cyanglaz cyanglaz added the waiting for tree to go green This PR is approved and tested, but waiting for the tree to be green to land. label Dec 8, 2021
@fluttergithubbot fluttergithubbot merged commit 6981c04 into flutter:main Dec 8, 2021
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Dec 8, 2021
zanderso pushed a commit to flutter/flutter that referenced this pull request Dec 8, 2021
* 9b74c21 Run iOS scenario apps on iPhone 11 and iOS 14 (flutter/engine#30104)

* 4108898 Add error handler for os.rmtree calls (flutter/engine#30169)

* 55c5e56 Don't run curl in verbose mode when --verbose set (flutter/engine#30170)

* a1fe531 Win32: Implement DispatchAccessibilityAction (flutter/engine#30187)

* a7a8024 Update buildroot to db6d037a778930ad9 (ToT). (flutter/engine#30171)

* 7ccf290 Revert "Run iOS scenario apps on iPhone 11 and iOS 14 (#30104)" (flutter/engine#30193)

* 1313e73 Add unconditional waits on fml::Semaphore. (flutter/engine#30165)

* 094ff9e Roll Fuchsia Mac SDK from EAlr46NQ8... to zMg5gNi2E... (flutter/engine#30190)

* a572ab5 Roll Fuchsia Linux SDK from WGMjaVH60... to s03VQc7lX... (flutter/engine#30191)

* 07c6f41 Roll Skia from f333f5614a9b to 06f3d68627c2 (24 revisions) (flutter/engine#30192)

* 8796f0f Update Swiftshader to dc0f131930 (flutter/engine#30188)

* c1e235d Add length guard to fix Windows build with VS2019 16.11.7 headers (flutter/engine#30189)

* 7831529 Roll Skia from 06f3d68627c2 to 1c4cf27965bd (2 revisions) (flutter/engine#30194)

* 5672f9e Document rationale for Dart VM flag prefix match (flutter/engine#30195)

* 1c10e68 Roll buildroot to 430b57c643883e6090b5af09faddd8048efee57c. (flutter/engine#30197)

* e32d04a Roll Skia from 1c4cf27965bd to 543b8681c7f2 (1 revision) (flutter/engine#30198)

* 6981c04 [ios platform view] fix overlay zPosition (flutter/engine#29930)

* efaccf0 renew cirrus key (flutter/engine#30186)

* 9b80c08 Roll Skia from 543b8681c7f2 to 00edeefab7f4 (1 revision) (flutter/engine#30200)

* 164045d Roll Fuchsia Mac SDK from zMg5gNi2E... to QeaP059wu... (flutter/engine#30203)

* 83b84d3 Roll Skia from 00edeefab7f4 to 21b8ccb7393c (3 revisions) (flutter/engine#30206)
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Dec 8, 2021
@cyanglaz cyanglaz deleted the platform_view_flash branch December 8, 2021 18:44
yx-mike added a commit to yx-mike/engine that referenced this pull request Jan 12, 2022
yx-mike added a commit to yx-mike/engine that referenced this pull request Jan 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes platform-ios waiting for tree to go green This PR is approved and tested, but waiting for the tree to be green to land.
Projects
None yet
4 participants