Fixed unexpected NPE happening in framework due to 'more keys' placer views

This commit is contained in:
pdroidandroid@gmail.com 2020-12-13 13:06:29 +01:00 committed by Daniele Laudani
parent 629fd562e4
commit fa66144d65

View file

@ -28,6 +28,7 @@ import android.view.LayoutInflater;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityEvent;
import android.widget.FrameLayout; import android.widget.FrameLayout;
@ -57,7 +58,7 @@ import java.util.WeakHashMap;
final class EmojiPageKeyboardView extends KeyboardView implements final class EmojiPageKeyboardView extends KeyboardView implements
MoreKeysPanel.Controller { MoreKeysPanel.Controller {
private static final String TAG = "EmojiPageKeyboardView"; private static final String TAG = "EmojiPageKeyboardView";
private static final boolean LOG = true; private static final boolean LOG = false;
private static final long KEY_PRESS_DELAY_TIME = 250; // msec private static final long KEY_PRESS_DELAY_TIME = 250; // msec
private static final long KEY_RELEASE_DELAY_TIME = 30; // msec private static final long KEY_RELEASE_DELAY_TIME = 30; // msec
@ -121,13 +122,7 @@ final class EmojiPageKeyboardView extends KeyboardView implements
mMoreKeysPlacerView.setLayerType(LAYER_TYPE_HARDWARE, layerPaint); mMoreKeysPlacerView.setLayerType(LAYER_TYPE_HARDWARE, layerPaint);
} }
@Override private void installMoreKeysPlacerView(final boolean uninstall) {
protected void onAttachedToWindow() {
super.onAttachedToWindow();
installMoreKeysPlacerView();
}
private void installMoreKeysPlacerView() {
final View rootView = getRootView(); final View rootView = getRootView();
if (rootView == null) { if (rootView == null) {
Log.w(TAG, "Cannot find root view"); Log.w(TAG, "Cannot find root view");
@ -140,30 +135,11 @@ final class EmojiPageKeyboardView extends KeyboardView implements
return; return;
} }
windowContentView.addView(mMoreKeysPlacerView); if (uninstall) {
} windowContentView.removeView(mMoreKeysPlacerView);
} else {
@Override windowContentView.addView(mMoreKeysPlacerView);
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mMoreKeysPlacerView.removeAllViews();
uninstallMoreKeysPlacerView();
}
private void uninstallMoreKeysPlacerView() {
final View rootView = getRootView();
if (rootView == null) {
Log.w(TAG, "Cannot find root view");
return;
} }
final ViewGroup windowContentView = rootView.findViewById(android.R.id.content);
// Note: It'd be very weird if we get null by android.R.id.content.
if (windowContentView == null) {
Log.w(TAG, "Cannot find android.R.id.content view to add DrawingPreviewPlacerView");
return;
}
windowContentView.removeView(mMoreKeysPlacerView);
} }
public void setOnKeyEventListener(final OnKeyEventListener listener) { public void setOnKeyEventListener(final OnKeyEventListener listener) {
@ -223,12 +199,10 @@ final class EmojiPageKeyboardView extends KeyboardView implements
return moreKeysKeyboardView; return moreKeysKeyboardView;
} }
@Override private void dismissMoreKeysPanel() {
public void onShowMoreKeysPanel(final MoreKeysPanel panel) { if (isShowingMoreKeysPanel()) {
// Dismiss another {@link MoreKeysPanel} that may be being showed. mMoreKeysPanel.dismissMoreKeysPanel();
onDismissMoreKeysPanel(); }
panel.showInParent(mMoreKeysPlacerView);
mMoreKeysPanel = panel;
} }
public boolean isShowingMoreKeysPanel() { public boolean isShowingMoreKeysPanel() {
@ -236,8 +210,12 @@ final class EmojiPageKeyboardView extends KeyboardView implements
} }
@Override @Override
public void onCancelMoreKeysPanel() { public void onShowMoreKeysPanel(final MoreKeysPanel panel) {
// Nothing to do // install placer view only when needed instead of when this
// view is attached to window
installMoreKeysPlacerView(false /* uninstall */);
panel.showInParent(mMoreKeysPlacerView);
mMoreKeysPanel = panel;
} }
@Override @Override
@ -245,12 +223,14 @@ final class EmojiPageKeyboardView extends KeyboardView implements
if (isShowingMoreKeysPanel()) { if (isShowingMoreKeysPanel()) {
mMoreKeysPanel.removeFromParent(); mMoreKeysPanel.removeFromParent();
mMoreKeysPanel = null; mMoreKeysPanel = null;
installMoreKeysPlacerView(true /* uninstall */);
} }
} }
private void dismissMoreKeysPanel() { @Override
public void onCancelMoreKeysPanel() {
if (isShowingMoreKeysPanel()) { if (isShowingMoreKeysPanel()) {
mMoreKeysPanel.dismissMoreKeysPanel(); dismissMoreKeysPanel();
} }
} }
@ -319,6 +299,9 @@ final class EmojiPageKeyboardView extends KeyboardView implements
final int translatedX = moreKeysPanel.translateX(x); final int translatedX = moreKeysPanel.translateX(x);
final int translatedY = moreKeysPanel.translateY(y); final int translatedY = moreKeysPanel.translateY(y);
moreKeysPanel.onDownEvent(translatedX, translatedY, mPointerId, 0 /* nor used for now */); moreKeysPanel.onDownEvent(translatedX, translatedY, mPointerId, 0 /* nor used for now */);
// No need of re-allowing parent later as we don't
// want any scroll to append during this entire input.
disallowParentInterceptTouchEvent(true);
} }
} }
@ -465,4 +448,13 @@ final class EmojiPageKeyboardView extends KeyboardView implements
mLastY = y; mLastY = y;
return true; return true;
} }
private void disallowParentInterceptTouchEvent(final boolean disallow) {
final ViewParent parent = getParent();
if (parent == null) {
Log.w(TAG, "Cannot disallow touch event interception, no parent found.");
return;
}
parent.requestDisallowInterceptTouchEvent(disallow);
}
} }