Only register listeners if setView was success.

Found a memory leak on ViewRootImpl. If the view wasn't been set
to the VRI successfully, there would keep the registed listeners to the
AccessibilityManager and DisplayManager forever because there didn't
need to deatch anything from window.
Another reasonable way is to register all listeners after setView
success.

Bug: 200843755
Test: manual, hard code to force addWindow fail and monitor no more
ViewRootImpl object leaked to AccessibilityManager and DisplayManager.

Change-Id: I3c9cc52d0ca4595c74c1dc3c51d286d9e6e3897f
This commit is contained in:
wilsonshih
2021-10-20 19:00:22 +08:00
parent 8172fc3e42
commit 1c833479dd

View File

@@ -820,11 +820,7 @@ public final class ViewRootImpl implements ViewParent,
context); context);
mCompatibleVisibilityInfo = new SystemUiVisibilityInfo(); mCompatibleVisibilityInfo = new SystemUiVisibilityInfo();
mAccessibilityManager = AccessibilityManager.getInstance(context); mAccessibilityManager = AccessibilityManager.getInstance(context);
mAccessibilityManager.addAccessibilityStateChangeListener(
mAccessibilityInteractionConnectionManager, mHandler);
mHighContrastTextManager = new HighContrastTextManager(); mHighContrastTextManager = new HighContrastTextManager();
mAccessibilityManager.addHighTextContrastStateChangeListener(
mHighContrastTextManager, mHandler);
mViewConfiguration = ViewConfiguration.get(context); mViewConfiguration = ViewConfiguration.get(context);
mDensity = context.getResources().getDisplayMetrics().densityDpi; mDensity = context.getResources().getDisplayMetrics().densityDpi;
mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi; mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi;
@@ -1024,8 +1020,6 @@ public final class ViewRootImpl implements ViewParent,
mView = view; mView = view;
mAttachInfo.mDisplayState = mDisplay.getState(); mAttachInfo.mDisplayState = mDisplay.getState();
mDisplayManager.registerDisplayListener(mDisplayListener, mHandler);
mViewLayoutDirectionInitial = mView.getRawLayoutDirection(); mViewLayoutDirectionInitial = mView.getRawLayoutDirection();
mFallbackEventHandler.setView(view); mFallbackEventHandler.setView(view);
mWindowAttributes.copyFrom(attrs); mWindowAttributes.copyFrom(attrs);
@@ -1218,6 +1212,7 @@ public final class ViewRootImpl implements ViewParent,
"Unable to add window -- unknown error code " + res); "Unable to add window -- unknown error code " + res);
} }
registerListeners();
if ((res & WindowManagerGlobal.ADD_FLAG_USE_BLAST) != 0) { if ((res & WindowManagerGlobal.ADD_FLAG_USE_BLAST) != 0) {
mUseBLASTAdapter = true; mUseBLASTAdapter = true;
} }
@@ -1274,6 +1269,28 @@ public final class ViewRootImpl implements ViewParent,
} }
} }
/**
* Register any kind of listeners if setView was success.
*/
private void registerListeners() {
mAccessibilityManager.addAccessibilityStateChangeListener(
mAccessibilityInteractionConnectionManager, mHandler);
mAccessibilityManager.addHighTextContrastStateChangeListener(
mHighContrastTextManager, mHandler);
mDisplayManager.registerDisplayListener(mDisplayListener, mHandler);
}
/**
* Unregister all listeners while detachedFromWindow.
*/
private void unregisterListeners() {
mAccessibilityManager.removeAccessibilityStateChangeListener(
mAccessibilityInteractionConnectionManager);
mAccessibilityManager.removeHighTextContrastStateChangeListener(
mHighContrastTextManager);
mDisplayManager.unregisterDisplayListener(mDisplayListener);
}
private void setTag() { private void setTag() {
final String[] split = mWindowAttributes.getTitle().toString().split("\\."); final String[] split = mWindowAttributes.getTitle().toString().split("\\.");
if (split.length > 0) { if (split.length > 0) {
@@ -5016,10 +5033,6 @@ public final class ViewRootImpl implements ViewParent,
} }
mAccessibilityInteractionConnectionManager.ensureNoConnection(); mAccessibilityInteractionConnectionManager.ensureNoConnection();
mAccessibilityManager.removeAccessibilityStateChangeListener(
mAccessibilityInteractionConnectionManager);
mAccessibilityManager.removeHighTextContrastStateChangeListener(
mHighContrastTextManager);
removeSendWindowContentChangedCallback(); removeSendWindowContentChangedCallback();
destroyHardwareRenderer(); destroyHardwareRenderer();
@@ -5052,8 +5065,7 @@ public final class ViewRootImpl implements ViewParent,
mInputEventReceiver = null; mInputEventReceiver = null;
} }
mDisplayManager.unregisterDisplayListener(mDisplayListener); unregisterListeners();
unscheduleTraversals(); unscheduleTraversals();
} }