Commit 706bd90e authored by Clark DuVall's avatar Clark DuVall Committed by Commit Bot

[WebLayer] Fix WebLayer bundle tests which broke with WebLayer in split

These tests depended on the context that was returned from
TestWebLayer.getRemoteContext() to have been processed by the
implementation side. This was no longer the case when WebLayer was in a
split, since the context that gets processed was the one returned by
createContextForSplit().

To make these types of tests more robust,
TestWebLayer.getRemoteContext() now returns the actual context used by
the implementation side (from ContextUtils.getApplicationContext()), and
a new TestWebLayer.getWebLayerContext() method is added to get the
context for the WebLayer package. This required adding a test only
method to IWebLayer.aidl which allows tests against the WebView bundle
target to call it. Alternatively, we could build a separate WebView
bundle with WebLayer test code, but I would rather have these tests
testing the actual WebView bundle to make sure there aren't any issues.

Bug: 1130660
Change-Id: I68838dc7f918d1ee86fe8c65e84a4f5fefbec655
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2427068
Commit-Queue: Clark DuVall <cduvall@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#810211}
parent 5ae0a404
......@@ -8,7 +8,6 @@ import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build.VERSION_CODES;
import android.util.SparseArray;
import androidx.test.filters.SmallTest;
......@@ -19,7 +18,6 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.base.test.util.DisableIf;
import org.chromium.weblayer.TestWebLayer;
import org.chromium.weblayer.shell.InstrumentationActivity;
......@@ -39,17 +37,17 @@ public class BundleLanguageTest {
new InstrumentationActivityTestRule();
private Context mRemoteContext;
private Context mWebLayerContext;
@Before
public void setUp() {
public void setUp() throws Exception {
InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl("about:blank");
mRemoteContext = TestWebLayer.getRemoteContext(activity.getApplicationContext());
mWebLayerContext = TestWebLayer.getWebLayerContext(activity.getApplicationContext());
}
@Test
@SmallTest
@DisableIf.
Build(sdk_is_greater_than = VERSION_CODES.O_MR1, message = "https://crbug.com/1130660")
public void testWebLayerString() throws Exception {
// The bundle tests have both "es" and "fr" splits installed, so each of these should have a
// separate translation.
......@@ -66,8 +64,6 @@ public class BundleLanguageTest {
@Test
@SmallTest
@DisableIf.
Build(sdk_is_greater_than = VERSION_CODES.O_MR1, message = "https://crbug.com/1130660")
public void testSharedString() throws Exception {
// This string is shared with WebView, so should have a separate translation for all
// locales, even locales without splits installed.
......@@ -86,11 +82,11 @@ public class BundleLanguageTest {
@SmallTest
public void testBasePackageIdCorrect() throws Exception {
AssetManager assetManager = createEmptyAssetManager();
addAssetPath(assetManager, mRemoteContext.getApplicationInfo().sourceDir);
addAssetPath(assetManager, mWebLayerContext.getApplicationInfo().sourceDir);
SparseArray<String> packageIds = getPackageIds(assetManager);
Assert.assertEquals(2, packageIds.size());
Assert.assertEquals(packageIds.get(1), "android");
Assert.assertEquals(packageIds.get(2), mRemoteContext.getPackageName());
Assert.assertEquals(packageIds.get(2), mWebLayerContext.getPackageName());
}
/** Tests that locale splits only have resources from the hardcoded locale package ID. */
......@@ -98,14 +94,14 @@ public class BundleLanguageTest {
@SmallTest
public void testLocalePackageIdCorrect() throws Exception {
AssetManager assetManager = createEmptyAssetManager();
for (String path : mRemoteContext.getApplicationInfo().splitSourceDirs) {
for (String path : mWebLayerContext.getApplicationInfo().splitSourceDirs) {
addAssetPath(assetManager, path);
}
SparseArray<String> packageIds = getPackageIds(assetManager);
Assert.assertEquals(2, packageIds.size());
Assert.assertEquals(packageIds.get(1), "android");
Assert.assertEquals(packageIds.get(ResourceUtil.REQUIRED_PACKAGE_IDENTIFIER),
mRemoteContext.getPackageName() + "_translations");
mWebLayerContext.getPackageName() + "_translations");
}
private String getStringForLocale(String name, String locale) {
......@@ -113,7 +109,8 @@ public class BundleLanguageTest {
Configuration config = resources.getConfiguration();
config.setLocale(new Locale(locale));
resources.updateConfiguration(config, resources.getDisplayMetrics());
return resources.getString(ResourceUtil.getIdentifier(mRemoteContext, name));
return resources.getString(ResourceUtil.getIdentifier(
mRemoteContext, name, mWebLayerContext.getPackageName()));
}
private static AssetManager createEmptyAssetManager() throws ReflectiveOperationException {
......
......@@ -44,7 +44,9 @@ public class PageInfoTest {
mActivityTestRule.getTestDataURL("simple_page.html"), extras);
Context remoteContext = TestWebLayer.getRemoteContext(activity.getApplicationContext());
int buttonId = ResourceUtil.getIdentifier(remoteContext, "id/security_button");
String packageName =
TestWebLayer.getWebLayerContext(activity.getApplicationContext()).getPackageName();
int buttonId = ResourceUtil.getIdentifier(remoteContext, "id/security_button", packageName);
TestThreadUtils.runOnUiThreadBlocking(() -> {
StrictModeContext ignored = StrictModeContext.allowDiskReads();
......
......@@ -52,7 +52,9 @@ public final class PopupTest {
mActivityTestRule.executeScriptSync("window.open('about:blank')", true);
// Make sure the infobar shows up and the popup has not been opened.
int buttonId = ResourceUtil.getIdentifier(mRemoteContext, "id/button_primary");
String packageName =
TestWebLayer.getWebLayerContext(mActivity.getApplicationContext()).getPackageName();
int buttonId = ResourceUtil.getIdentifier(mRemoteContext, "id/button_primary", packageName);
CriteriaHelper.pollInstrumentationThread(() -> {
Criteria.checkThat(mActivity.findViewById(buttonId), Matchers.notNullValue());
});
......
......@@ -30,11 +30,14 @@ public final class ResourceLoadingTest {
new InstrumentationActivityTestRule();
private Context mRemoteContext;
private String mPackageName;
@Before
public void setUp() throws Exception {
InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl("about:blank");
mRemoteContext = TestWebLayer.getRemoteContext(activity);
mRemoteContext = TestWebLayer.getRemoteContext(activity.getApplicationContext());
mPackageName =
TestWebLayer.getWebLayerContext(activity.getApplicationContext()).getPackageName();
}
@Test
......@@ -60,6 +63,6 @@ public final class ResourceLoadingTest {
}
private int getIdentifier(String name) {
return ResourceUtil.getIdentifier(mRemoteContext, name);
return ResourceUtil.getIdentifier(mRemoteContext, name, mPackageName);
}
}
......@@ -15,8 +15,8 @@ public class ResourceUtil {
private ResourceUtil() {}
/** Gets the ID of a resource in a remote context. */
public static int getIdentifier(Context context, String name) {
int id = context.getResources().getIdentifier(name, null, context.getPackageName());
public static int getIdentifier(Context context, String name, String packageName) {
int id = context.getResources().getIdentifier(name, null, packageName);
// This was build with app_as_shared_lib, no need to modify package ID.
if ((id & 0xff000000) == 0x7f000000) {
return id;
......
......@@ -34,11 +34,14 @@ public class TranslateTest {
private InstrumentationActivity mActivity;
private Context mRemoteContext;
private String mPackageName;
@Before
public void setUp() throws Exception {
mActivity = mActivityTestRule.launchShellWithUrl("about:blank");
mRemoteContext = TestWebLayer.getRemoteContext(mActivity.getApplicationContext());
mPackageName =
TestWebLayer.getWebLayerContext(mActivity.getApplicationContext()).getPackageName();
TestWebLayer testWebLayer = TestWebLayer.getTestWebLayer(mActivity.getApplicationContext());
testWebLayer.setIgnoreMissingKeyForTranslateManager(true);
testWebLayer.forceNetworkConnectivityState(true);
......@@ -114,7 +117,7 @@ public class TranslateTest {
}
private View findViewByStringId(String id) {
return mActivity.findViewById(ResourceUtil.getIdentifier(mRemoteContext, id));
return mActivity.findViewById(ResourceUtil.getIdentifier(mRemoteContext, id, mPackageName));
}
private void waitForInfoBarToShow() {
......
......@@ -418,6 +418,11 @@ public final class WebLayerImpl extends IWebLayer.Stub {
WebLayerImplJni.get().registerExternalExperimentIDs(trialName, experimentIDs);
}
@Override
public IObjectWrapper getApplicationContext() {
return ObjectWrapper.wrap(ContextUtils.getApplicationContext());
}
public static Intent createIntent() {
if (sClient == null) {
throw new IllegalStateException("WebLayer should have been initialized already.");
......@@ -525,10 +530,6 @@ public final class WebLayerImpl extends IWebLayer.Stub {
}
assert remoteContext != null;
// TODO: This is only needed for tests. Remove once BundleLanguageTests can call through to
// TestWebLayerImpl.
forceCorrectPackageId(remoteContext);
Context lightContext = createContextForMode(remoteContext, Configuration.UI_MODE_NIGHT_NO);
Context darkContext = createContextForMode(remoteContext, Configuration.UI_MODE_NIGHT_YES);
ClassLoaderContextWrapperFactory.setLightDarkResourceOverrideContext(
......
......@@ -98,4 +98,7 @@ interface IWebLayer {
// Added in Version 86.
IBinder initializeImageDecoder(in IObjectWrapper appContext,
in IObjectWrapper remoteContext) = 19;
// Added in Version 87.
IObjectWrapper getApplicationContext() = 20;
}
......@@ -20,6 +20,7 @@ import android.webkit.ValueCallback;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment;
import org.chromium.weblayer_private.interfaces.APICallException;
......@@ -562,6 +563,16 @@ public class WebLayer {
return getWebLayerLoader(context).getIWebLayer();
}
@VisibleForTesting
/* package */ static Context getApplicationContextForTesting(Context appContext) {
try {
return (Context) ObjectWrapper.unwrap(
getIWebLayer(appContext).getApplicationContext(), Context.class);
} catch (RemoteException e) {
throw new APICallException(e);
}
}
/**
* Creates a ClassLoader for the remote (weblayer implementation) side.
*/
......
......@@ -49,7 +49,16 @@ public final class TestWebLayer {
return mITestWebLayer.isNetworkChangeAutoDetectOn();
}
/**
* Gets the processed context which is returned by ContextUtils.getApplicationContext() on the
* remote side.
*/
public static Context getRemoteContext(@NonNull Context appContext) {
return WebLayer.getApplicationContextForTesting(appContext);
}
/** Gets the context for the WebLayer implementation package. */
public static Context getWebLayerContext(@NonNull Context appContext) {
try {
return WebLayer.getOrCreateRemoteContext(appContext);
} catch (PackageManager.NameNotFoundException | ReflectiveOperationException e) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment