aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreeHugger Robot <treehugger-gerrit@google.com>2017-05-18 17:28:31 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2017-05-18 17:28:34 +0000
commit52b0360b1a3af42893c35227992d5bd78d1a32c7 (patch)
treef8c63089059a53a924d99a759821fcc405d44263
parentac6b06ff015ab321b726c5fa990ce368c8fbf399 (diff)
parentb35cacc0b2f6d8b97e052ae14ed5971117dc8203 (diff)
downloadlayoutlib-52b0360b1a3af42893c35227992d5bd78d1a32c7.tar.gz
Merge "Implement Resources.getIdentifier in layoutlib"
-rw-r--r--bridge/src/android/content/res/Resources_Delegate.java69
-rw-r--r--bridge/tests/src/android/content/res/Resources_DelegateTest.java69
-rw-r--r--bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java40
-rw-r--r--create/src/com/android/tools/layoutlib/create/CreateInfo.java1
4 files changed, 178 insertions, 1 deletions
diff --git a/bridge/src/android/content/res/Resources_Delegate.java b/bridge/src/android/content/res/Resources_Delegate.java
index 6e97b2bd44..0a5912974f 100644
--- a/bridge/src/android/content/res/Resources_Delegate.java
+++ b/bridge/src/android/content/res/Resources_Delegate.java
@@ -33,6 +33,7 @@ import com.android.layoutlib.bridge.impl.ResourceHelper;
import com.android.layoutlib.bridge.util.NinePatchInputStream;
import com.android.ninepatch.NinePatch;
import com.android.resources.ResourceType;
+import com.android.resources.ResourceUrl;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
import com.android.tools.layoutlib.annotations.VisibleForTesting;
import com.android.util.Pair;
@@ -62,6 +63,9 @@ import java.util.Iterator;
import java.util.Objects;
import java.util.WeakHashMap;
+import static com.android.SdkConstants.ANDROID_PKG;
+import static com.android.SdkConstants.PREFIX_RESOURCE_REF;
+
@SuppressWarnings("deprecation")
public class Resources_Delegate {
private static WeakHashMap<Resources, LayoutlibCallback> sLayoutlibCallbacks = new
@@ -437,7 +441,7 @@ public class Resources_Delegate {
@NonNull
private static String resolveReference(Resources resources, @NonNull String ref,
boolean forceFrameworkOnly) {
- if (ref.startsWith(SdkConstants.PREFIX_RESOURCE_REF) || ref.startsWith
+ if (ref.startsWith(PREFIX_RESOURCE_REF) || ref.startsWith
(SdkConstants.PREFIX_THEME_REF)) {
ResourceValue rv =
getContext(resources).getRenderResources().findResValue(ref, forceFrameworkOnly);
@@ -1014,6 +1018,69 @@ public class Resources_Delegate {
throw new UnsupportedOperationException();
}
+ @VisibleForTesting
+ @Nullable
+ static ResourceUrl resourceUrlFromName(@NonNull String name, @Nullable String defType,
+ @Nullable
+ String defPackage) {
+ int colonIdx = name.indexOf(':');
+ int slashIdx = name.indexOf('/');
+
+ if (colonIdx != -1 && slashIdx != -1) {
+ // Easy case
+ return ResourceUrl.parse(PREFIX_RESOURCE_REF + name);
+ }
+
+ if (colonIdx == -1 && slashIdx == -1) {
+ if (defType == null) {
+ throw new IllegalArgumentException("name does not define a type an no defType was" +
+ " passed");
+ }
+
+ // It does not define package or type
+ return ResourceUrl.parse(
+ PREFIX_RESOURCE_REF + (defPackage != null ? defPackage + ":" : "") + defType +
+ "/" + name);
+ }
+
+ if (colonIdx != -1) {
+ if (defType == null) {
+ throw new IllegalArgumentException("name does not define a type an no defType was" +
+ " passed");
+ }
+ // We have package but no type
+ String pkg = name.substring(0, colonIdx);
+ ResourceType type = ResourceType.getEnum(defType);
+ return type != null ? ResourceUrl.create(pkg, type, name.substring(colonIdx + 1)) :
+ null;
+ }
+
+ ResourceType type = ResourceType.getEnum(name.substring(0, slashIdx));
+ if (type == null) {
+ return null;
+ }
+ // We have type but no package
+ return ResourceUrl.create(defPackage,
+ type,
+ name.substring(slashIdx + 1));
+ }
+
+ @LayoutlibDelegate
+ static int getIdentifier(Resources resources, String name, String defType, String defPackage) {
+ if (name == null) {
+ return 0;
+ }
+
+ ResourceUrl url = resourceUrlFromName(name, defType, defPackage);
+ Integer id = null;
+ if (url != null) {
+ id = ANDROID_PKG.equals(url.namespace) ? Bridge.getResourceId(url.type, url.name) :
+ getLayoutlibCallback(resources).getResourceId(url.type, url.name);
+ }
+
+ return id != null ? id : 0;
+ }
+
/**
* Builds and throws a {@link Resources.NotFoundException} based on a resource id and a resource
* type.
diff --git a/bridge/tests/src/android/content/res/Resources_DelegateTest.java b/bridge/tests/src/android/content/res/Resources_DelegateTest.java
new file mode 100644
index 0000000000..be39ab0712
--- /dev/null
+++ b/bridge/tests/src/android/content/res/Resources_DelegateTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.res;
+
+import com.android.resources.ResourceType;
+import com.android.resources.ResourceUrl;
+
+import org.junit.Test;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+public class Resources_DelegateTest {
+ private static void assertResourceUrl(@Nullable String pkg, @NonNull String name,
+ @NonNull ResourceType type, @Nullable ResourceUrl url) {
+ assertNotNull(url);
+ assertEquals(type, url.type);
+ assertEquals(pkg, url.namespace);
+ assertEquals(name, url.name);
+ }
+
+ @Test
+ public void resourceUrlFromName() {
+ try {
+ Resources_Delegate.resourceUrlFromName("pkg:name", null, null);
+ fail("Expected IllegalArgumentException since no type was defined");
+ } catch (IllegalArgumentException ignored) {
+ }
+
+ assertNull(Resources_Delegate.resourceUrlFromName("package:invalid/name", null, null));
+ assertNull(Resources_Delegate.resourceUrlFromName("package:name", "invalid", null));
+ assertResourceUrl("package", "name", ResourceType.ID,
+ Resources_Delegate.resourceUrlFromName("package:name", "id", null));
+ assertResourceUrl("package", "name", ResourceType.ID,
+ Resources_Delegate.resourceUrlFromName("name", "id", "package"));
+ assertResourceUrl("package", "test", ResourceType.STRING,
+ Resources_Delegate.resourceUrlFromName("package:string/test", null, null));
+ assertResourceUrl(null, "test", ResourceType.STRING,
+ Resources_Delegate.resourceUrlFromName("string/test", null, null));
+
+
+ // Type and package in the name take precedence over the passed defType and defPackage
+ assertResourceUrl("p1", "r1", ResourceType.STRING,
+ Resources_Delegate.resourceUrlFromName("p1:string/r1", "id", "p2"));
+ assertResourceUrl("p2", "r1", ResourceType.STRING,
+ Resources_Delegate.resourceUrlFromName("string/r1", "id", "p2"));
+ assertResourceUrl("p1", "r1", ResourceType.ID,
+ Resources_Delegate.resourceUrlFromName("p1:r1", "id", "p2"));
+ }
+} \ No newline at end of file
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java b/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java
index b0f39083bb..208c2d7030 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java
+++ b/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java
@@ -20,6 +20,7 @@ import com.android.ide.common.rendering.api.RenderSession;
import com.android.ide.common.rendering.api.SessionParams;
import com.android.ide.common.rendering.api.SessionParams.RenderingMode;
import com.android.ide.common.rendering.api.ViewInfo;
+import com.android.internal.R;
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.layoutlib.bridge.android.RenderParamsFlags;
import com.android.layoutlib.bridge.impl.RenderAction;
@@ -48,6 +49,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
@@ -533,4 +535,42 @@ public class RenderTests extends RenderTestBase {
public void testRectangleShadow() throws Exception {
renderAndVerify("shadows_test.xml", "shadows_test.png");
}
+
+ @Test
+ public void testResourcesGetIdentifier() throws Exception {
+ // Setup
+ // Create the layout pull parser for our resources (empty.xml can not be part of the test
+ // app as it won't compile).
+ LayoutPullParser parser = LayoutPullParser.createFromPath("/empty.xml");
+ // Create LayoutLibCallback.
+ LayoutLibTestCallback layoutLibCallback =
+ new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
+ layoutLibCallback.initResources();
+ SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_4,
+ layoutLibCallback, "AppTheme", true, RenderingMode.NORMAL, 22);
+ AssetManager assetManager = AssetManager.getSystem();
+ DisplayMetrics metrics = new DisplayMetrics();
+ Configuration configuration = RenderAction.getConfiguration(params);
+ BridgeContext context = new BridgeContext(params.getProjectKey(), metrics, params.getResources(),
+ params.getAssets(), params.getLayoutlibCallback(), configuration,
+ params.getTargetSdkVersion(), params.isRtlSupported());
+ Resources resources = Resources_Delegate.initSystem(context, assetManager, metrics,
+ configuration, params.getLayoutlibCallback());
+ int id = Resources_Delegate.getLayoutlibCallback(resources).getResourceId(
+ ResourceType.STRING,
+ "app_name");
+ assertEquals(id, resources.getIdentifier("string/app_name", null, null));
+ assertEquals(id, resources.getIdentifier("app_name", "string", null));
+ assertEquals(0, resources.getIdentifier("string/does_not_exist", null, null));
+ assertEquals(R.string.accept, resources.getIdentifier("android:string/accept", null,
+ null));
+ assertEquals(R.string.accept, resources.getIdentifier("string/accept", null,
+ "android"));
+ assertEquals(R.id.message, resources.getIdentifier("id/message", null,
+ "android"));
+ assertEquals(R.string.accept, resources.getIdentifier("accept", "string",
+ "android"));
+
+ context.disposeResources();
+ }
}
diff --git a/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index cb0bc6d3c4..5951a67f6b 100644
--- a/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -133,6 +133,7 @@ public final class CreateInfo implements ICreateInfo {
"android.content.res.Resources#getDimensionPixelSize",
"android.content.res.Resources#getDrawable",
"android.content.res.Resources#getFont",
+ "android.content.res.Resources#getIdentifier",
"android.content.res.Resources#getIntArray",
"android.content.res.Resources#getInteger",
"android.content.res.Resources#getLayout",