From 64e1ba4398aad1b08a24b15a1d094eb2e9cc1e61 Mon Sep 17 00:00:00 2001 From: Adam Powell Date: Mon, 22 Aug 2016 09:09:44 -0700 Subject: [PATCH] Only dispatch window visibility aggregation for targetSdk >= N Some existing apps treat drawable visibility notifications as a signal to crossfade from a placeholder to the new image for the purposes of scrolling onscreen via a recycling collection view or similar. Since dispatchVisibilityAggregated is now called for window visibility changes and ImageView informs its drawable of the visiblity change, the extra call triggers a repeat fade-in in some existing apps when you return them to visibility. These apps should pay attention to the second parameter of Drawable#setVisible, which signals that animations should not restart in response to a visibility change. Updating to targetSdkVersion=24+ will enable the new behavior. Bug 30216207 Change-Id: I27ce9f09bc7544863f7f7980c273650949db21cc --- core/java/android/view/ViewRootImpl.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 4dc1009fe4468..7494b94ce7138 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -52,6 +52,7 @@ import android.hardware.input.InputManager; import android.media.AudioManager; import android.os.Binder; import android.os.Build; +import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.os.Debug; import android.os.Handler; @@ -1540,7 +1541,15 @@ public final class ViewRootImpl implements ViewParent, if (viewVisibilityChanged) { mAttachInfo.mWindowVisibility = viewVisibility; host.dispatchWindowVisibilityChanged(viewVisibility); - host.dispatchVisibilityAggregated(viewVisibility == View.VISIBLE); + + // Prior to N we didn't have dispatchVisibilityAggregated to give a more accurate + // view into when views are visible to the user or not. ImageView never dealt with + // telling its drawable about window visibility, among other things. Some apps cause + // an additional crossfade animation when windows become visible if they get this + // additional call, so only send it to new apps to avoid new visual jank. + if (host.getContext().getApplicationInfo().targetSdkVersion >= VERSION_CODES.N) { + host.dispatchVisibilityAggregated(viewVisibility == View.VISIBLE); + } if (viewVisibility != View.VISIBLE || mNewSurfaceNeeded) { endDragResizing(); destroyHardwareResources();