Merge "Adds ViewTreeObserver window visibility listeners" into tm-qpr-dev

This commit is contained in:
Alejandro Nijamkin
2022-07-06 19:31:20 +00:00
committed by Android (Google) Code Review
2 changed files with 85 additions and 0 deletions

View File

@@ -2801,6 +2801,7 @@ public final class ViewRootImpl implements ViewParent,
if (viewVisibilityChanged) {
mAttachInfo.mWindowVisibility = viewVisibility;
host.dispatchWindowVisibilityChanged(viewVisibility);
mAttachInfo.mTreeObserver.dispatchOnWindowVisibilityChange(viewVisibility);
if (viewUserVisibilityChanged) {
host.dispatchVisibilityAggregated(viewVisibility == View.VISIBLE);
}

View File

@@ -43,6 +43,7 @@ public final class ViewTreeObserver {
// Recursive listeners use CopyOnWriteArrayList
private CopyOnWriteArrayList<OnWindowFocusChangeListener> mOnWindowFocusListeners;
private CopyOnWriteArrayList<OnWindowAttachListener> mOnWindowAttachListeners;
private CopyOnWriteArrayList<OnWindowVisibilityChangeListener> mOnWindowVisibilityListeners;
private CopyOnWriteArrayList<OnGlobalFocusChangeListener> mOnGlobalFocusListeners;
@UnsupportedAppUsage
private CopyOnWriteArrayList<OnTouchModeChangeListener> mOnTouchModeChangeListeners;
@@ -105,6 +106,21 @@ public final class ViewTreeObserver {
public void onWindowFocusChanged(boolean hasFocus);
}
/**
* Interface definition for a callback to be invoked when the view hierarchy's window
* visibility changes.
*
* @hide
*/
public interface OnWindowVisibilityChangeListener {
/**
* Callback method to be invoked when the window visibility changes in the view tree.
*
* @param visibility The new visibility of the window.
*/
void onWindowVisibilityChanged(@View.Visibility int visibility);
}
/**
* Interface definition for a callback to be invoked when the focus state within
* the view tree changes.
@@ -386,6 +402,14 @@ public final class ViewTreeObserver {
}
}
if (observer.mOnWindowVisibilityListeners != null) {
if (mOnWindowVisibilityListeners != null) {
mOnWindowVisibilityListeners.addAll(observer.mOnWindowVisibilityListeners);
} else {
mOnWindowVisibilityListeners = observer.mOnWindowVisibilityListeners;
}
}
if (observer.mOnGlobalFocusListeners != null) {
if (mOnGlobalFocusListeners != null) {
mOnGlobalFocusListeners.addAll(observer.mOnGlobalFocusListeners);
@@ -540,6 +564,49 @@ public final class ViewTreeObserver {
}
/**
* Register a callback to be invoked when the window visibility changes.
*
* @param listener The callback to add
*
* @throws IllegalStateException If {@link #isAlive()} returns false
*
* @hide
*/
public void addOnWindowVisibilityChangeListener(
@NonNull OnWindowVisibilityChangeListener listener) {
checkIsAlive();
if (mOnWindowVisibilityListeners == null) {
mOnWindowVisibilityListeners =
new CopyOnWriteArrayList<OnWindowVisibilityChangeListener>();
}
mOnWindowVisibilityListeners.add(listener);
}
/**
* Remove a previously installed window visibility callback.
*
* @param victim The callback to remove
*
* @throws IllegalStateException If {@link #isAlive()} returns false
*
* @see #addOnWindowVisibilityChangeListener(
* android.view.ViewTreeObserver.OnWindowVisibilityChangeListener)
*
* @hide
*/
public void removeOnWindowVisibilityChangeListener(
@NonNull OnWindowVisibilityChangeListener victim) {
checkIsAlive();
if (mOnWindowVisibilityListeners == null) {
return;
}
mOnWindowVisibilityListeners.remove(victim);
}
/*
* Register a callback to be invoked when the focus state within the view tree changes.
*
* @param listener The callback to add
@@ -1025,6 +1092,23 @@ public final class ViewTreeObserver {
}
}
/**
* Notifies registered listeners that window visibility has changed.
*/
void dispatchOnWindowVisibilityChange(int visibility) {
// NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to
// perform the dispatching. The iterator is a safe guard against listeners that
// could mutate the list by calling the various add/remove methods. This prevents
// the array from being modified while we iterate it.
final CopyOnWriteArrayList<OnWindowVisibilityChangeListener> listeners =
mOnWindowVisibilityListeners;
if (listeners != null && listeners.size() > 0) {
for (OnWindowVisibilityChangeListener listener : listeners) {
listener.onWindowVisibilityChanged(visibility);
}
}
}
/**
* Notifies registered listeners that focus has changed.
*/