Merge "Fix NPE when invoking Context#isUiContext" into rvc-dev

This commit is contained in:
Charles Chen
2020-07-08 17:46:09 +00:00
committed by Android (Google) Code Review
3 changed files with 48 additions and 17 deletions

View File

@@ -1900,26 +1900,31 @@ class ContextImpl extends Context {
@Override
public Object getSystemService(String name) {
// We may override this API from outer context.
final boolean isUiContext = isUiContext() || getOuterContext().isUiContext();
// Check incorrect Context usage.
if (isUiComponent(name) && !isUiContext && vmIncorrectContextUseEnabled()) {
final String errorMessage = "Tried to access visual service "
+ SystemServiceRegistry.getSystemServiceClassName(name)
+ " from a non-visual Context:" + getOuterContext();
final String message = "Visual services, such as WindowManager, WallpaperService or "
+ "LayoutInflater should be accessed from Activity or other visual Context. "
+ "Use an Activity or a Context created with "
+ "Context#createWindowContext(int, Bundle), which are adjusted to the "
+ "configuration and visual bounds of an area on screen.";
final Exception exception = new IllegalAccessException(errorMessage);
StrictMode.onIncorrectContextUsed(message, exception);
Log.e(TAG, errorMessage + message, exception);
if (vmIncorrectContextUseEnabled()) {
// We may override this API from outer context.
final boolean isUiContext = isUiContext() || isOuterUiContext();
// Check incorrect Context usage.
if (isUiComponent(name) && !isUiContext) {
final String errorMessage = "Tried to access visual service "
+ SystemServiceRegistry.getSystemServiceClassName(name)
+ " from a non-visual Context:" + getOuterContext();
final String message = "Visual services, such as WindowManager, WallpaperService "
+ "or LayoutInflater should be accessed from Activity or other visual "
+ "Context. Use an Activity or a Context created with "
+ "Context#createWindowContext(int, Bundle), which are adjusted to "
+ "the configuration and visual bounds of an area on screen.";
final Exception exception = new IllegalAccessException(errorMessage);
StrictMode.onIncorrectContextUsed(message, exception);
Log.e(TAG, errorMessage + " " + message, exception);
}
}
return SystemServiceRegistry.getSystemService(this, name);
}
private boolean isOuterUiContext() {
return getOuterContext() != null && getOuterContext().isUiContext();
}
@Override
public String getSystemServiceName(Class<?> serviceClass) {
return SystemServiceRegistry.getSystemServiceName(serviceClass);
@@ -2371,7 +2376,7 @@ class ContextImpl extends Context {
context.setResources(createResources(mToken, mPackageInfo, mSplitName, displayId,
overrideConfiguration, getDisplayAdjustments(displayId).getCompatibilityInfo(),
mResources.getLoaders()));
context.mIsUiContext = isUiContext() || getOuterContext().isUiContext();
context.mIsUiContext = isUiContext() || isOuterUiContext();
return context;
}

View File

@@ -1151,6 +1151,9 @@ public class ContextWrapper extends Context {
*/
@Override
public boolean isUiContext() {
if (mBase == null) {
return false;
}
return mBase.isUiContext();
}
}

View File

@@ -23,6 +23,7 @@ import static android.view.Display.DEFAULT_DISPLAY;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import android.app.ActivityThread;
@@ -180,4 +181,26 @@ public class ContextTest {
VIRTUAL_DISPLAY_FLAG_PUBLIC | VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
return virtualDisplay.getDisplay();
}
@Test
public void testIsUiContext_ContextWrapper() {
ContextWrapper wrapper = new ContextWrapper(null /* base */);
assertFalse(wrapper.isUiContext());
wrapper = new ContextWrapper(new TestUiContext());
assertTrue(wrapper.isUiContext());
}
private static class TestUiContext extends ContextWrapper {
TestUiContext() {
super(null /* base */);
}
@Override
public boolean isUiContext() {
return true;
}
}
}