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

View File

@@ -1151,6 +1151,9 @@ public class ContextWrapper extends Context {
*/ */
@Override @Override
public boolean isUiContext() { public boolean isUiContext() {
if (mBase == null) {
return false;
}
return mBase.isUiContext(); 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 com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import android.app.ActivityThread; import android.app.ActivityThread;
@@ -180,4 +181,26 @@ public class ContextTest {
VIRTUAL_DISPLAY_FLAG_PUBLIC | VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY); VIRTUAL_DISPLAY_FLAG_PUBLIC | VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
return virtualDisplay.getDisplay(); 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;
}
}
} }