Skip to content

Commit 1a2833c

Browse files
authored
Merge pull request #2800 from DataDog/yl/fix-window-callback-npe
RUM-10958: Fix WindowCallbackWrapper NPE
2 parents 97cb232 + 43a6780 commit 1a2833c

File tree

3 files changed

+593
-2
lines changed

3 files changed

+593
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
/*
2+
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3+
* This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
* Copyright 2016-Present Datadog, Inc.
5+
*/
6+
7+
package com.datadog.android.rum.internal.instrumentation.gestures;
8+
9+
import android.os.Build;
10+
import android.view.ActionMode;
11+
import android.view.KeyEvent;
12+
import android.view.KeyboardShortcutGroup;
13+
import android.view.Menu;
14+
import android.view.MenuItem;
15+
import android.view.MotionEvent;
16+
import android.view.SearchEvent;
17+
import android.view.View;
18+
import android.view.Window;
19+
import android.view.WindowManager;
20+
import android.view.accessibility.AccessibilityEvent;
21+
22+
import androidx.annotation.NonNull;
23+
import androidx.annotation.Nullable;
24+
import androidx.annotation.RequiresApi;
25+
26+
import com.datadog.android.lint.InternalApi;
27+
28+
import java.util.List;
29+
30+
/**
31+
* A wrapper for {@link Window.Callback} that ensures the callback methods are called.
32+
* This is to fix an issue where the system calls {@link #onMenuOpened(int, Menu)}
33+
* with a null menu parameter.
34+
* To track the issue: https://issuetracker.google.com/issues/188568911
35+
*/
36+
@InternalApi
37+
class FixedWindowCallback implements Window.Callback {
38+
39+
private final Window.Callback delegate;
40+
41+
FixedWindowCallback(@NonNull Window.Callback delegate) {
42+
this.delegate = delegate;
43+
}
44+
45+
@Override
46+
public boolean dispatchGenericMotionEvent(MotionEvent event) {
47+
return delegate.dispatchGenericMotionEvent(event);
48+
}
49+
50+
@Override
51+
public boolean dispatchKeyEvent(KeyEvent event) {
52+
return delegate.dispatchKeyEvent(event);
53+
}
54+
55+
@Override
56+
public boolean dispatchKeyShortcutEvent(KeyEvent event) {
57+
return delegate.dispatchKeyShortcutEvent(event);
58+
}
59+
60+
@Override
61+
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
62+
return delegate.dispatchPopulateAccessibilityEvent(event);
63+
}
64+
65+
@Override
66+
public boolean dispatchTouchEvent(MotionEvent event) {
67+
return delegate.dispatchTouchEvent(event);
68+
}
69+
70+
@Override
71+
public boolean dispatchTrackballEvent(MotionEvent event) {
72+
return delegate.dispatchTrackballEvent(event);
73+
}
74+
75+
@Override
76+
public void onActionModeFinished(ActionMode mode) {
77+
delegate.onActionModeFinished(mode);
78+
}
79+
80+
@Override
81+
public void onActionModeStarted(ActionMode mode) {
82+
delegate.onActionModeStarted(mode);
83+
}
84+
85+
@Override
86+
public void onAttachedToWindow() {
87+
delegate.onAttachedToWindow();
88+
}
89+
90+
@Override
91+
public void onContentChanged() {
92+
delegate.onContentChanged();
93+
}
94+
95+
@Override
96+
public boolean onCreatePanelMenu(int featureId, @Nullable Menu menu) {
97+
return delegate.onCreatePanelMenu(featureId, menu);
98+
}
99+
100+
@Nullable
101+
@Override
102+
public View onCreatePanelView(int featureId) {
103+
return delegate.onCreatePanelView(featureId);
104+
}
105+
106+
@Override
107+
public void onDetachedFromWindow() {
108+
delegate.onDetachedFromWindow();
109+
}
110+
111+
@Override
112+
public boolean onMenuItemSelected(int featureId, @Nullable MenuItem item) {
113+
return delegate.onMenuItemSelected(featureId, item);
114+
}
115+
116+
@Override
117+
public boolean onMenuOpened(int featureId, @Nullable Menu menu) {
118+
return delegate.onMenuOpened(featureId, menu);
119+
}
120+
121+
@Override
122+
public void onPanelClosed(int featureId, @Nullable Menu menu) {
123+
delegate.onPanelClosed(featureId, menu);
124+
}
125+
126+
@RequiresApi(api = Build.VERSION_CODES.O)
127+
@Override
128+
public void onPointerCaptureChanged(boolean hasCapture) {
129+
delegate.onPointerCaptureChanged(hasCapture);
130+
}
131+
132+
@Override
133+
public boolean onPreparePanel(int featureId, @Nullable View view, @Nullable Menu menu) {
134+
return delegate.onPreparePanel(featureId, view, menu);
135+
}
136+
137+
@RequiresApi(api = Build.VERSION_CODES.N)
138+
@Override
139+
public void onProvideKeyboardShortcuts(List<KeyboardShortcutGroup> data, @Nullable Menu menu, int deviceId) {
140+
delegate.onProvideKeyboardShortcuts(data, menu, deviceId);
141+
}
142+
143+
@Override
144+
public boolean onSearchRequested() {
145+
return delegate.onSearchRequested();
146+
}
147+
148+
@RequiresApi(api = Build.VERSION_CODES.M)
149+
@Override
150+
public boolean onSearchRequested(SearchEvent searchEvent) {
151+
return delegate.onSearchRequested(searchEvent);
152+
}
153+
154+
@Override
155+
public void onWindowAttributesChanged(WindowManager.LayoutParams attrs) {
156+
delegate.onWindowAttributesChanged(attrs);
157+
}
158+
159+
@Override
160+
public void onWindowFocusChanged(boolean hasFocus) {
161+
delegate.onWindowFocusChanged(hasFocus);
162+
}
163+
164+
@Nullable
165+
@Override
166+
public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
167+
return delegate.onWindowStartingActionMode(callback);
168+
}
169+
170+
@RequiresApi(api = Build.VERSION_CODES.M)
171+
@Nullable
172+
@Override
173+
public ActionMode onWindowStartingActionMode(ActionMode.Callback callback, int type) {
174+
return delegate.onWindowStartingActionMode(callback, type);
175+
}
176+
}

features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/instrumentation/gestures/WindowCallbackWrapper.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import com.datadog.android.rum.internal.tracking.NoOpInteractionPredicate
1919
import com.datadog.android.rum.tracking.InteractionPredicate
2020
import com.datadog.android.rum.tracking.ViewAttributesProvider
2121
import java.lang.ref.WeakReference
22-
import kotlin.Exception
2322

2423
@Suppress("TooGenericExceptionCaught")
2524
internal class WindowCallbackWrapper(
@@ -34,7 +33,7 @@ internal class WindowCallbackWrapper(
3433
},
3534
val targetAttributesProviders: Array<ViewAttributesProvider> = emptyArray(),
3635
val internalLogger: InternalLogger
37-
) : Window.Callback by wrappedCallback {
36+
) : FixedWindowCallback(wrappedCallback) {
3837

3938
internal val windowReference = WeakReference(window)
4039

0 commit comments

Comments
 (0)