Skip to content

[Fireperf][AASA] FirstDrawDoneListener #4041

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

Merged
merged 15 commits into from
Sep 2, 2022
Merged

[Fireperf][AASA] FirstDrawDoneListener #4041

merged 15 commits into from
Sep 2, 2022

Conversation

leotianlizhan
Copy link
Contributor

b/243538554

@github-actions
Copy link
Contributor

github-actions bot commented Aug 29, 2022

Unit Test Results

973 tests  +4   973 ✔️ +4   1m 42s ⏱️ +30s
  51 suites +1       0 💤 ±0 
  51 files   +1       0 ±0 

Results for commit 95990a6. ± Comparison against base commit 3f13291.

♻️ This comment has been updated with latest results.

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Aug 29, 2022

Coverage Report 1

Affected Products

  • firebase-perf

    Overall coverage changed from 71.37% (53c0e1d) to 71.43% (d158f9f) by +0.06%.

    FilenameBase (53c0e1d)Merge (d158f9f)Diff
    FirstDrawDoneListener.java?85.19%?

Test Logs

Notes

  • Commit (d158f9f) is created by Prow via merging PR base commit (53c0e1d) and head commit (95990a6).
  • Run gradle <product>:checkCoverage to produce HTML coverage reports locally. After gradle commands finished, report files can be found under <product-build-dir>/reports/jacoco/.

  1. https://storage.googleapis.com/firebase-sdk-metric-reports/kqod0FVw1S.html

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Aug 29, 2022

Size Report 1

Affected Products

  • firebase-perf

    TypeBase (53c0e1d)Merge (d158f9f)Diff
    aar311 kB313 kB+2.42 kB (+0.8%)
    apk (release)2.48 MB2.48 MB+428 B (+0.0%)

Test Logs

Notes

  1. https://storage.googleapis.com/firebase-sdk-metric-reports/Izw8s6vrk9.html

@leotianlizhan leotianlizhan changed the title [Fireperf][AASA] FirstDrawDownListener [Fireperf][AASA] FirstDrawDoneListener Aug 30, 2022
// Handle bug prior to API 26 where OnDrawListener from the floating ViewTreeObserver is not
// merged into the real ViewTreeObserver.
// https://android.googlesource.com/platform/frameworks/base/+/9f8ec54244a5e0343b9748db3329733f259604f3
if (Build.VERSION.SDK_INT >= 26
Copy link
Member

Choose a reason for hiding this comment

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

nit: I recommend flipping the cases around so we are checking for special cases first then falling through to the default. This also moves the comment to be close to the specific case it's referring to.

if (Build.VERSION.SDK_INT < 26 && (!view.getViewTreeObserver().isAlive() || view.getWindowToken() == null) {
  view.addOnAttachStateChangeListener(...)
  return;
}
view.getViewTreeObserver()....

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

assertThat(listOfListeners).isNotNull();
assertThat(listOfListeners.size()).isEqualTo(1);

// OnDrawListener is not registered, it is delayed for later
Copy link
Member

Choose a reason for hiding this comment

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

Can we test that it is registered later on a state change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't see a way to do it because View class doesn't have public View.dispatchAttachView() unlike the other listeners we have for ViewTreeObserver (ViewTreeObserver.dispatchOnDraw() and ViewTreeObserver.dispatchOnGlobalLayout()), and although there's a private View.dispatchAttachView() it uses parameter classes that are also not visible to us.

Copy link
Contributor

Choose a reason for hiding this comment

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

+1 to Raymond's ask. Currently, the test does not do much validate the listener registration for API < 26.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Figured out a way to do it through reflection, PTAL @visumickey @raymondlam

}

@Test
@Config(sdk = 26)
Copy link
Member

Choose a reason for hiding this comment

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

Can we have a test for un-registering itself in Config(sdk=25) for both OnAttachStateChangeListener and OnDrawListener?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I only added @Config(sdk = 26) for this test because it uses reflection, so I don't know if in the future Android will change field names or refactor ViewTreeObserver.

The < API 26 bug is that adding OnDrawListeners to ViewTreeObserver doesn't work, it has nothing to do with removing or the listener itself, so I don't think we need to test unregistering for 2 different versions.

Copy link
Member

Choose a reason for hiding this comment

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

For the < API 26 bug, we should be making sure that we have a test to make sure that if we do register a View.OnAttachStateChangeListener, that it is unregistered once onViewAttachedToWindow is called. Otherwise, we could change the code to leave it registered and the tests would still pass.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, I see what you mean. That is difficult for the same reason as the other comment: View class doesn't have public, easy to use dispatchXYZ() methods like ViewTreeObserver does.

Copy link
Member

Choose a reason for hiding this comment

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

Could you use a FakeView or mock the View object? This way you have access to the listeners and can trigger the interfaces directly.

Copy link
Contributor Author

@leotianlizhan leotianlizhan Sep 1, 2022

Choose a reason for hiding this comment

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

Added a check at the last line of registerForNextDraw_delaysAddingListenerForAPIsBelow26().

@leotianlizhan
Copy link
Contributor Author

/test smoke-tests


@Override
public void onDraw() {
// Prevent 2nd draw and on from triggering onDraw
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Fix comment. The comment is a bit hard to parse.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

reworded, PTAL @visumickey

// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.firebase.perf.util;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Is there a better package where we drop this in? Util is too open and overtime this has becomes a drop off of different kind of classes. Since this is in the context of app start measurements, can we find a better place for this class? If it is hard to find, let catch up offline on the package structure.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't know where else to drop this in. I don't want to drop it in /metrics which is where AppStartTrace and other Trace metrics live in, because that would allow AppStartTrace access to some package-private methods that should not be allowed to use apart from testing. I only want AppStartTrace (the consumer of FirstDrawDoneListener) to use public static factory to register and create FirstDrawDoneListener.

assertThat(listOfListeners).isNotNull();
assertThat(listOfListeners.size()).isEqualTo(1);

// OnDrawListener is not registered, it is delayed for later
Copy link
Contributor

Choose a reason for hiding this comment

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

+1 to Raymond's ask. Currently, the test does not do much validate the listener registration for API < 26.

@leotianlizhan
Copy link
Contributor Author

/test check-coverage-changed

@leotianlizhan leotianlizhan merged commit ffd44ee into master Sep 2, 2022
@leotianlizhan leotianlizhan deleted the ondrawlistener branch September 2, 2022 18:58
qdpham13 pushed a commit that referenced this pull request Sep 13, 2022
* WIP

* handler

* handle bug prior to api 26

* tests

* copyright

* improve tests

* comment fix

* improve tests

* comment

* backport View.isAttachedToWindow()

* improved registerForNextDraw_delaysAddingListenerForAPIsBelow26

* remove LayoutChangeListener

* add check to mmake sure OnAttachStateChangeListener removes itself

* mcreate helper isAliveAndAttached

* improve test with Robolectric ShadowLooper
@firebase firebase locked and limited conversation to collaborators Oct 3, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants