diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2021-06-19 12:05:33 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2021-06-19 12:05:33 +0000 |
commit | 008521ac77a0bd3d07ca88bacdf22058de3feb1e (patch) | |
tree | 9e1a3d30b39c2c7ab4f6ff97be6aec9c808d4b89 | |
parent | 6874846eda0321a78dac2bbaee8452f96d85b9e7 (diff) | |
parent | a97634658360f16c4943fb70b6836c450467729b (diff) | |
download | layoutlib-android12-mainline-media-swcodec-release.tar.gz |
Snap for 7474514 from a97634658360f16c4943fb70b6836c450467729b to mainline-media-swcodec-releaseandroid-mainline-12.0.0_r91android-mainline-12.0.0_r75android-mainline-12.0.0_r47android-mainline-12.0.0_r30android-mainline-12.0.0_r13android-mainline-12.0.0_r120android-mainline-12.0.0_r105android12-mainline-media-swcodec-release
Change-Id: Ia250a0689f0ad83c38b3aebdb8240f01350f5461
132 files changed, 2069 insertions, 1074 deletions
diff --git a/.idea/artifacts/studio_android_widgets_jar.xml b/.idea/artifacts/studio_android_widgets_jar.xml deleted file mode 100644 index 0450be35ae..0000000000 --- a/.idea/artifacts/studio_android_widgets_jar.xml +++ /dev/null @@ -1,8 +0,0 @@ -<component name="ArtifactManager"> - <artifact type="jar" name="studio-android-widgets:jar"> - <output-path>$PROJECT_DIR$/out/artifacts/studio_android_widgets_jar</output-path> - <root id="archive" name="studio-android-widgets.jar"> - <element id="module-output" name="studio-android-widgets" /> - </root> - </artifact> -</component>
\ No newline at end of file diff --git a/.idea/artifacts/studio_android_widgets_src_jar.xml b/.idea/artifacts/studio_android_widgets_src_jar.xml deleted file mode 100644 index a844ca34d8..0000000000 --- a/.idea/artifacts/studio_android_widgets_src_jar.xml +++ /dev/null @@ -1,8 +0,0 @@ -<component name="ArtifactManager"> - <artifact type="jar" name="studio-android-widgets-src:jar"> - <output-path>$PROJECT_DIR$/out/artifacts/studio_android_widgets_src_jar</output-path> - <root id="archive" name="studio-android-widgets-src.jar"> - <element id="dir-copy" path="$PROJECT_DIR$/studio-custom-widgets/src" /> - </root> - </artifact> -</component>
\ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml index 50836c1e64..52102152a7 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -9,7 +9,6 @@ <module fileurl="file://$PROJECT_DIR$/remote/common/remote common.iml" filepath="$PROJECT_DIR$/remote/common/remote common.iml" group="remote" /> <module fileurl="file://$PROJECT_DIR$/remote/server/remote server.iml" filepath="$PROJECT_DIR$/remote/server/remote server.iml" group="remote" /> <module fileurl="file://$PROJECT_DIR$/remote/tests/remote tests.iml" filepath="$PROJECT_DIR$/remote/tests/remote tests.iml" group="remote" /> - <module fileurl="file://$PROJECT_DIR$/studio-custom-widgets/studio-android-widgets.iml" filepath="$PROJECT_DIR$/studio-custom-widgets/studio-android-widgets.iml" /> <module fileurl="file://$PROJECT_DIR$/validator/validator.iml" filepath="$PROJECT_DIR$/validator/validator.iml" /> </modules> </component> diff --git a/Android.bp b/Android.bp index b38baa2b8a..048b78e942 100644 --- a/Android.bp +++ b/Android.bp @@ -20,14 +20,42 @@ // transform the framework jar into the temp_layoutlib jar. // +package { + default_applicable_licenses: ["frameworks_layoutlib_license"], +} + +// Added automatically by a large-scale-change that took the approach of +// 'apply every license found to every target'. While this makes sure we respect +// every license restriction, it may not be entirely correct. +// +// e.g. GPL in an MIT project might only apply to the contrib/ directory. +// +// Please consider splitting the single license below into multiple licenses, +// taking care not to lose any license_kind information, and overriding the +// default license using the 'licenses: [...]' property on targets as needed. +// +// For unused files, consider creating a 'fileGroup' with "//visibility:private" +// to attach the license to, and including a comment whether the files may be +// used in the current project. +// See: http://go/android-license-faq +license { + name: "frameworks_layoutlib_license", + visibility: [":__subpackages__"], + license_kinds: [ + "SPDX-license-identifier-Apache-2.0", + "SPDX-license-identifier-EPL", + ], + // large-scale-change unable to identify any license_text files +} + java_genrule_host { name: "temp_layoutlib", tools: ["layoutlib_create"], out: ["temp_layoutlib.jar"], srcs: [ ":atf-prebuilt{.jar}", - ":core-icu4j{.jar}", - ":core-libart{.jar}", + ":core-icu4j-for-host{.jar}", + ":core-libart-for-host{.jar}", ":framework-all{.jar}", ":ext{.jar}", ":icu4j-icudata-jarjar{.jar}", // HOST diff --git a/METADATA b/METADATA new file mode 100644 index 0000000000..487c3e38ce --- /dev/null +++ b/METADATA @@ -0,0 +1,11 @@ +third_party { + # would be NOTICE save for EPL in: + # create/tests/res/mock_data/mock_android/fake/InnerTest.java + # create/tests/res/mock_data/mock_android/util/EmptyArray.java + # create/tests/res/mock_data/mock_android/view/View.java + # create/tests/res/mock_data/mock_android/view/ViewGroup.java + # create/tests/res/mock_data/mock_android/widget/LinearLayout.java + # create/tests/res/mock_data/mock_android/widget/TableLayout.java + # create/tests/res/mock_data/notjava/lang/JavaClass.java + license_type: RECIPROCAL +} diff --git a/bridge/Android.bp b/bridge/Android.bp index fa07cb8f68..6e86073052 100644 --- a/bridge/Android.bp +++ b/bridge/Android.bp @@ -14,6 +14,10 @@ // limitations under the License. // +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + java_library_host { name: "layoutlib", @@ -32,8 +36,11 @@ java_library_host { "ninepatch-prebuilt", "layoutlib-common", "layoutlib-validator", + "sdk-common", ], + jarjar_rules: "jarjar-rules.txt", + dist: { targets: ["layoutlib"], }, @@ -58,8 +65,11 @@ java_library_host { "ninepatch-prebuilt", "layoutlib-common", "layoutlib-validator", + "sdk-common", ], + jarjar_rules: "jarjar-rules.txt", + dist: { targets: ["layoutlib"], }, diff --git a/bridge/bridge.iml b/bridge/bridge.iml index 9358a54f3c..c9ce012ce1 100644 --- a/bridge/bridge.iml +++ b/bridge/bridge.iml @@ -102,5 +102,16 @@ <SOURCES /> </library> </orderEntry> + <orderEntry type="module-library"> + <library> + <CLASSES> + <root url="jar://$MODULE_DIR$/../../../prebuilts/misc/common/sdk-common/sdk-common.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="jar://$MODULE_DIR$/../../../prebuilts/misc/common/sdk-common/sdk-common-sources.jar!/" /> + </SOURCES> + </library> + </orderEntry> </component> </module>
\ No newline at end of file diff --git a/bridge/jarjar-rules.txt b/bridge/jarjar-rules.txt new file mode 100644 index 0000000000..3318faad1d --- /dev/null +++ b/bridge/jarjar-rules.txt @@ -0,0 +1 @@ +rule com.google.protobuf.** com.android.layoutlib.protobuf.@1 diff --git a/bridge/src/android/app/ActivityManager_Accessor.java b/bridge/src/android/app/ActivityManager_Accessor.java new file mode 100644 index 0000000000..aa79658c02 --- /dev/null +++ b/bridge/src/android/app/ActivityManager_Accessor.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2020 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.app; + +import android.annotation.NonNull; +import android.content.Context; + +public class ActivityManager_Accessor { + @NonNull + public static ActivityManager getActivityManagerInstance(@NonNull Context context) { + return new ActivityManager(context, null); + } +} diff --git a/bridge/src/android/content/res/BridgeTypedArray.java b/bridge/src/android/content/res/BridgeTypedArray.java index 5023dcb2e8..eb603f0ebe 100644 --- a/bridge/src/android/content/res/BridgeTypedArray.java +++ b/bridge/src/android/content/res/BridgeTypedArray.java @@ -18,7 +18,7 @@ package android.content.res; import com.android.ide.common.rendering.api.ArrayResourceValue; import com.android.ide.common.rendering.api.AttrResourceValue; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.ide.common.rendering.api.RenderResources; import com.android.ide.common.rendering.api.ResourceNamespace; import com.android.ide.common.rendering.api.ResourceNamespace.Resolver; @@ -26,6 +26,7 @@ import com.android.ide.common.rendering.api.ResourceReference; import com.android.ide.common.rendering.api.ResourceValue; import com.android.ide.common.rendering.api.StyleResourceValue; import com.android.ide.common.rendering.api.TextResourceValue; +import com.android.ide.common.resources.ValueXmlHelper; import com.android.internal.util.XmlUtils; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.android.BridgeContext; @@ -73,6 +74,8 @@ import static com.android.ide.common.rendering.api.RenderResources.REFERENCE_UND * Custom implementation of TypedArray to handle non compiled resources. */ public final class BridgeTypedArray extends TypedArray { + private static final String MATCH_PARENT_INT_STRING = String.valueOf(LayoutParams.MATCH_PARENT); + private static final String WRAP_CONTENT_INT_STRING = String.valueOf(LayoutParams.WRAP_CONTENT); private final Resources mBridgeResources; private final BridgeContext mContext; @@ -208,7 +211,9 @@ public final class BridgeTypedArray extends TypedArray { ResourceValue resourceValue = mResourceData[index]; String value = resourceValue.getValue(); if (resourceValue instanceof TextResourceValue) { - String rawValue = resourceValue.getRawXmlValue(); + String rawValue = + ValueXmlHelper.unescapeResourceString(resourceValue.getRawXmlValue(), + true, false); if (rawValue != null && !rawValue.equals(value)) { return Html.fromHtml(rawValue, FROM_HTML_MODE_COMPACT); } @@ -265,7 +270,7 @@ public final class BridgeTypedArray extends TypedArray { try { return convertValueToInt(s, defValue); } catch (NumberFormatException e) { - Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT, + Bridge.getLog().warning(ILayoutLog.TAG_RESOURCES_FORMAT, String.format("\"%1$s\" in attribute \"%2$s\" is not a valid integer", s, mNames[index]), null, null); @@ -288,7 +293,7 @@ public final class BridgeTypedArray extends TypedArray { return Float.parseFloat(s); } } catch (NumberFormatException e) { - Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT, + Bridge.getLog().warning(ILayoutLog.TAG_RESOURCES_FORMAT, String.format("\"%1$s\" in attribute \"%2$s\" cannot be converted to float.", s, mNames[index]), null, null); @@ -382,13 +387,11 @@ public final class BridgeTypedArray extends TypedArray { return defValue; } // Check if the value is a magic constant that doesn't require a unit. - try { - int i = Integer.parseInt(s); - if (i == LayoutParams.MATCH_PARENT || i == LayoutParams.WRAP_CONTENT) { - return i; - } - } catch (NumberFormatException ignored) { - // pass + if (MATCH_PARENT_INT_STRING.equals(s)) { + return LayoutParams.MATCH_PARENT; + } + if (WRAP_CONTENT_INT_STRING.equals(s)) { + return LayoutParams.WRAP_CONTENT; } if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true)) { @@ -440,21 +443,33 @@ public final class BridgeTypedArray extends TypedArray { */ @Override public int getDimensionPixelSize(int index, int defValue) { - try { - return getDimension(index, null); - } catch (RuntimeException e) { - String s = getString(index); + String s = getString(index); + if (s == null) { + return defValue; + } - if (s != null) { - // looks like we were unable to resolve the dimension value - Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT, - String.format("\"%1$s\" in attribute \"%2$s\" is not a valid format.", - s, mNames[index]), - null, null); - } + if (MATCH_PARENT_INT_STRING.equals(s)) { + return LayoutParams.MATCH_PARENT; + } + if (WRAP_CONTENT_INT_STRING.equals(s)) { + return LayoutParams.WRAP_CONTENT; + } - return defValue; + if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true)) { + float f = mValue.getDimension(mBridgeResources.getDisplayMetrics()); + + final int res = (int) (f + 0.5f); + if (res != 0) return res; + if (f == 0) return 0; + if (f > 0) return 1; } + + // looks like we were unable to resolve the dimension value + Bridge.getLog().warning(ILayoutLog.TAG_RESOURCES_FORMAT, + String.format("\"%1$s\" in attribute \"%2$s\" is not a valid format.", s, mNames[index]), + null, null); + + return defValue; } /** @@ -471,21 +486,34 @@ public final class BridgeTypedArray extends TypedArray { */ @Override public int getLayoutDimension(int index, String name) { - try { - // this will throw an exception if not found. - return getDimension(index, name); - } catch (RuntimeException e) { - - if (LayoutInflater_Delegate.sIsInInclude) { - throw new RuntimeException("Layout Dimension '" + name + "' not found."); + String s = getString(index); + if (s != null) { + // Check if the value is a magic constant that doesn't require a unit. + if (MATCH_PARENT_INT_STRING.equals(s)) { + return LayoutParams.MATCH_PARENT; + } + if (WRAP_CONTENT_INT_STRING.equals(s)) { + return LayoutParams.WRAP_CONTENT; } - Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT, - "You must supply a " + name + " attribute.", - null, null); + if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true)) { + float f = mValue.getDimension(mBridgeResources.getDisplayMetrics()); - return 0; + final int res = (int) (f + 0.5f); + if (res != 0) return res; + if (f == 0) return 0; + if (f > 0) return 1; + } + } + + if (LayoutInflater_Delegate.sIsInInclude) { + throw new RuntimeException("Layout Dimension '" + name + "' not found."); } + + Bridge.getLog().warning(ILayoutLog.TAG_RESOURCES_FORMAT, + "You must supply a " + name + " attribute.", null, null); + + return 0; } @Override @@ -493,36 +521,6 @@ public final class BridgeTypedArray extends TypedArray { return getDimensionPixelSize(index, defValue); } - /** @param name attribute name, used for error reporting. */ - private int getDimension(int index, @Nullable String name) { - String s = getString(index); - if (s == null) { - if (name != null) { - throw new RuntimeException("Attribute '" + name + "' not found"); - } - throw new RuntimeException(); - } - // Check if the value is a magic constant that doesn't require a unit. - try { - int i = Integer.parseInt(s); - if (i == LayoutParams.MATCH_PARENT || i == LayoutParams.WRAP_CONTENT) { - return i; - } - } catch (NumberFormatException ignored) { - // pass - } - if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true)) { - float f = mValue.getDimension(mBridgeResources.getDisplayMetrics()); - - final int res = (int)(f+0.5f); - if (res != 0) return res; - if (f == 0) return 0; - if (f > 0) return 1; - } - - throw new RuntimeException(); - } - /** * Retrieve a fractional unit attribute at <var>index</var>. * @@ -550,7 +548,7 @@ public final class BridgeTypedArray extends TypedArray { } // looks like we were unable to resolve the fraction value - Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT, + Bridge.getLog().warning(ILayoutLog.TAG_RESOURCES_FORMAT, String.format( "\"%1$s\" in attribute \"%2$s\" cannot be converted to a fraction.", value, mNames[index]), @@ -809,57 +807,9 @@ public final class BridgeTypedArray extends TypedArray { } @Override - @SuppressWarnings("ResultOfMethodCallIgnored") public int getType(int index) { String value = getString(index); - if (value == null) { - return TYPE_NULL; - } - if (value.startsWith(PREFIX_RESOURCE_REF)) { - return TYPE_REFERENCE; - } - if (value.startsWith(PREFIX_THEME_REF)) { - return TYPE_ATTRIBUTE; - } - try { - // Don't care about the value. Only called to check if an exception is thrown. - convertValueToInt(value, 0); - if (value.startsWith("0x") || value.startsWith("0X")) { - return TYPE_INT_HEX; - } - // is it a color? - if (value.startsWith("#")) { - int length = value.length() - 1; - if (length == 3) { // rgb - return TYPE_INT_COLOR_RGB4; - } - if (length == 4) { // argb - return TYPE_INT_COLOR_ARGB4; - } - if (length == 6) { // rrggbb - return TYPE_INT_COLOR_RGB8; - } - if (length == 8) { // aarrggbb - return TYPE_INT_COLOR_ARGB8; - } - } - if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false")) { - return TYPE_INT_BOOLEAN; - } - return TYPE_INT_DEC; - } catch (NumberFormatException ignored) { - try { - Float.parseFloat(value); - return TYPE_FLOAT; - } catch (NumberFormatException ignore) { - } - // Might be a dimension. - if (ResourceHelper.parseFloatAttribute(null, value, new TypedValue(), false)) { - return TYPE_DIMENSION; - } - } - // TODO: handle fractions. - return TYPE_STRING; + return getType(value); } /** @@ -1031,6 +981,73 @@ public final class BridgeTypedArray extends TypedArray { return ((int)Long.parseLong(charSeq.substring(index), base)) * sign; } + protected static int getType(@Nullable String value) { + if (value == null) { + return TYPE_NULL; + } + if (value.startsWith(PREFIX_RESOURCE_REF)) { + return TYPE_REFERENCE; + } + if (value.startsWith(PREFIX_THEME_REF)) { + return TYPE_ATTRIBUTE; + } + if (value.equals("true") || value.equals("false")) { + return TYPE_INT_BOOLEAN; + } + if (value.startsWith("0x") || value.startsWith("0X")) { + try { + // Check if it is a hex value. + Long.parseLong(value.substring(2), 16); + return TYPE_INT_HEX; + } catch (NumberFormatException e) { + return TYPE_STRING; + } + } + if (value.startsWith("#")) { + try { + // Check if it is a color. + ResourceHelper.getColor(value); + int length = value.length() - 1; + if (length == 3) { // rgb + return TYPE_INT_COLOR_RGB4; + } + if (length == 4) { // argb + return TYPE_INT_COLOR_ARGB4; + } + if (length == 6) { // rrggbb + return TYPE_INT_COLOR_RGB8; + } + if (length == 8) { // aarrggbb + return TYPE_INT_COLOR_ARGB8; + } + } catch (NumberFormatException e) { + return TYPE_STRING; + } + } + if (!Character.isDigit(value.charAt(value.length() - 1))) { + // Check if it is a dimension. + if (ResourceHelper.parseFloatAttribute(null, value, new TypedValue(), false)) { + return TYPE_DIMENSION; + } else { + return TYPE_STRING; + } + } + try { + // Check if it is an int. + convertValueToInt(value, 0); + return TYPE_INT_DEC; + } catch (NumberFormatException ignored) { + try { + // Check if it is a float. + Float.parseFloat(value); + return TYPE_FLOAT; + } catch (NumberFormatException ignore) { + } + } + // TODO: handle fractions. + return TYPE_STRING; + } + static TypedArray obtain(Resources res, int len) { return new BridgeTypedArray(res, null, len); } diff --git a/bridge/src/android/content/res/Resources_Delegate.java b/bridge/src/android/content/res/Resources_Delegate.java index a5216bc008..2689acda75 100644 --- a/bridge/src/android/content/res/Resources_Delegate.java +++ b/bridge/src/android/content/res/Resources_Delegate.java @@ -20,7 +20,7 @@ import com.android.SdkConstants; import com.android.ide.common.rendering.api.ArrayResourceValue; import com.android.ide.common.rendering.api.AssetRepository; import com.android.ide.common.rendering.api.DensityBasedResourceValue; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.ide.common.rendering.api.LayoutlibCallback; import com.android.ide.common.rendering.api.PluralsResourceValue; import com.android.ide.common.rendering.api.RenderResources; @@ -42,7 +42,7 @@ 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; +import com.android.utils.Pair; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -71,7 +71,6 @@ import static android.content.res.AssetManager.ACCESS_STREAMING; 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 WeakHashMap<>(); @@ -226,7 +225,7 @@ public class Resources_Delegate { } else { message = e.getMessage(); } - Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, message, e, null, null); + Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_FORMAT, message, e, null, null); return 0; } } @@ -372,16 +371,16 @@ public class Resources_Delegate { values[i] = getInt(element); } } catch (NumberFormatException e) { - Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, + Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_FORMAT, "Integer resource array contains non-integer value: \"" + element + "\"", null, null); } catch (IllegalArgumentException e) { - Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, + Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_FORMAT, "Integer resource array contains wrong color format: \"" + element + "\"", null, null); } } else { - Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, + Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_FORMAT, "Integer resource array contains non-integer value: \"" + resValue.getElement(i) + "\"", null, null); } @@ -395,13 +394,13 @@ public class Resources_Delegate { try { return new int[]{getInt(firstValue)}; } catch (NumberFormatException e) { - Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, + Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_FORMAT, "Integer resource array contains non-integer value: \"" + firstValue + "\"", null, null); return new int[1]; } } else { - Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, + Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_FORMAT, "Integer resource array contains non-integer value: \"" + rv.getValue() + "\"", null, null); return new int[1]; @@ -432,7 +431,7 @@ public class Resources_Delegate { if (resValue != null) { final ResourceType type = resValue.getResourceType(); if (type != ResourceType.ARRAY) { - Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE, + Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_RESOLVE, String.format( "Resource with id 0x%1$X is not an array resource, but %2$s", id, type == null ? "null" : type.getDisplayName()), @@ -440,7 +439,7 @@ public class Resources_Delegate { return null; } if (!(resValue instanceof ArrayResourceValue)) { - Bridge.getLog().warning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().warning(ILayoutLog.TAG_UNSUPPORTED, "Obtaining resource arrays via getTextArray, getStringArray or getIntArray is not fully supported in this version of the IDE.", null, null); } @@ -488,7 +487,7 @@ public class Resources_Delegate { return parser; } } catch (XmlPullParserException e) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "Failed to parse " + value.getValue(), e, null, null /*data*/); // we'll return null below. } @@ -511,7 +510,7 @@ public class Resources_Delegate { try { return ResourceHelper.getXmlBlockParser(getContext(resources), value); } catch (XmlPullParserException e) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "Failed to parse " + value.getValue(), e, null, null /*data*/); // we'll return null below. } @@ -946,7 +945,7 @@ public class Resources_Delegate { try { return ResourceHelper.getXmlBlockParser(getContext(resources), value); } catch (XmlPullParserException e) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "Failed to parse " + value.getValue(), e, null, null /*data*/); // we'll return null below. } @@ -1078,12 +1077,12 @@ public class Resources_Delegate { } // We have package but no type String pkg = name.substring(0, colonIdx); - ResourceType type = ResourceType.getEnum(defType); + ResourceType type = ResourceType.fromClassName(defType); return type != null ? ResourceUrl.create(pkg, type, name.substring(colonIdx + 1)) : null; } - ResourceType type = ResourceType.getEnum(name.substring(0, slashIdx)); + ResourceType type = ResourceType.fromClassName(name.substring(0, slashIdx)); if (type == null) { return null; } diff --git a/bridge/src/android/graphics/BaseCanvas_Delegate.java b/bridge/src/android/graphics/BaseCanvas_Delegate.java index df28305931..5a9236ca2e 100644 --- a/bridge/src/android/graphics/BaseCanvas_Delegate.java +++ b/bridge/src/android/graphics/BaseCanvas_Delegate.java @@ -16,7 +16,7 @@ package android.graphics; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.layoutlib.bridge.impl.GcSnapshot; @@ -29,7 +29,11 @@ import android.text.TextUtils; import android.util.imagepool.ImagePool; import android.util.imagepool.ImagePoolProvider; -import java.awt.*; +import java.awt.Composite; +import java.awt.Graphics2D; +import java.awt.PaintContext; +import java.awt.RenderingHints; +import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.Arc2D; import java.awt.geom.Area; @@ -167,7 +171,7 @@ public class BaseCanvas_Delegate { @LayoutlibDelegate /*package*/ static void nDrawPaint(long nativeCanvas, long paint) { // FIXME - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Canvas.drawPaint is not supported.", null,null, null /*data*/); } @@ -420,7 +424,7 @@ public class BaseCanvas_Delegate { /*package*/ static void nDrawRegion(long nativeCanvas, long nativeRegion, long nativePaint) { // FIXME - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Some canvas paths may not be drawn", null, null, null); } @@ -512,7 +516,7 @@ public class BaseCanvas_Delegate { int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset, long nPaint) { // FIXME - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Canvas.drawBitmapMesh is not supported.", null, null, null /*data*/); } @@ -524,7 +528,7 @@ public class BaseCanvas_Delegate { short[] indices, int indexOffset, int indexCount, long nPaint) { // FIXME - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Canvas.drawVertices is not supported.", null, null, null /*data*/); } @@ -573,7 +577,7 @@ public class BaseCanvas_Delegate { float vOffset, int bidiFlags, long paint) { // FIXME - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Canvas.drawTextOnPath is not supported.", null, null, null /*data*/); } @@ -584,7 +588,7 @@ public class BaseCanvas_Delegate { float vOffset, int bidiFlags, long paint) { // FIXME - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Canvas.drawTextOnPath is not supported.", null, null, null /*data*/); } diff --git a/bridge/src/android/graphics/BidiRenderer.java b/bridge/src/android/graphics/BidiRenderer.java index 1de2a45a16..40d350b158 100644 --- a/bridge/src/android/graphics/BidiRenderer.java +++ b/bridge/src/android/graphics/BidiRenderer.java @@ -16,7 +16,7 @@ package android.graphics; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import android.annotation.NonNull; @@ -222,7 +222,7 @@ public class BidiRenderer { } private static void logFontWarning() { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_BROKEN, "Some fonts could not be loaded. The rendering may not be perfect.", null, null, null); } diff --git a/bridge/src/android/graphics/BitmapFactory_Delegate.java b/bridge/src/android/graphics/BitmapFactory_Delegate.java index b344451400..7a12d382f5 100644 --- a/bridge/src/android/graphics/BitmapFactory_Delegate.java +++ b/bridge/src/android/graphics/BitmapFactory_Delegate.java @@ -73,12 +73,9 @@ import java.util.Set; npis, true /*is9Patch*/, false /*convert*/); // get the bitmap and chunk objects. - bm = Bitmap_Delegate.createBitmap(ninePatch.getImage(), bitmapCreateFlags, - density); NinePatchChunk chunk = ninePatch.getChunk(); - - // put the chunk in the bitmap - bm.setNinePatchChunk(NinePatch_Delegate.serialize(chunk)); + bm = Bitmap_Delegate.createBitmap(ninePatch.getImage(), + NinePatch_Delegate.serialize(chunk), bitmapCreateFlags, density); if (padding != null) { // read the padding diff --git a/bridge/src/android/graphics/BitmapShader_Delegate.java b/bridge/src/android/graphics/BitmapShader_Delegate.java index 53b1db6e14..e763824e18 100644 --- a/bridge/src/android/graphics/BitmapShader_Delegate.java +++ b/bridge/src/android/graphics/BitmapShader_Delegate.java @@ -16,7 +16,7 @@ package android.graphics; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; @@ -118,7 +118,7 @@ public class BitmapShader_Delegate extends Shader_Delegate { try { canvasMatrix = xform.createInverse(); } catch (NoninvertibleTransformException e) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MATRIX_INVERSE, "Unable to inverse matrix in BitmapShader", e, null, null /*data*/); canvasMatrix = new AffineTransform(); } @@ -127,7 +127,7 @@ public class BitmapShader_Delegate extends Shader_Delegate { try { localMatrix = localMatrix.createInverse(); } catch (NoninvertibleTransformException e) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MATRIX_INVERSE, "Unable to inverse matrix in BitmapShader", e, null, null /*data*/); localMatrix = new AffineTransform(); } diff --git a/bridge/src/android/graphics/Bitmap_Delegate.java b/bridge/src/android/graphics/Bitmap_Delegate.java index 7fc952d10c..bfd00c5e8f 100644 --- a/bridge/src/android/graphics/Bitmap_Delegate.java +++ b/bridge/src/android/graphics/Bitmap_Delegate.java @@ -17,7 +17,7 @@ package android.graphics; import com.android.ide.common.rendering.api.AssetRepository; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.ide.common.rendering.api.RenderResources; import com.android.ide.common.rendering.api.ResourceValue; import com.android.layoutlib.bridge.Bridge; @@ -143,7 +143,7 @@ public final class Bitmap_Delegate { Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888); delegate.mIsMutable = createFlags.contains(BitmapCreateFlags.MUTABLE); - return createBitmap(delegate, createFlags, density.getDpiValue()); + return createBitmap(delegate, createFlags, density.getDpiValue(), null); } /** @@ -172,11 +172,27 @@ public final class Bitmap_Delegate { */ public static Bitmap createBitmap(BufferedImage image, Set<BitmapCreateFlags> createFlags, Density density) { + return createBitmap(image, null, createFlags, density); + } + + /** + * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage} + * + * @param image the bitmap content + * @param ninePatchChunk serialized ninepatch data + * @param density the density associated with the bitmap + * + * @see Bitmap#isPremultiplied() + * @see Bitmap#isMutable() + * @see Bitmap#getDensity() + */ + public static Bitmap createBitmap(BufferedImage image, byte[] ninePatchChunk, + Set<BitmapCreateFlags> createFlags, Density density) { // create a delegate with the given image. Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888); delegate.mIsMutable = createFlags.contains(BitmapCreateFlags.MUTABLE); - return createBitmap(delegate, createFlags, density.getDpiValue()); + return createBitmap(delegate, createFlags, density.getDpiValue(), ninePatchChunk); } private static int getBufferedImageType() { @@ -234,7 +250,7 @@ public final class Bitmap_Delegate { delegate.mIsMutable = isMutable; return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable), - Bitmap.getDefaultDensity()); + Bitmap.getDefaultDensity(), null); } @LayoutlibDelegate @@ -264,7 +280,7 @@ public final class Bitmap_Delegate { delegate.mIsMutable = isMutable; return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable), - Bitmap.getDefaultDensity()); + Bitmap.getDefaultDensity(), null); } @LayoutlibDelegate @@ -299,14 +315,14 @@ public final class Bitmap_Delegate { @LayoutlibDelegate /*package*/ static void nativeReconfigure(long nativeBitmap, int width, int height, int config, boolean isPremultiplied) { - Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED, "Bitmap.reconfigure() is not supported", null, null /*data*/); } @LayoutlibDelegate /*package*/ static boolean nativeCompress(long nativeBitmap, int format, int quality, OutputStream stream, byte[] tempStorage) { - Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED, "Bitmap.compress() is not supported", null, null /*data*/); return true; } @@ -426,14 +442,14 @@ public final class Bitmap_Delegate { @LayoutlibDelegate /*package*/ static void nativeCopyPixelsToBuffer(long nativeBitmap, Buffer dst) { // FIXME implement native delegate - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Bitmap.copyPixelsToBuffer is not supported.", null, null, null /*data*/); } @LayoutlibDelegate /*package*/ static void nativeCopyPixelsFromBuffer(long nb, Buffer src) { // FIXME implement native delegate - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Bitmap.copyPixelsFromBuffer is not supported.", null, null, null /*data*/); } @@ -451,7 +467,7 @@ public final class Bitmap_Delegate { /*package*/ static Bitmap nativeCreateFromParcel(Parcel p) { // This is only called by Bitmap.CREATOR (Parcelable.Creator<Bitmap>), which is only // used during aidl call so really this should not be called. - Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED, "AIDL is not suppored, and therefore Bitmaps cannot be created from parcels.", null, null /*data*/); return null; @@ -461,7 +477,7 @@ public final class Bitmap_Delegate { /*package*/ static boolean nativeWriteToParcel(long nativeBitmap, int density, Parcel p) { // This is only called when sending a bitmap through aidl, so really this should not // be called. - Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED, "AIDL is not suppored, and therefore Bitmaps cannot be written to parcels.", null, null /*data*/); return false; @@ -479,7 +495,7 @@ public final class Bitmap_Delegate { Paint_Delegate paint = Paint_Delegate.getDelegate(nativePaint); if (paint != null && paint.getMaskFilter() != null) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MASKFILTER, "MaskFilter not supported in Bitmap.extractAlpha", null, null, null /*data*/); } @@ -493,7 +509,7 @@ public final class Bitmap_Delegate { // the density doesn't matter, it's set by the Java method. return createBitmap(delegate, EnumSet.of(BitmapCreateFlags.MUTABLE), - Density.DEFAULT_DENSITY /*density*/); + Density.DEFAULT_DENSITY /*density*/, null); } @LayoutlibDelegate @@ -617,47 +633,40 @@ public final class Bitmap_Delegate { delegate.mIsMutable = srcBmpDelegate.mIsMutable; return createBitmap(delegate, EnumSet.of(BitmapCreateFlags.NONE), - Bitmap.getDefaultDensity()); + Bitmap.getDefaultDensity(), null); } @LayoutlibDelegate /*package*/ static Bitmap nativeWrapHardwareBufferBitmap(HardwareBuffer buffer, long nativeColorSpace) { - Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED, "Bitmap.nativeWrapHardwareBufferBitmap() is not supported", null, null, null); return null; } @LayoutlibDelegate - /*package*/ static GraphicBuffer nativeCreateGraphicBufferHandle(long nativeBitmap) { - Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, - "Bitmap.nativeCreateGraphicBufferHandle() is not supported", null /*data*/); - return null; - } - - @LayoutlibDelegate /*package*/ static boolean nativeIsSRGB(long nativeBitmap) { - Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED, "Color spaces are not supported", null, null /*data*/); return false; } @LayoutlibDelegate /*package*/ static ColorSpace nativeComputeColorSpace(long nativePtr) { - Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED, "Color spaces are not supported", null, null /*data*/); return null; } @LayoutlibDelegate /*package*/ static void nativeSetColorSpace(long nativePtr, long nativeColorSpace) { - Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED, "Color spaces are not supported", null, null /*data*/); } @LayoutlibDelegate /*package*/ static boolean nativeIsSRGBLinear(long nativePtr) { - Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED, "Color spaces are not supported", null, null /*data*/); return false; } @@ -682,7 +691,7 @@ public final class Bitmap_Delegate { @LayoutlibDelegate /*package*/ static HardwareBuffer nativeGetHardwareBuffer(long nativeBitmap) { - Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED, "HardwareBuffer is not supported", null, null /*data*/); return null; } @@ -695,7 +704,7 @@ public final class Bitmap_Delegate { } private static Bitmap createBitmap(Bitmap_Delegate delegate, - Set<BitmapCreateFlags> createFlags, int density) { + Set<BitmapCreateFlags> createFlags, int density, byte[] ninePatchChunk) { // get its native_int long nativeInt = sManager.addNewDelegate(delegate); @@ -705,7 +714,7 @@ public final class Bitmap_Delegate { // and create/return a new Bitmap with it return new Bitmap(nativeInt, width, height, density, isPremultiplied, - null /*ninePatchChunk*/, null /* layoutBounds */, true /* fromMalloc */); + ninePatchChunk, null /* layoutBounds */, true /* fromMalloc */); } private static Set<BitmapCreateFlags> getPremultipliedBitmapCreateFlags(boolean isMutable) { diff --git a/bridge/src/android/graphics/Canvas_Delegate.java b/bridge/src/android/graphics/Canvas_Delegate.java index afcb40ca19..19e88b6d3b 100644 --- a/bridge/src/android/graphics/Canvas_Delegate.java +++ b/bridge/src/android/graphics/Canvas_Delegate.java @@ -16,13 +16,12 @@ package android.graphics; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.layoutlib.bridge.impl.GcSnapshot; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; -import android.annotation.Nullable; import android.graphics.Bitmap.Config; import java.awt.Graphics2D; @@ -354,7 +353,7 @@ public final class Canvas_Delegate extends BaseCanvas_Delegate { if (matrixDelegate.hasPerspective()) { assert false; - Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_AFFINE, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MATRIX_AFFINE, "android.graphics.Canvas#setMatrix(android.graphics.Matrix) only " + "supports affine transformations.", null, null, null /*data*/); } @@ -401,7 +400,7 @@ public final class Canvas_Delegate extends BaseCanvas_Delegate { canvasDelegate.mDrawFilter = DrawFilter_Delegate.getDelegate(nativeFilter); if (canvasDelegate.mDrawFilter != null && !canvasDelegate.mDrawFilter.isSupported()) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_DRAWFILTER, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_DRAWFILTER, canvasDelegate.mDrawFilter.getSupportMessage(), null, null, null /*data*/); } } diff --git a/bridge/src/android/graphics/FontFamily_Delegate.java b/bridge/src/android/graphics/FontFamily_Delegate.java index afcf9bd9f4..a452aae16b 100644 --- a/bridge/src/android/graphics/FontFamily_Delegate.java +++ b/bridge/src/android/graphics/FontFamily_Delegate.java @@ -16,7 +16,7 @@ package android.graphics; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; @@ -183,7 +183,7 @@ public class FontFamily_Delegate { } } } catch (FileNotFoundException e) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "Unable to load the list of fonts. Try re-installing the SDK Platform from the SDK Manager.", e, null, null); } finally { @@ -268,12 +268,12 @@ public class FontFamily_Delegate { // warning. return null; } - Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_BROKEN, String.format("Unable to load font %1$s", relativePath), e, null, null); } } else { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Only platform fonts located in " + SYSTEM_FONTS + "can be loaded.", null, null, null); } diff --git a/bridge/src/android/graphics/LinearGradient_Delegate.java b/bridge/src/android/graphics/LinearGradient_Delegate.java index 7b544fe6d7..4574dd7d80 100644 --- a/bridge/src/android/graphics/LinearGradient_Delegate.java +++ b/bridge/src/android/graphics/LinearGradient_Delegate.java @@ -16,7 +16,7 @@ package android.graphics; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; @@ -126,7 +126,7 @@ public final class LinearGradient_Delegate extends Gradient_Delegate { try { canvasMatrix = xform.createInverse(); } catch (java.awt.geom.NoninvertibleTransformException e) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MATRIX_INVERSE, "Unable to inverse matrix in LinearGradient", e, null, null /*data*/); canvasMatrix = new java.awt.geom.AffineTransform(); } @@ -135,7 +135,7 @@ public final class LinearGradient_Delegate extends Gradient_Delegate { try { localMatrix = localMatrix.createInverse(); } catch (java.awt.geom.NoninvertibleTransformException e) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MATRIX_INVERSE, "Unable to inverse matrix in LinearGradient", e, null, null /*data*/); localMatrix = new java.awt.geom.AffineTransform(); } diff --git a/bridge/src/android/graphics/Matrix_Delegate.java b/bridge/src/android/graphics/Matrix_Delegate.java index ca3cc96292..d0a0adc5e2 100644 --- a/bridge/src/android/graphics/Matrix_Delegate.java +++ b/bridge/src/android/graphics/Matrix_Delegate.java @@ -17,7 +17,7 @@ package android.graphics; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; @@ -25,7 +25,6 @@ import com.android.tools.layoutlib.annotations.LayoutlibDelegate; import android.graphics.Matrix.ScaleToFit; import java.awt.geom.AffineTransform; -import java.awt.geom.NoninvertibleTransformException; import libcore.util.NativeAllocationRegistry_Delegate; @@ -64,7 +63,7 @@ public final class Matrix_Delegate { * Returns an {@link AffineTransform} matching the given Matrix. */ public static AffineTransform getAffineTransform(Matrix m) { - Matrix_Delegate delegate = sManager.getDelegate(m.native_instance); + Matrix_Delegate delegate = sManager.getDelegate(m.ni()); if (delegate == null) { return null; } @@ -73,7 +72,7 @@ public final class Matrix_Delegate { } public static boolean hasPerspective(Matrix m) { - Matrix_Delegate delegate = sManager.getDelegate(m.native_instance); + Matrix_Delegate delegate = sManager.getDelegate(m.ni()); if (delegate == null) { return false; } @@ -598,7 +597,7 @@ public final class Matrix_Delegate { /*package*/ static boolean nSetPolyToPoly(long native_object, float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount) { // FIXME - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Matrix.setPolyToPoly is not supported.", null, null, null /*data*/); return false; diff --git a/bridge/src/android/graphics/NinePatch_Delegate.java b/bridge/src/android/graphics/NinePatch_Delegate.java index ca2a9ca595..28e682b6d3 100644 --- a/bridge/src/android/graphics/NinePatch_Delegate.java +++ b/bridge/src/android/graphics/NinePatch_Delegate.java @@ -16,7 +16,7 @@ package android.graphics; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.ninepatch.NinePatchChunk; @@ -120,11 +120,11 @@ public final class NinePatch_Delegate { sChunkCache.put(array, new SoftReference<>(chunk)); } } catch (IOException e) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "Failed to deserialize NinePatchChunk content.", e, null, null /*data*/); return null; } catch (ClassNotFoundException e) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "Failed to deserialize NinePatchChunk class.", e, null, null /*data*/); return null; } diff --git a/bridge/src/android/graphics/Paint_Delegate.java b/bridge/src/android/graphics/Paint_Delegate.java index 0512edf8a6..f6c6d71a92 100644 --- a/bridge/src/android/graphics/Paint_Delegate.java +++ b/bridge/src/android/graphics/Paint_Delegate.java @@ -16,7 +16,7 @@ package android.graphics; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; @@ -228,7 +228,7 @@ public class Paint_Delegate { return stroke; } } else { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_PATHEFFECT, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_PATHEFFECT, mPathEffect.getSupportMessage(), null, null, null /*data*/); } @@ -455,14 +455,14 @@ public class Paint_Delegate { /*package*/ static void nSetShadowLayer(long paintPtr, float radius, float dx, float dy, long colorSpaceHandle, long shadowColor) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Paint.setShadowLayer is not supported.", null, null, null /*data*/); } @LayoutlibDelegate /*package*/ static boolean nHasShadowLayer(long paint) { // FIXME - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Paint.hasShadowLayer is not supported.", null, null, null /*data*/); return false; } @@ -847,7 +847,7 @@ public class Paint_Delegate { // Log warning if it's not supported. if (delegate.mColorFilter != null && !delegate.mColorFilter.isSupported()) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_COLORFILTER, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_COLORFILTER, delegate.mColorFilter.getSupportMessage(), null, null, null /*data*/); } @@ -888,7 +888,7 @@ public class Paint_Delegate { // since none of those are supported, display a fidelity warning right away if (delegate.mMaskFilter != null && !delegate.mMaskFilter.isSupported()) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MASKFILTER, delegate.mMaskFilter.getSupportMessage(), null, null, null /*data*/); } @@ -984,7 +984,7 @@ public class Paint_Delegate { /*package*/ static int nGetTextRunCursor(Paint paint, long native_object, char[] text, int contextStart, int contextLength, int flags, int offset, int cursorOpt) { // FIXME - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Paint.getTextRunCursor is not supported.", null, null, null /*data*/); return 0; } @@ -993,7 +993,7 @@ public class Paint_Delegate { /*package*/ static int nGetTextRunCursor(Paint paint, long native_object, String text, int contextStart, int contextEnd, int flags, int offset, int cursorOpt) { // FIXME - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Paint.getTextRunCursor is not supported.", null, null, null /*data*/); return 0; } @@ -1002,7 +1002,7 @@ public class Paint_Delegate { /*package*/ static void nGetTextPath(long native_object, int bidiFlags, char[] text, int index, int count, float x, float y, long path) { // FIXME - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Paint.getTextPath is not supported.", null, null, null /*data*/); } @@ -1010,7 +1010,7 @@ public class Paint_Delegate { /*package*/ static void nGetTextPath(long native_object, int bidiFlags, String text, int start, int end, float x, float y, long path) { // FIXME - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Paint.getTextPath is not supported.", null, null, null /*data*/); } @@ -1056,7 +1056,7 @@ public class Paint_Delegate { @LayoutlibDelegate /*package*/ static void nSetLetterSpacing(long nativePaint, float letterSpacing) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_TEXT_RENDERING, "Paint.setLetterSpacing() not supported.", null, null, null); Paint_Delegate delegate = sManager.getDelegate(nativePaint); if (delegate == null) { @@ -1085,7 +1085,7 @@ public class Paint_Delegate { @LayoutlibDelegate /*package*/ static void nSetFontFeatureSettings(long nativePaint, String settings) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_TEXT_RENDERING, "Paint.setFontFeatureSettings() not supported.", null, null, null); } @@ -1135,7 +1135,7 @@ public class Paint_Delegate { return false; } if (string.length() > 1) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_TEXT_RENDERING, "Paint.hasGlyph() is not supported for ligatures.", null, null, null); return false; } diff --git a/bridge/src/android/graphics/PathMeasure_Delegate.java b/bridge/src/android/graphics/PathMeasure_Delegate.java index 7276c456a3..83a4ff1843 100644 --- a/bridge/src/android/graphics/PathMeasure_Delegate.java +++ b/bridge/src/android/graphics/PathMeasure_Delegate.java @@ -16,13 +16,12 @@ package android.graphics; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.layoutlib.bridge.util.CachedPathIteratorFactory; -import com.android.tools.layoutlib.annotations.LayoutlibDelegate; - import com.android.layoutlib.bridge.util.CachedPathIteratorFactory.CachedPathIterator; +import com.android.tools.layoutlib.annotations.LayoutlibDelegate; import java.awt.geom.PathIterator; @@ -79,7 +78,7 @@ public final class PathMeasure_Delegate { @LayoutlibDelegate /*package*/ static boolean native_getPosTan(long native_instance, float distance, float pos[], float tan[]) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "PathMeasure.getPostTan is not supported.", null, null, null); return false; } @@ -87,14 +86,14 @@ public final class PathMeasure_Delegate { @LayoutlibDelegate /*package*/ static boolean native_getMatrix(long native_instance, float distance, long native_matrix, int flags) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "PathMeasure.getMatrix is not supported.", null, null, null); return false; } @LayoutlibDelegate /*package*/ static boolean native_nextContour(long native_instance) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "PathMeasure.nextContour is not supported.", null, null, null); return false; } diff --git a/bridge/src/android/graphics/Path_Delegate.java b/bridge/src/android/graphics/Path_Delegate.java index df83d65b0f..88f2815855 100644 --- a/bridge/src/android/graphics/Path_Delegate.java +++ b/bridge/src/android/graphics/Path_Delegate.java @@ -16,7 +16,7 @@ package android.graphics; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; @@ -157,7 +157,7 @@ public final class Path_Delegate { @LayoutlibDelegate /*package*/ static boolean nIsConvex(long nPath) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Path.isConvex is not supported.", null, null, null); return true; } @@ -475,7 +475,7 @@ public final class Path_Delegate { @LayoutlibDelegate /*package*/ static boolean nOp(long nPath1, long nPath2, int op, long result) { - Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "Path.op() not supported", null, null); + Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED, "Path.op() not supported", null, null); return false; } @@ -889,7 +889,7 @@ public final class Path_Delegate { public void transform(Matrix_Delegate matrix, Path_Delegate dst) { if (matrix.hasPerspective()) { assert false; - Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_AFFINE, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MATRIX_AFFINE, "android.graphics.Path#transform() only " + "supports affine transformations.", null, null, null /*data*/); } diff --git a/bridge/src/android/graphics/RadialGradient_Delegate.java b/bridge/src/android/graphics/RadialGradient_Delegate.java index cd46b31097..4a18219f82 100644 --- a/bridge/src/android/graphics/RadialGradient_Delegate.java +++ b/bridge/src/android/graphics/RadialGradient_Delegate.java @@ -16,7 +16,7 @@ package android.graphics; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; @@ -116,7 +116,7 @@ public class RadialGradient_Delegate extends Gradient_Delegate { try { canvasMatrix = xform.createInverse(); } catch (java.awt.geom.NoninvertibleTransformException e) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MATRIX_INVERSE, "Unable to inverse matrix in RadialGradient", e, null, null /*data*/); canvasMatrix = new java.awt.geom.AffineTransform(); } @@ -125,7 +125,7 @@ public class RadialGradient_Delegate extends Gradient_Delegate { try { localMatrix = localMatrix.createInverse(); } catch (java.awt.geom.NoninvertibleTransformException e) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MATRIX_INVERSE, "Unable to inverse matrix in RadialGradient", e, null, null /*data*/); localMatrix = new java.awt.geom.AffineTransform(); } diff --git a/bridge/src/android/graphics/Region_Delegate.java b/bridge/src/android/graphics/Region_Delegate.java index f1f44b957b..254e825fee 100644 --- a/bridge/src/android/graphics/Region_Delegate.java +++ b/bridge/src/android/graphics/Region_Delegate.java @@ -16,7 +16,7 @@ package android.graphics; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; @@ -436,7 +436,7 @@ public class Region_Delegate { /*package*/ static long nativeCreateFromParcel(Parcel p) { // This is only called by Region.CREATOR (Parcelable.Creator<Region>), which is only // used during aidl call so really this should not be called. - Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED, "AIDL is not suppored, and therefore Regions cannot be created from parcels.", null, null /*data*/); return 0; @@ -447,7 +447,7 @@ public class Region_Delegate { Parcel p) { // This is only called when sending a region through aidl, so really this should not // be called. - Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED, "AIDL is not suppored, and therefore Regions cannot be written to parcels.", null, null /*data*/); return false; diff --git a/bridge/src/android/graphics/SweepGradient_Delegate.java b/bridge/src/android/graphics/SweepGradient_Delegate.java index e02144d5e5..01ef14073c 100644 --- a/bridge/src/android/graphics/SweepGradient_Delegate.java +++ b/bridge/src/android/graphics/SweepGradient_Delegate.java @@ -16,7 +16,7 @@ package android.graphics; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; @@ -111,7 +111,7 @@ public class SweepGradient_Delegate extends Gradient_Delegate { try { canvasMatrix = xform.createInverse(); } catch (java.awt.geom.NoninvertibleTransformException e) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MATRIX_INVERSE, "Unable to inverse matrix in SweepGradient", e, null, null /*data*/); canvasMatrix = new java.awt.geom.AffineTransform(); } @@ -120,7 +120,7 @@ public class SweepGradient_Delegate extends Gradient_Delegate { try { localMatrix = localMatrix.createInverse(); } catch (java.awt.geom.NoninvertibleTransformException e) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MATRIX_INVERSE, "Unable to inverse matrix in SweepGradient", e, null, null /*data*/); localMatrix = new java.awt.geom.AffineTransform(); } diff --git a/bridge/src/android/graphics/Typeface_Delegate.java b/bridge/src/android/graphics/Typeface_Delegate.java index fb044d95da..6c0ab20ec5 100644 --- a/bridge/src/android/graphics/Typeface_Delegate.java +++ b/bridge/src/android/graphics/Typeface_Delegate.java @@ -17,7 +17,7 @@ package android.graphics; import com.android.SdkConstants; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.ide.common.rendering.api.ResourceNamespace; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.android.BridgeContext; @@ -142,7 +142,7 @@ public final class Typeface_Delegate { long newInstance = nativeCreateFromTypeface(native_instance, 0); if (newInstance != 0) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "nativeCreateFromTypefaceWithVariation is not supported", null, null, null); } return newInstance; @@ -272,7 +272,7 @@ public final class Typeface_Delegate { blockParser.ensurePopped(); } } else { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, String.format("File %s does not exist (or is not a file)", path), null, null /*data*/); } diff --git a/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_Delegate.java b/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_Delegate.java index be7809147d..9c272fac48 100644 --- a/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_Delegate.java +++ b/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_Delegate.java @@ -16,7 +16,7 @@ package android.graphics.drawable; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; @@ -99,7 +99,7 @@ public class AnimatedVectorDrawable_Delegate { @LayoutlibDelegate /*package*/ static long nCreatePathDataPropertyHolder(long nativePtr, long startValuePtr, long endValuePtr) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, "AnimatedVectorDrawable path " + + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "AnimatedVectorDrawable path " + "animations are not supported.", null, null, null); return 0; } diff --git a/bridge/src/android/graphics/drawable/NinePatchDrawable_Delegate.java b/bridge/src/android/graphics/drawable/NinePatchDrawable_Delegate.java new file mode 100644 index 0000000000..bd73cfb6ec --- /dev/null +++ b/bridge/src/android/graphics/drawable/NinePatchDrawable_Delegate.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2020 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.graphics.drawable; + +import com.android.ide.common.rendering.api.ILayoutLog; +import com.android.layoutlib.bridge.Bridge; +import com.android.tools.layoutlib.annotations.LayoutlibDelegate; + +import android.graphics.PixelFormat; + +public class NinePatchDrawable_Delegate { + + @LayoutlibDelegate + static int getOpacity(NinePatchDrawable thisDrawable) { + // User-defined nine-patches can have a null underlying bitmap, if incorrectly constructed. + // Trying to preview such a nine-patch drawable will trigger a NullPointerException in the + // getOpacity, which then get logged by the Studio crash reporting system. + // Do not crash here, but let it instead crash during draw, which gets logged by layoutlib + // and is then handled better by Studio. + try { + return thisDrawable.getOpacity_Original(); + } catch (NullPointerException ignore) { + Bridge.getLog().warning(ILayoutLog.TAG_BROKEN, "The source for the nine-patch " + + "drawable has not been correctly defined.", null , null); + return PixelFormat.OPAQUE; + } + } +} diff --git a/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java b/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java index 8102894c87..828df6bfd5 100644 --- a/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java +++ b/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java @@ -1195,7 +1195,7 @@ public class VectorDrawable_Delegate { if (shaderDelegate != null) { // If there is a shader, apply the local transformation to make sure // the gradient is transformed to match the viewport - shaderDelegate.setLocalMatrix(mFinalPathMatrix.native_instance); + shaderDelegate.setLocalMatrix(mFinalPathMatrix.ni()); shaderDelegate.setAlpha(fullPath.mFillAlpha); } diff --git a/bridge/src/android/graphics/fonts/FontFamily_Builder_Delegate.java b/bridge/src/android/graphics/fonts/FontFamily_Builder_Delegate.java index 32f1157d64..018329dc2e 100644 --- a/bridge/src/android/graphics/fonts/FontFamily_Builder_Delegate.java +++ b/bridge/src/android/graphics/fonts/FontFamily_Builder_Delegate.java @@ -16,7 +16,7 @@ package android.graphics.fonts; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; @@ -189,7 +189,7 @@ public class FontFamily_Builder_Delegate { buffer.get(byteArray); return Font.createFont(Font.TRUETYPE_FONT, new ByteArrayInputStream(byteArray)); } catch (Exception e) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN, "Unable to load font", + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_BROKEN, "Unable to load font", e, null, null); } @@ -201,7 +201,7 @@ public class FontFamily_Builder_Delegate { File file = new File(path); return Font.createFont(Font.TRUETYPE_FONT, file); } catch (Exception e) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN, "Unable to load font", + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_BROKEN, "Unable to load font", e, null, null); } diff --git a/bridge/src/android/graphics/fonts/Font_Builder_Delegate.java b/bridge/src/android/graphics/fonts/Font_Builder_Delegate.java index f58f0279e4..0d3ce3f3ca 100644 --- a/bridge/src/android/graphics/fonts/Font_Builder_Delegate.java +++ b/bridge/src/android/graphics/fonts/Font_Builder_Delegate.java @@ -16,7 +16,7 @@ package android.graphics.fonts; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; @@ -83,7 +83,7 @@ public class Font_Builder_Delegate { @LayoutlibDelegate /*package*/ static void nAddAxis(long builderPtr, int tag, float value) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Font$Builder.nAddAxis is not supported.", null, null, null); } diff --git a/bridge/src/android/graphics/fonts/SystemFonts_Delegate.java b/bridge/src/android/graphics/fonts/SystemFonts_Delegate.java index df976d0891..3f3e065338 100644 --- a/bridge/src/android/graphics/fonts/SystemFonts_Delegate.java +++ b/bridge/src/android/graphics/fonts/SystemFonts_Delegate.java @@ -21,10 +21,11 @@ import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; import android.annotation.NonNull; +import android.annotation.Nullable; import android.text.FontConfig; -import android.util.ArrayMap; -import java.util.ArrayList; +import java.io.File; +import java.util.Map; import static android.graphics.FontFamily_Delegate.getFontLocation; @@ -43,13 +44,15 @@ import static android.graphics.FontFamily_Delegate.getFontLocation; public class SystemFonts_Delegate { @LayoutlibDelegate - /*package*/ static FontConfig.Alias[] buildSystemFallback(@NonNull String xmlPath, - @NonNull String fontDir, - @NonNull FontCustomizationParser.Result oemCustomization, - @NonNull ArrayMap<String, FontFamily[]> fallbackMap, - @NonNull ArrayList<Font> availableFonts) { + /*package*/ static FontConfig getSystemFontConfigInternal( + String fontsXml, + String systemFontDir, + String oemXml, + String productFontDir, + Map<String, File> updatableFontMap) { Bridge.sIsTypefaceInitialized = true; - return SystemFonts.buildSystemFallback_Original(getFontLocation() + "/standard/fonts.xml", - getFontLocation() + "/", oemCustomization, fallbackMap, availableFonts); + return SystemFonts.getSystemFontConfigInternal_Original( + getFontLocation() + "/standard/fonts.xml", getFontLocation() + "/", + null, null, updatableFontMap, 0, 0); } } diff --git a/bridge/src/android/net/ConnectivityManager.java b/bridge/src/android/net/ConnectivityManager.java new file mode 100644 index 0000000000..74ac8f57cd --- /dev/null +++ b/bridge/src/android/net/ConnectivityManager.java @@ -0,0 +1,895 @@ +/* + * Copyright (C) 2020 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.net; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.app.PendingIntent; +import android.content.Context; +import android.net.IpSecManager.UdpEncapsulationSocket; +import android.net.SocketKeepalive.Callback; +import android.os.Bundle; +import android.os.Handler; +import android.os.Messenger; +import android.os.ParcelFileDescriptor; +import android.os.PersistableBundle; + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.List; +import java.util.concurrent.Executor; + +import static android.os._Original_Build.VERSION_CODES.BASE; + +/** + * Stub ConnectivityManager for layoutlib + */ +public class ConnectivityManager { + @Deprecated + public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE"; + + public static final String ACTION_CAPTIVE_PORTAL_SIGN_IN = "android.net.conn.CAPTIVE_PORTAL"; + + @Deprecated + public static final String EXTRA_NETWORK_INFO = "networkInfo"; + @Deprecated + public static final String EXTRA_NETWORK_TYPE = "networkType"; + + @Deprecated + public static final String EXTRA_IS_FAILOVER = "isFailover"; + @Deprecated + public static final String EXTRA_OTHER_NETWORK_INFO = "otherNetwork"; + public static final String EXTRA_NO_CONNECTIVITY = "noConnectivity"; + public static final String EXTRA_REASON = "reason"; + @Deprecated + public static final String EXTRA_EXTRA_INFO = "extraInfo"; + public static final String EXTRA_INET_CONDITION = "inetCondition"; + public static final String EXTRA_CAPTIVE_PORTAL = "android.net.extra.CAPTIVE_PORTAL"; + + public static final String EXTRA_CAPTIVE_PORTAL_URL = "android.net.extra.CAPTIVE_PORTAL_URL"; + + public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC = + "android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC"; + + public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT = + "android.net.extra.CAPTIVE_PORTAL_USER_AGENT"; + + public static final String ACTION_DATA_ACTIVITY_CHANGE = + "android.net.conn.DATA_ACTIVITY_CHANGE"; + public static final String EXTRA_DEVICE_TYPE = "deviceType"; + public static final String EXTRA_IS_ACTIVE = "isActive"; + public static final String EXTRA_REALTIME_NS = "tsNanos"; + + @Deprecated + public static final String ACTION_BACKGROUND_DATA_SETTING_CHANGED = + "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED"; + + public static final String INET_CONDITION_ACTION = + "android.net.conn.INET_CONDITION_ACTION"; + + public static final String ACTION_TETHER_STATE_CHANGED = + TetheringManager.ACTION_TETHER_STATE_CHANGED; + + public static final String EXTRA_AVAILABLE_TETHER = TetheringManager.EXTRA_AVAILABLE_TETHER; + + public static final String EXTRA_ACTIVE_LOCAL_ONLY = TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY; + + public static final String EXTRA_ACTIVE_TETHER = TetheringManager.EXTRA_ACTIVE_TETHER; + + public static final String EXTRA_ERRORED_TETHER = TetheringManager.EXTRA_ERRORED_TETHER; + + public static final String ACTION_CAPTIVE_PORTAL_TEST_COMPLETED = + "android.net.conn.CAPTIVE_PORTAL_TEST_COMPLETED"; + public static final String EXTRA_IS_CAPTIVE_PORTAL = "captivePortal"; + + public static final String ACTION_PROMPT_UNVALIDATED = "android.net.conn.PROMPT_UNVALIDATED"; + + public static final String ACTION_PROMPT_LOST_VALIDATION = + "android.net.conn.PROMPT_LOST_VALIDATION"; + + public static final String ACTION_PROMPT_PARTIAL_CONNECTIVITY = + "android.net.conn.PROMPT_PARTIAL_CONNECTIVITY"; + + public static final int TETHERING_INVALID = TetheringManager.TETHERING_INVALID; + + public static final int TETHERING_WIFI = TetheringManager.TETHERING_WIFI; + + public static final int TETHERING_USB = TetheringManager.TETHERING_USB; + + public static final int TETHERING_BLUETOOTH = TetheringManager.TETHERING_BLUETOOTH; + + public static final int TETHERING_WIFI_P2P = TetheringManager.TETHERING_WIFI_P2P; + + public static final int TYPE_NONE = -1; + + @Deprecated + public static final int TYPE_MOBILE = 0; + + @Deprecated + public static final int TYPE_WIFI = 1; + + @Deprecated + public static final int TYPE_MOBILE_MMS = 2; + + @Deprecated + public static final int TYPE_MOBILE_SUPL = 3; + + @Deprecated + public static final int TYPE_MOBILE_DUN = 4; + + @Deprecated + public static final int TYPE_MOBILE_HIPRI = 5; + + @Deprecated + public static final int TYPE_WIMAX = 6; + + @Deprecated + public static final int TYPE_BLUETOOTH = 7; + + @Deprecated + public static final int TYPE_DUMMY = 8; + + @Deprecated + public static final int TYPE_ETHERNET = 9; + + @Deprecated + public static final int TYPE_MOBILE_FOTA = 10; + + @Deprecated + public static final int TYPE_MOBILE_IMS = 11; + + @Deprecated + public static final int TYPE_MOBILE_CBS = 12; + + @Deprecated + public static final int TYPE_WIFI_P2P = 13; + + @Deprecated + public static final int TYPE_MOBILE_IA = 14; + + @Deprecated + public static final int TYPE_MOBILE_EMERGENCY = 15; + + @Deprecated + public static final int TYPE_PROXY = 16; + + @Deprecated + public static final int TYPE_VPN = 17; + + @Deprecated + public static final int TYPE_TEST = 18; // TODO: Remove this once NetworkTypes are unused. + + @Deprecated + public @interface LegacyNetworkType {} + + public static final int MAX_RADIO_TYPE = TYPE_TEST; + + public static final int MAX_NETWORK_TYPE = TYPE_TEST; + + @Deprecated + public static final int DEFAULT_NETWORK_PREFERENCE = TYPE_WIFI; + + public static final int REQUEST_ID_UNSET = 0; + + public static final int NETID_UNSET = 0; + public static final String PRIVATE_DNS_MODE_OFF = "off"; + public static final String PRIVATE_DNS_MODE_OPPORTUNISTIC = "opportunistic"; + public static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = "hostname"; + public static final String PRIVATE_DNS_DEFAULT_MODE_FALLBACK = PRIVATE_DNS_MODE_OPPORTUNISTIC; + + private static ConnectivityManager sInstance; + + @Deprecated + public static boolean isNetworkTypeValid(int networkType) { + return false; + } + + @Deprecated + public static String getNetworkTypeName(int type) { + return null; + } + + @Deprecated + public static boolean isNetworkTypeMobile(int networkType) { + return false; + } + + @Deprecated + public static boolean isNetworkTypeWifi(int networkType) { + return false; + } + + @Deprecated + public void setNetworkPreference(int preference) { + } + + @Deprecated + public int getNetworkPreference() { + return TYPE_NONE; + } + + @Deprecated + @Nullable + public NetworkInfo getActiveNetworkInfo() { + return null; + } + + @Nullable + public Network getActiveNetwork() { + return null; + } + + @Nullable + public Network getActiveNetworkForUid(int uid) { + return null; + } + + public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) { + return null; + } + + public boolean isAlwaysOnVpnPackageSupportedForUser(int userId, @Nullable String vpnPackage) { + return false; + } + + public boolean setAlwaysOnVpnPackageForUser(int userId, @Nullable String vpnPackage, + boolean lockdownEnabled, @Nullable List<String> lockdownList) { + return false; + } + + public String getAlwaysOnVpnPackageForUser(int userId) { + return null; + } + + public boolean isVpnLockdownEnabled(int userId) { + return false; + } + + public List<String> getVpnLockdownWhitelist(int userId) { + return null; + } + + public NetworkInfo getActiveNetworkInfoForUid(int uid) { + return null; + } + + public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) { + return null; + } + + @Deprecated + @Nullable + public NetworkInfo getNetworkInfo(int networkType) { + return null; + } + + @Deprecated + @Nullable + public NetworkInfo getNetworkInfo(@Nullable Network network) { + return null; + } + + public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) { + return null; + } + + @Deprecated + @NonNull + public NetworkInfo[] getAllNetworkInfo() { + return new NetworkInfo[0]; + } + + @Deprecated + public Network getNetworkForType(int networkType) { + return null; + } + + @NonNull + public Network[] getAllNetworks() { + return new Network[0]; + } + + public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId) { + return null; + } + + public LinkProperties getActiveLinkProperties() { + return null; + } + + @Deprecated + public LinkProperties getLinkProperties(int networkType) { + return null; + } + + @Nullable + public LinkProperties getLinkProperties(@Nullable Network network) { + return null; + } + + @Nullable + public NetworkCapabilities getNetworkCapabilities(@Nullable Network network) { + return null; + } + + @Deprecated + public String getCaptivePortalServerUrl() { + return null; + } + + @Deprecated + public int startUsingNetworkFeature(int networkType, String feature) { + return -1; + } + + @Deprecated + public int stopUsingNetworkFeature(int networkType, String feature) { + return -1; + } + + public static NetworkCapabilities networkCapabilitiesForType(int type) { + return null; + } + + public static class PacketKeepaliveCallback { + public PacketKeepaliveCallback() { + } + public void onStarted() {} + public void onStopped() {} + public void onError(int error) {} + } + + public class PacketKeepalive { + public static final int SUCCESS = 0; + + public static final int NO_KEEPALIVE = -1; + + public static final int BINDER_DIED = -10; + + public static final int ERROR_INVALID_NETWORK = -20; + public static final int ERROR_INVALID_IP_ADDRESS = -21; + public static final int ERROR_INVALID_PORT = -22; + public static final int ERROR_INVALID_LENGTH = -23; + public static final int ERROR_INVALID_INTERVAL = -24; + + public static final int ERROR_HARDWARE_UNSUPPORTED = -30; + public static final int ERROR_HARDWARE_ERROR = -31; + + public static final int NATT_PORT = 4500; + + public static final int MIN_INTERVAL = 10; + + public void stop() {} + } + + public PacketKeepalive startNattKeepalive( + Network network, int intervalSeconds, PacketKeepaliveCallback callback, + InetAddress srcAddr, int srcPort, InetAddress dstAddr) { + return null; + } + + public @NonNull SocketKeepalive createSocketKeepalive(@NonNull Network network, + @NonNull UdpEncapsulationSocket socket, + @NonNull InetAddress source, + @NonNull InetAddress destination, + @NonNull Executor executor, + @NonNull Callback callback) { + throw new UnsupportedOperationException( + "createSocketKeepalive is not supported in layoutlib"); + } + + public @NonNull SocketKeepalive createNattKeepalive(@NonNull Network network, + @NonNull ParcelFileDescriptor pfd, + @NonNull InetAddress source, + @NonNull InetAddress destination, + @NonNull Executor executor, + @NonNull Callback callback) { + throw new UnsupportedOperationException( + "createSocketKeepalive is not supported in layoutlib"); + } + + public @NonNull SocketKeepalive createSocketKeepalive(@NonNull Network network, + @NonNull Socket socket, + @NonNull Executor executor, + @NonNull Callback callback) { + throw new UnsupportedOperationException( + "createSocketKeepalive is not supported in layoutlib"); + } + + @Deprecated + public boolean requestRouteToHost(int networkType, int hostAddress) { + return false; + } + + @Deprecated + public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) { + return false; + } + + @Deprecated + public boolean getBackgroundDataSetting() { + return false; + } + + @Deprecated + public void setBackgroundDataSetting(boolean allowBackgroundData) {} + + @Deprecated + public boolean getMobileDataEnabled() { + return false; + } + + public interface OnNetworkActiveListener { + void onNetworkActive(); + } + + public void addDefaultNetworkActiveListener(final OnNetworkActiveListener l) {} + + public void removeDefaultNetworkActiveListener(@NonNull OnNetworkActiveListener l) {} + + public boolean isDefaultNetworkActive() { + return false; + } + + public ConnectivityManager(Context context, IConnectivityManager service) { + sInstance = this; + } + + public static ConnectivityManager from(Context context) { + return new ConnectivityManager(context, null); + } + + public NetworkRequest getDefaultRequest() { + return null; + } + + public static final void enforceChangePermission(Context context) {} + + @Deprecated + static ConnectivityManager getInstanceOrNull() { + return sInstance; + } + + @Deprecated + private static ConnectivityManager getInstance() { + if (getInstanceOrNull() == null) { + throw new IllegalStateException("No ConnectivityManager yet constructed"); + } + return getInstanceOrNull(); + } + + @Deprecated + public String[] getTetherableIfaces() { + return null; + } + + @Deprecated + public String[] getTetheredIfaces() { + return null; + } + + @Deprecated + public String[] getTetheringErroredIfaces() { + return null; + } + + @Deprecated + public String[] getTetheredDhcpRanges() { + throw new UnsupportedOperationException("getTetheredDhcpRanges is not supported"); + } + + @Deprecated + public int tether(String iface) { + return 0; + } + + @Deprecated + public int untether(String iface) { + return 0; + } + + public boolean isTetheringSupported() { + return false; + } + + @Deprecated + public static abstract class OnStartTetheringCallback { + public void onTetheringStarted() {} + + public void onTetheringFailed() {} + } + + @Deprecated + public void startTethering(int type, boolean showProvisioningUi, + final OnStartTetheringCallback callback) {} + + @Deprecated + public void startTethering(int type, boolean showProvisioningUi, + final OnStartTetheringCallback callback, Handler handler) {} + + @Deprecated + public void stopTethering(int type) {} + + @Deprecated + public abstract static class OnTetheringEventCallback { + + public void onUpstreamChanged(@Nullable Network network) {} + } + + @Deprecated + public void registerTetheringEventCallback( + @NonNull Executor executor, + @NonNull final OnTetheringEventCallback callback) {} + + @Deprecated + public void unregisterTetheringEventCallback( + @NonNull final OnTetheringEventCallback callback) {} + + + @Deprecated + public String[] getTetherableUsbRegexs() { + return null; + } + + @Deprecated + public String[] getTetherableWifiRegexs() { + return null; + } + + @Deprecated + public String[] getTetherableBluetoothRegexs() { + return null; + } + + @Deprecated + public int setUsbTethering(boolean enable) { + return 0; + } + + @Deprecated + public static final int TETHER_ERROR_NO_ERROR = TetheringManager.TETHER_ERROR_NO_ERROR; + @Deprecated + public static final int TETHER_ERROR_UNKNOWN_IFACE = + TetheringManager.TETHER_ERROR_UNKNOWN_IFACE; + @Deprecated + public static final int TETHER_ERROR_SERVICE_UNAVAIL = + TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL; + @Deprecated + public static final int TETHER_ERROR_UNSUPPORTED = TetheringManager.TETHER_ERROR_UNSUPPORTED; + @Deprecated + public static final int TETHER_ERROR_UNAVAIL_IFACE = + TetheringManager.TETHER_ERROR_UNAVAIL_IFACE; + @Deprecated + public static final int TETHER_ERROR_MASTER_ERROR = + TetheringManager.TETHER_ERROR_INTERNAL_ERROR; + @Deprecated + public static final int TETHER_ERROR_TETHER_IFACE_ERROR = + TetheringManager.TETHER_ERROR_TETHER_IFACE_ERROR; + @Deprecated + public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = + TetheringManager.TETHER_ERROR_UNTETHER_IFACE_ERROR; + @Deprecated + public static final int TETHER_ERROR_ENABLE_NAT_ERROR = + TetheringManager.TETHER_ERROR_ENABLE_FORWARDING_ERROR; + @Deprecated + public static final int TETHER_ERROR_DISABLE_NAT_ERROR = + TetheringManager.TETHER_ERROR_DISABLE_FORWARDING_ERROR; + @Deprecated + public static final int TETHER_ERROR_IFACE_CFG_ERROR = + TetheringManager.TETHER_ERROR_IFACE_CFG_ERROR; + @Deprecated + public static final int TETHER_ERROR_PROVISION_FAILED = + TetheringManager.TETHER_ERROR_PROVISIONING_FAILED; + @Deprecated + public static final int TETHER_ERROR_DHCPSERVER_ERROR = + TetheringManager.TETHER_ERROR_DHCPSERVER_ERROR; + @Deprecated + public static final int TETHER_ERROR_ENTITLEMENT_UNKONWN = + TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN; + + @Deprecated + public int getLastTetherError(String iface) { + return 0; + } + + public @interface EntitlementResultCode { + } + + @Deprecated + public interface OnTetheringEntitlementResultListener { + void onTetheringEntitlementResult(@EntitlementResultCode int resultCode); + } + + @Deprecated + public void getLatestTetheringEntitlementResult(int type, boolean showEntitlementUi, + @NonNull Executor executor, + @NonNull final OnTetheringEntitlementResultListener listener) {} + + public void reportInetCondition(int networkType, int percentage) {} + + @Deprecated + public void reportBadNetwork(@Nullable Network network) {} + + public void reportNetworkConnectivity(@Nullable Network network, boolean hasConnectivity) {} + + public void setGlobalProxy(ProxyInfo p) {} + + public ProxyInfo getGlobalProxy() { + return null; + } + + public ProxyInfo getProxyForNetwork(Network network) { + return null; + } + + @Nullable + public ProxyInfo getDefaultProxy() { + return null; + } + + @Deprecated + public boolean isNetworkSupported(int networkType) { + return false; + } + + public boolean isActiveNetworkMetered() { + return false; + } + + public boolean updateLockdownVpn() { + return false; + } + + public int checkMobileProvisioning(int suggestedTimeOutMs) { + return 0; + } + + public String getMobileProvisioningUrl() { + return null; + } + + @Deprecated + public void setProvisioningNotificationVisible(boolean visible, int networkType, + String action) {} + + public void setAirplaneMode(boolean enable) {} + + public int registerNetworkFactory(Messenger messenger, String name) { + return 0; + } + + public void unregisterNetworkFactory(Messenger messenger) {} + + public int registerNetworkProvider(@NonNull NetworkProvider provider) { + return 0; + } + + public void unregisterNetworkProvider(@NonNull NetworkProvider provider) {} + + public void declareNetworkRequestUnfulfillable(@NonNull NetworkRequest request) {} + + public Network registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp, + NetworkCapabilities nc, int score, NetworkAgentConfig config) { + return null; + } + + public Network registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp, + NetworkCapabilities nc, int score, NetworkAgentConfig config, int providerId) { + return null; + } + + public static class NetworkCallback { + public void onPreCheck(@NonNull Network network) {} + + public void onAvailable(@NonNull Network network, + @NonNull NetworkCapabilities networkCapabilities, + @NonNull LinkProperties linkProperties, boolean blocked) {} + + public void onAvailable(@NonNull Network network) {} + + public void onLosing(@NonNull Network network, int maxMsToLive) {} + + public void onLost(@NonNull Network network) {} + + public void onUnavailable() {} + + public void onCapabilitiesChanged(@NonNull Network network, + @NonNull NetworkCapabilities networkCapabilities) {} + + public void onLinkPropertiesChanged(@NonNull Network network, + @NonNull LinkProperties linkProperties) {} + + public void onNetworkSuspended(@NonNull Network network) {} + + public void onNetworkResumed(@NonNull Network network) {} + + public void onBlockedStatusChanged(@NonNull Network network, boolean blocked) {} + } + + public interface Errors { + int TOO_MANY_REQUESTS = 1; + } + + public static class TooManyRequestsException extends RuntimeException {} + + public static final int CALLBACK_PRECHECK = BASE + 1; + public static final int CALLBACK_AVAILABLE = BASE + 2; + public static final int CALLBACK_LOSING = BASE + 3; + public static final int CALLBACK_LOST = BASE + 4; + public static final int CALLBACK_UNAVAIL = BASE + 5; + public static final int CALLBACK_CAP_CHANGED = BASE + 6; + public static final int CALLBACK_IP_CHANGED = BASE + 7; + private static final int EXPIRE_LEGACY_REQUEST = BASE + 8; + public static final int CALLBACK_SUSPENDED = BASE + 9; + public static final int CALLBACK_RESUMED = BASE + 10; + public static final int CALLBACK_BLK_CHANGED = BASE + 11; + + public static String getCallbackName(int whichCallback) { + switch (whichCallback) { + case CALLBACK_PRECHECK: return "CALLBACK_PRECHECK"; + case CALLBACK_AVAILABLE: return "CALLBACK_AVAILABLE"; + case CALLBACK_LOSING: return "CALLBACK_LOSING"; + case CALLBACK_LOST: return "CALLBACK_LOST"; + case CALLBACK_UNAVAIL: return "CALLBACK_UNAVAIL"; + case CALLBACK_CAP_CHANGED: return "CALLBACK_CAP_CHANGED"; + case CALLBACK_IP_CHANGED: return "CALLBACK_IP_CHANGED"; + case EXPIRE_LEGACY_REQUEST: return "EXPIRE_LEGACY_REQUEST"; + case CALLBACK_SUSPENDED: return "CALLBACK_SUSPENDED"; + case CALLBACK_RESUMED: return "CALLBACK_RESUMED"; + case CALLBACK_BLK_CHANGED: return "CALLBACK_BLK_CHANGED"; + default: + return Integer.toString(whichCallback); + } + } + + public void requestNetwork(@NonNull NetworkRequest request, + int timeoutMs, int legacyType, @NonNull Handler handler, + @NonNull NetworkCallback networkCallback) {} + + public void requestNetwork(@NonNull NetworkRequest request, + @NonNull NetworkCallback networkCallback) {} + + public void requestNetwork(@NonNull NetworkRequest request, + @NonNull NetworkCallback networkCallback, @NonNull Handler handler) {} + + public void requestNetwork(@NonNull NetworkRequest request, + @NonNull NetworkCallback networkCallback, int timeoutMs) {} + + public void requestNetwork(@NonNull NetworkRequest request, + @NonNull NetworkCallback networkCallback, @NonNull Handler handler, int timeoutMs) {} + + public static final String EXTRA_NETWORK = "android.net.extra.NETWORK"; + + public static final String EXTRA_NETWORK_REQUEST = "android.net.extra.NETWORK_REQUEST"; + + + public void requestNetwork(@NonNull NetworkRequest request, + @NonNull PendingIntent operation) {} + + public void releaseNetworkRequest(@NonNull PendingIntent operation) {} + + public void registerNetworkCallback(@NonNull NetworkRequest request, + @NonNull NetworkCallback networkCallback) {} + + public void registerNetworkCallback(@NonNull NetworkRequest request, + @NonNull NetworkCallback networkCallback, @NonNull Handler handler) {} + + public void registerNetworkCallback(@NonNull NetworkRequest request, + @NonNull PendingIntent operation) {} + + public void registerDefaultNetworkCallback(@NonNull NetworkCallback networkCallback) {} + + public void registerDefaultNetworkCallback(@NonNull NetworkCallback networkCallback, + @NonNull Handler handler) {} + + public boolean requestBandwidthUpdate(@NonNull Network network) { + return false; + } + + public void unregisterNetworkCallback(@NonNull NetworkCallback networkCallback) {} + + public void unregisterNetworkCallback(@NonNull PendingIntent operation) {} + + public void setAcceptUnvalidated(Network network, boolean accept, boolean always) {} + + public void setAcceptPartialConnectivity(Network network, boolean accept, boolean always) {} + + public void setAvoidUnvalidated(Network network) {} + + public void startCaptivePortalApp(Network network) {} + + public void startCaptivePortalApp(@NonNull Network network, @NonNull Bundle appExtras) {} + + public boolean shouldAvoidBadWifi() { + return false; + } + + public static final int MULTIPATH_PREFERENCE_HANDOVER = 1 << 0; + + public static final int MULTIPATH_PREFERENCE_RELIABILITY = 1 << 1; + + public static final int MULTIPATH_PREFERENCE_PERFORMANCE = 1 << 2; + + public static final int MULTIPATH_PREFERENCE_UNMETERED = + MULTIPATH_PREFERENCE_HANDOVER | + MULTIPATH_PREFERENCE_RELIABILITY | + MULTIPATH_PREFERENCE_PERFORMANCE; + + public @interface MultipathPreference { + } + + public @MultipathPreference int getMultipathPreference(@Nullable Network network) { + return 0; + } + + public void factoryReset() {} + + public boolean bindProcessToNetwork(@Nullable Network network) { + return false; + } + + public static boolean setProcessDefaultNetwork(@Nullable Network network) { + return false; + } + + @Nullable + public Network getBoundNetworkForProcess() { + return null; + } + + @Deprecated + @Nullable + public static Network getProcessDefaultNetwork() { + return null; + } + + @Deprecated + public static boolean setProcessDefaultNetworkForHostResolution(Network network) { + return false; + } + + public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1; + + public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2; + + public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3; + + public static final String ACTION_RESTRICT_BACKGROUND_CHANGED = + "android.net.conn.RESTRICT_BACKGROUND_CHANGED"; + + public @interface RestrictBackgroundStatus { + } + + public @RestrictBackgroundStatus int getRestrictBackgroundStatus() { + return 0; + } + + @Nullable + public byte[] getNetworkWatchlistConfigHash() { + return null; + } + + public int getConnectionOwnerUid( + int protocol, @NonNull InetSocketAddress local, @NonNull InetSocketAddress remote) { + return 0; + } + + public void simulateDataStall(int detectionMethod, long timestampMillis, + @NonNull Network network, @NonNull PersistableBundle extras) {} +} + diff --git a/bridge/src/android/os/SystemClock_Delegate.java b/bridge/src/android/os/SystemClock_Delegate.java index 9677aaf5d0..b6a85f893a 100644 --- a/bridge/src/android/os/SystemClock_Delegate.java +++ b/bridge/src/android/os/SystemClock_Delegate.java @@ -54,6 +54,16 @@ public class SystemClock_Delegate { } /** + * Returns nanoseconds since boot, not counting time spent in deep sleep. + * + * @return nanoseconds of non-sleep uptime since boot. + */ + @LayoutlibDelegate + /*package*/ static long uptimeNanos() { + return System_Delegate.nanoTime() - System_Delegate.bootTime(); + } + + /** * Returns nanoseconds since boot, including time spent in sleep. * * @return elapsed nanoseconds since boot. diff --git a/bridge/src/android/os/SystemProperties_Delegate.java b/bridge/src/android/os/SystemProperties_Delegate.java index c6a7657ff4..b5c829427e 100644 --- a/bridge/src/android/os/SystemProperties_Delegate.java +++ b/bridge/src/android/os/SystemProperties_Delegate.java @@ -16,7 +16,7 @@ package android.os; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; @@ -106,35 +106,35 @@ public class SystemProperties_Delegate { @LayoutlibDelegate /*package*/ static String native_get(long handle) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Layoutlib does not support SystemProperties Handle", null, null, null); return null; } @LayoutlibDelegate /*package*/ static int native_get_int(long handle, int def) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Layoutlib does not support SystemProperties Handle", null, null, null); return def; } @LayoutlibDelegate /*package*/ static long native_get_long(long handle, long def) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Layoutlib does not support SystemProperties Handle", null, null, null); return def; } @LayoutlibDelegate /*package*/ static boolean native_get_boolean(long handle, boolean def) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Layoutlib does not support SystemProperties Handle", null, null, null); return def; } @LayoutlibDelegate /*package*/ static long native_find(String name) { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Layoutlib does not support SystemProperties Handle", null, null, null); return 0; } diff --git a/bridge/src/android/util/PathParser_Delegate.java b/bridge/src/android/util/PathParser_Delegate.java index 96c093cc6b..46e94a7f46 100644 --- a/bridge/src/android/util/PathParser_Delegate.java +++ b/bridge/src/android/util/PathParser_Delegate.java @@ -16,7 +16,7 @@ package android.util; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; @@ -121,7 +121,7 @@ public class PathParser_Delegate { } int length = from.mPathDataNodes.length; if (length != to.mPathDataNodes.length) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "Cannot interpolate path data with different lengths (from " + length + " to " + to.mPathDataNodes.length + ").", null, null); return false; diff --git a/bridge/src/android/view/BridgeInflater.java b/bridge/src/android/view/BridgeInflater.java index f2cbfa00c8..dfb46f2bd4 100644 --- a/bridge/src/android/view/BridgeInflater.java +++ b/bridge/src/android/view/BridgeInflater.java @@ -17,7 +17,7 @@ package android.view; import com.android.SdkConstants; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.ide.common.rendering.api.LayoutlibCallback; import com.android.ide.common.rendering.api.MergeCookie; import com.android.ide.common.rendering.api.ResourceNamespace; @@ -264,7 +264,7 @@ public final class BridgeInflater extends LayoutInflater { true /*readAppTheme*/, true /*wrapContext*/); } catch (IllegalAccessException | InvocationTargetException e) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, e.getMessage(), e, + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, e.getMessage(), e, null, null); } return null; @@ -295,7 +295,7 @@ public final class BridgeInflater extends LayoutInflater { name = attrs.getAttributeValue(null, "class"); if (name == null) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to inflate view tag without " + + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "Unable to inflate view tag without " + "class attribute", null, null); // We weren't able to resolve the view so we just pass a mock View to be able to // continue rendering. @@ -323,7 +323,7 @@ public final class BridgeInflater extends LayoutInflater { // There is some unknown inflation exception in inflating a View that was found. view = new MockView(context, attrs); ((MockView) view).setText(name); - Bridge.getLog().error(LayoutLog.TAG_BROKEN, e.getMessage(), e, null, null); + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, e.getMessage(), e, null, null); } else { final Object lastContext = mConstructorArgs[0]; mConstructorArgs[0] = context; @@ -382,7 +382,7 @@ public final class BridgeInflater extends LayoutInflater { return inflate(bridgeParser, root); } catch (Exception e) { - Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ, + Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_READ, "Failed to parse file " + path, e, null, null); return null; diff --git a/bridge/src/android/view/Choreographer_Delegate.java b/bridge/src/android/view/Choreographer_Delegate.java index 1dc777885b..3a8839f2ab 100644 --- a/bridge/src/android/view/Choreographer_Delegate.java +++ b/bridge/src/android/view/Choreographer_Delegate.java @@ -33,6 +33,8 @@ import java.util.concurrent.atomic.AtomicReference; public class Choreographer_Delegate { private static final AtomicReference<Choreographer> mInstance = new AtomicReference<Choreographer>(); + private static final int MS_16 = 16000000; + @LayoutlibDelegate public static Choreographer getInstance() { if (mInstance.get() == null) { @@ -60,15 +62,15 @@ public class Choreographer_Delegate { try { thisChoreographer.mLastFrameTimeNanos = frameTimeNanos - thisChoreographer.getFrameIntervalNanos(); thisChoreographer.mFrameInfo.markInputHandlingStart(); - thisChoreographer.doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos); + thisChoreographer.doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos, MS_16); thisChoreographer.mFrameInfo.markAnimationsStart(); - thisChoreographer.doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos); + thisChoreographer.doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos, MS_16); thisChoreographer.mFrameInfo.markPerformTraversalsStart(); - thisChoreographer.doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos); + thisChoreographer.doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos, MS_16); - thisChoreographer.doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos); + thisChoreographer.doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos, MS_16); } finally { AnimationUtils.unlockAnimationClock(); } diff --git a/bridge/src/android/view/LayoutInflater_Delegate.java b/bridge/src/android/view/LayoutInflater_Delegate.java index 66a94fa48f..cb446e7610 100644 --- a/bridge/src/android/view/LayoutInflater_Delegate.java +++ b/bridge/src/android/view/LayoutInflater_Delegate.java @@ -16,7 +16,7 @@ package android.view; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; @@ -106,7 +106,7 @@ public class LayoutInflater_Delegate { if (layout == 0) { final String value = attrs.getAttributeValue(null, ATTR_LAYOUT); if (value == null || value.length() <= 0) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, "You must specify a layout in the" + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "You must specify a layout in the" + " include tag: <include layout=\"@layout/layoutID\" />", null, null); LayoutInflater.consumeChildElements(parser); return; @@ -129,10 +129,10 @@ public class LayoutInflater_Delegate { if (layout == 0) { final String value = attrs.getAttributeValue(null, ATTR_LAYOUT); if (value == null) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, "You must specify a layout in the" + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "You must specify a layout in the" + " include tag: <include layout=\"@layout/layoutID\" />", null, null); } else { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, "You must specify a valid layout " + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "You must specify a valid layout " + "reference. The layout ID " + value + " is not valid.", null, null); } } else { @@ -148,7 +148,7 @@ public class LayoutInflater_Delegate { } if (type != XmlPullParser.START_TAG) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, childParser.getPositionDescription() + ": No start tag found!", null, null); LayoutInflater.consumeChildElements(parser); @@ -226,7 +226,7 @@ public class LayoutInflater_Delegate { } } } else { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "<include /> can only be used inside of a ViewGroup", null, null); } diff --git a/bridge/src/android/view/MenuInflater_Delegate.java b/bridge/src/android/view/MenuInflater_Delegate.java index 83586a13fd..818d7413a9 100644 --- a/bridge/src/android/view/MenuInflater_Delegate.java +++ b/bridge/src/android/view/MenuInflater_Delegate.java @@ -16,8 +16,7 @@ package android.view; -import android.content.Context; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.ide.common.rendering.api.ViewInfo; import com.android.internal.view.menu.BridgeMenuItemImpl; import com.android.internal.view.menu.MenuView; @@ -25,6 +24,7 @@ import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.android.BridgeContext; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; +import android.content.Context; import android.util.AttributeSet; /** @@ -64,7 +64,7 @@ public class MenuInflater_Delegate { // This is most likely a bug in the LayoutLib code. // We suppress this error for AppCompat menus since we do not support them in the menu // editor yet. - Bridge.getLog().warning(LayoutLog.TAG_BROKEN, + Bridge.getLog().warning(ILayoutLog.TAG_BROKEN, "Action Bar Menu rendering may be incorrect.", null, null); } diff --git a/bridge/src/android/view/View_Delegate.java b/bridge/src/android/view/View_Delegate.java index 9aae4ae6a4..6d82e8a13a 100644 --- a/bridge/src/android/view/View_Delegate.java +++ b/bridge/src/android/view/View_Delegate.java @@ -16,7 +16,7 @@ package android.view; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.android.BridgeContext; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; @@ -55,7 +55,7 @@ public class View_Delegate { // all the layout. thisView.draw_Original(canvas); } catch (Throwable t) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, "View draw failed", t, null, null); + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "View draw failed", t, null, null); } } @@ -67,7 +67,7 @@ public class View_Delegate { // all the layout. return thisView.draw_Original(canvas, parent, drawingTime); } catch (Throwable t) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, "View draw failed", t, null, null); + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "View draw failed", t, null, null); } return false; } @@ -79,7 +79,7 @@ public class View_Delegate { // all the layout. thisView.measure_Original(widthMeasureSpec, heightMeasureSpec); } catch (Throwable t) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, "View measure failed", t, null, null); + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "View measure failed", t, null, null); } } @@ -90,7 +90,7 @@ public class View_Delegate { // all the layout. thisView.layout_Original(l, t, r, b); } catch (Throwable th) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, "View layout failed", th, null, null); + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "View layout failed", th, null, null); } } diff --git a/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java b/bridge/src/android/view/WindowManagerImpl.java index 3cd95befa9..36b7165c1e 100644 --- a/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java +++ b/bridge/src/android/view/WindowManagerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 The Android Open Source Project + * Copyright (C) 2020 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. @@ -11,30 +11,27 @@ * 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. + * limitations under the License */ -package com.android.layoutlib.bridge.android.view; +package android.view; + +import static android.view.View.SYSTEM_UI_FLAG_VISIBLE; +import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; +import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import android.app.ResourcesManager; import android.content.Context; -import android.graphics.Insets; +import android.content.res.Configuration; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Region; +import android.os.IBinder; import android.os.RemoteException; import android.util.DisplayMetrics; -import android.util.Size; -import android.view.Display; import android.view.Display.Mode; -import android.view.DisplayAdjustments; -import android.view.DisplayCutout; -import android.view.DisplayInfo; -import android.view.InsetsState; -import android.view.View; -import android.view.WindowInsets; -import android.view.WindowManager; -import android.view.WindowManagerGlobal; -import android.view.WindowMetrics; + +import com.android.ide.common.rendering.api.ILayoutLog; +import com.android.layoutlib.bridge.Bridge; public class WindowManagerImpl implements WindowManager { @@ -57,6 +54,30 @@ public class WindowManagerImpl implements WindowManager { DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS); } + public WindowManagerImpl createLocalWindowManager(Window parentWindow) { + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, + "The preview does not support multiple windows.", + null, null, null); + return this; + } + + public WindowManagerImpl createPresentationWindowManager(Context displayContext) { + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, + "The preview does not support multiple windows.", + null, null, null); + return this; + } + + /** + * Sets the window token to assign when none is specified by the client or + * available from the parent window. + * + * @param token The default token to assign. + */ + public void setDefaultToken(IBinder token) { + + } + @Override public Display getDefaultDisplay() { return mDisplay; @@ -105,7 +126,7 @@ public class WindowManagerImpl implements WindowManager { } @Override - public void setShouldShowIme(int displayId, boolean shouldShow) { + public void setDisplayImePolicy(int displayId, int imePolicy) { // pass } @@ -135,18 +156,17 @@ public class WindowManagerImpl implements WindowManager { private WindowInsets computeWindowInsets() { try { - final Rect systemWindowInsets = new Rect(); - final Rect stableInsets = new Rect(); - final DisplayCutout.ParcelableWrapper displayCutout = - new DisplayCutout.ParcelableWrapper(); final InsetsState insetsState = new InsetsState(); - WindowManagerGlobal.getWindowManagerService().getWindowInsets( - new WindowManager.LayoutParams(), mContext.getDisplayId(), systemWindowInsets, - stableInsets, displayCutout, insetsState); - return new WindowInsets.Builder() - .setSystemWindowInsets(Insets.of(systemWindowInsets)) - .setStableInsets(Insets.of(stableInsets)) - .setDisplayCutout(displayCutout.get()).build(); + final boolean alwaysConsumeSystemBars = + WindowManagerGlobal.getWindowManagerService().getWindowInsets( + new WindowManager.LayoutParams(), mContext.getDisplayId(), insetsState); + final Configuration config = mContext.getResources().getConfiguration(); + final boolean isScreenRound = config.isScreenRound(); + final int windowingMode = config.windowConfiguration.getWindowingMode(); + return insetsState.calculateInsets(getCurrentBounds(mContext), + null /* ignoringVisibilityState*/, isScreenRound, alwaysConsumeSystemBars, + SOFT_INPUT_ADJUST_NOTHING, 0, SYSTEM_UI_FLAG_VISIBLE, TYPE_APPLICATION, + windowingMode, null /* typeSideMap */); } catch (RemoteException ignore) { } return null; diff --git a/bridge/src/android/view/accessibility/AccessibilityManager.java b/bridge/src/android/view/accessibility/AccessibilityManager.java index d5e60a96aa..4454f29e07 100644 --- a/bridge/src/android/view/accessibility/AccessibilityManager.java +++ b/bridge/src/android/view/accessibility/AccessibilityManager.java @@ -156,6 +156,9 @@ public final class AccessibilityManager { public void setRelevantEventTypes(int eventTypes) { } + + public void setFocusAppearance(int strokeWidth, int color) { + } }; /** diff --git a/bridge/src/android/view/shadow/AmbientShadowTriangulator.java b/bridge/src/android/view/shadow/AmbientShadowTriangulator.java index 630ec3017a..d768fa3466 100644 --- a/bridge/src/android/view/shadow/AmbientShadowTriangulator.java +++ b/bridge/src/android/view/shadow/AmbientShadowTriangulator.java @@ -16,7 +16,7 @@ package android.view.shadow; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; /** @@ -43,11 +43,11 @@ class AmbientShadowTriangulator { mCalculator.generateVertex(); mValid = true; } catch (IndexOutOfBoundsException|ArithmeticException mathError) { - Bridge.getLog().warning(LayoutLog.TAG_INFO, "Arithmetic error while drawing " + + Bridge.getLog().warning(ILayoutLog.TAG_INFO, "Arithmetic error while drawing " + "ambient shadow", null, mathError); } catch (Exception ex) { - Bridge.getLog().warning(LayoutLog.TAG_INFO, "Error while drawing shadow", + Bridge.getLog().warning(ILayoutLog.TAG_INFO, "Error while drawing shadow", null, ex); } } diff --git a/bridge/src/android/view/shadow/SpotShadowTriangulator.java b/bridge/src/android/view/shadow/SpotShadowTriangulator.java index 854a4d5919..d6661537c7 100644 --- a/bridge/src/android/view/shadow/SpotShadowTriangulator.java +++ b/bridge/src/android/view/shadow/SpotShadowTriangulator.java @@ -16,12 +16,8 @@ package android.view.shadow; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; -import com.android.tools.layoutlib.annotations.VisibleForTesting; - -import android.graphics.Bitmap; -import android.view.math.Math3DHelper; /** * Generate spot shadow bitmap. @@ -58,11 +54,11 @@ class SpotShadowTriangulator { mShadowConfig.getShadowStrength(), mStrips); } catch (IndexOutOfBoundsException|ArithmeticException mathError) { - Bridge.getLog().warning(LayoutLog.TAG_INFO, "Arithmetic error while drawing " + + Bridge.getLog().warning(ILayoutLog.TAG_INFO, "Arithmetic error while drawing " + "spot shadow", null, mathError); } catch (Exception ex) { - Bridge.getLog().warning(LayoutLog.TAG_INFO, "Error while drawing shadow", + Bridge.getLog().warning(ILayoutLog.TAG_INFO, "Error while drawing shadow", null, ex); } } diff --git a/bridge/src/com/android/layoutlib/bridge/Bridge.java b/bridge/src/com/android/layoutlib/bridge/Bridge.java index 88298d69e3..aa76e750d9 100644 --- a/bridge/src/com/android/layoutlib/bridge/Bridge.java +++ b/bridge/src/com/android/layoutlib/bridge/Bridge.java @@ -17,7 +17,7 @@ package com.android.layoutlib.bridge; import com.android.ide.common.rendering.api.DrawableParams; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.ide.common.rendering.api.RenderSession; import com.android.ide.common.rendering.api.ResourceNamespace; import com.android.ide.common.rendering.api.ResourceReference; @@ -33,7 +33,7 @@ import com.android.resources.ResourceType; import com.android.tools.layoutlib.annotations.Nullable; import com.android.tools.layoutlib.create.MethodAdapter; import com.android.tools.layoutlib.create.OverrideMethod; -import com.android.util.Pair; +import com.android.utils.Pair; import android.animation.PropertyValuesHolder; import android.animation.PropertyValuesHolder_Delegate; @@ -56,7 +56,6 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.EnumMap; -import java.util.EnumSet; import java.util.HashMap; import java.util.Map; import java.util.WeakHashMap; @@ -94,7 +93,6 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { /** * Maps from id to resource type/name. This is for com.android.internal.R */ - @SuppressWarnings("deprecation") private final static Map<Integer, Pair<ResourceType, String>> sRMap = new HashMap<>(); /** @@ -124,7 +122,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { /** * A default log than prints to stdout/stderr. */ - private final static LayoutLog sDefaultLog = new LayoutLog() { + private final static ILayoutLog sDefaultLog = new ILayoutLog() { @Override public void error(String tag, String message, Object viewCookie, Object data) { System.err.println(message); @@ -145,7 +143,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { /** * Current log. */ - private static LayoutLog sCurrentLog = sDefaultLog; + private static ILayoutLog sCurrentLog = sDefaultLog; public static boolean sIsTypefaceInitialized; @@ -155,7 +153,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { String nativeLibPath, String icuDataPath, Map<String, Map<String, Integer>> enumValueMap, - LayoutLog log) { + ILayoutLog log) { sPlatformProperties = platformProperties; sEnumValueMap = enumValueMap; @@ -208,7 +206,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { continue; } String resTypeName = inner.getSimpleName(); - ResourceType resType = ResourceType.getEnum(resTypeName); + ResourceType resType = ResourceType.fromClassName(resTypeName); if (resType != null) { Map<String, Integer> fullMap = null; switch (resType) { @@ -236,7 +234,6 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { Class<?> type = f.getType(); if (!type.isArray()) { Integer value = (Integer) f.get(null); - //noinspection deprecation sRMap.put(value, Pair.of(resType, f.getName())); fullMap.put(f.getName(), value); } @@ -245,7 +242,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { } } catch (Exception throwable) { if (log != null) { - log.error(LayoutLog.TAG_BROKEN, + log.error(ILayoutLog.TAG_BROKEN, "Failed to load com.android.internal.R from the layout library jar", throwable, null, null); } @@ -327,11 +324,9 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { if (arrayValue != null) { String attrName = name.substring(arrayName.length() + 1); int attrValue = arrayValue[index]; - //noinspection deprecation sRMap.put(attrValue, Pair.of(ResourceType.ATTR, attrName)); revRAttrMap.put(attrName, attrValue); } - //noinspection deprecation sRMap.put(index, Pair.of(ResourceType.STYLEABLE, name)); revRStyleableMap.put(name, index); } @@ -512,11 +507,11 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { Looper_Accessor.cleanupThread(); } - public static LayoutLog getLog() { + public static ILayoutLog getLog() { return sCurrentLog; } - public static void setLog(LayoutLog log) { + public static void setLog(ILayoutLog log) { // check only the thread currently owning the lock can do this. if (!sLock.isHeldByCurrentThread()) { throw new IllegalStateException("scene must be acquired first. see #acquire(long)"); diff --git a/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java b/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java index 442a77bdcd..558470845f 100644 --- a/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java +++ b/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java @@ -74,11 +74,6 @@ public class BridgeRenderSession extends RenderSession { } @Override - public Map<Object, String> getDefaultStyles() { - return mSession != null ? mSession.getDefaultStyles() : Collections.emptyMap(); - } - - @Override public Map<Object, ResourceReference> getDefaultNamespacedStyles() { return mSession != null ? mSession.getDefaultNamespacedStyles() : Collections.emptyMap(); } diff --git a/bridge/src/com/android/layoutlib/bridge/MockView.java b/bridge/src/com/android/layoutlib/bridge/MockView.java index 9856cf64c6..a1d1bbc456 100644 --- a/bridge/src/com/android/layoutlib/bridge/MockView.java +++ b/bridge/src/com/android/layoutlib/bridge/MockView.java @@ -111,7 +111,6 @@ public class MockView extends FrameLayout { mView.setText(text); } - @SuppressWarnings("WeakerAccess") // This method is used from Studio public void setGravity(int gravity) { mView.setGravity(gravity); } diff --git a/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java b/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java index ce613e0170..8934b122a3 100644 --- a/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java +++ b/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java @@ -16,6 +16,7 @@ package com.android.layoutlib.bridge.android; +import android.content.AttributionSource; import android.content.ContentProviderOperation; import android.content.ContentProviderResult; import android.content.ContentResolver; @@ -44,7 +45,7 @@ import java.util.ArrayList; */ public final class BridgeContentProvider implements IContentProvider { @Override - public ContentProviderResult[] applyBatch(String callingPackage, String callingFeatureId, + public ContentProviderResult[] applyBatch(AttributionSource attributionSource, String authority, ArrayList<ContentProviderOperation> arg0) throws RemoteException, OperationApplicationException { // TODO Auto-generated method stub @@ -52,21 +53,21 @@ public final class BridgeContentProvider implements IContentProvider { } @Override - public int bulkInsert(String callingPackage, String callingFeatureId, Uri arg0, + public int bulkInsert(AttributionSource attributionSource, Uri arg0, ContentValues[] arg1) throws RemoteException { // TODO Auto-generated method stub return 0; } @Override - public Bundle call(String callingPackage, String callingFeatureId, String authority, + public Bundle call(AttributionSource attributionSource, String authority, String arg0, String arg1, Bundle arg2) throws RemoteException { // TODO Auto-generated method stub return null; } @Override - public int delete(String callingPackage, String callingFeatureId, Uri arg0, Bundle arg1) + public int delete(AttributionSource attributionSource, Uri arg0, Bundle arg1) throws RemoteException { // TODO Auto-generated method stub return 0; @@ -93,14 +94,14 @@ public final class BridgeContentProvider implements IContentProvider { } @Override - public Uri insert(String callingPackage, String callingFeatureId, Uri arg0, ContentValues arg1, + public Uri insert(AttributionSource attributionSource, Uri arg0, ContentValues arg1, Bundle arg2) throws RemoteException { // TODO Auto-generated method stub return null; } @Override - public AssetFileDescriptor openAssetFile(String callingPackage, String callingFeatureId, + public AssetFileDescriptor openAssetFile(AttributionSource attributionSource, Uri arg0, String arg1, ICancellationSignal signal) throws RemoteException, FileNotFoundException { // TODO Auto-generated method stub @@ -108,22 +109,22 @@ public final class BridgeContentProvider implements IContentProvider { } @Override - public ParcelFileDescriptor openFile(String callingPackage, String callingFeatureId, Uri arg0, - String arg1, ICancellationSignal signal, IBinder token) + public ParcelFileDescriptor openFile(AttributionSource attributionSource, Uri arg0, + String arg1, ICancellationSignal signal) throws RemoteException, FileNotFoundException { // TODO Auto-generated method stub return null; } @Override - public Cursor query(String callingPackage, String callingFeatureId, Uri arg0, String[] arg1, + public Cursor query(AttributionSource attributionSource, Uri arg0, String[] arg1, Bundle arg3, ICancellationSignal arg4) throws RemoteException { // TODO Auto-generated method stub return null; } @Override - public int update(String callingPackage, String callingFeatureId, Uri arg0, ContentValues arg1, + public int update(AttributionSource attributionSource, Uri arg0, ContentValues arg1, Bundle arg2) throws RemoteException { // TODO Auto-generated method stub return 0; @@ -142,7 +143,7 @@ public final class BridgeContentProvider implements IContentProvider { } @Override - public AssetFileDescriptor openTypedAssetFile(String callingPackage, String callingFeatureId, + public AssetFileDescriptor openTypedAssetFile(AttributionSource attributionSource, Uri arg0, String arg1, Bundle arg2, ICancellationSignal signal) throws RemoteException, FileNotFoundException { // TODO Auto-generated method stub @@ -157,20 +158,20 @@ public final class BridgeContentProvider implements IContentProvider { @Override - public Uri canonicalize(String callingPkg, String callingFeatureId, Uri uri) + public Uri canonicalize(AttributionSource attributionSource, Uri uri) throws RemoteException { return null; } @SuppressWarnings("deprecation") @Override - public void canonicalizeAsync(String callingPkg, String callingFeatureId, Uri uri, + public void canonicalizeAsync(AttributionSource attributionSource, Uri uri, RemoteCallback remoteCallback) { AsyncTask.SERIAL_EXECUTOR.execute(() -> { try { final Bundle bundle = new Bundle(); bundle.putParcelable(ContentResolver.REMOTE_CALLBACK_RESULT, - canonicalize(callingPkg, callingFeatureId, uri)); + canonicalize(attributionSource, uri)); remoteCallback.sendResult(bundle); } catch (RemoteException e) { // Ignore @@ -179,19 +180,35 @@ public final class BridgeContentProvider implements IContentProvider { } @Override - public Uri uncanonicalize(String callingPkg, String callingFeatureId, Uri uri) + public Uri uncanonicalize(AttributionSource attributionSource, Uri uri) throws RemoteException { return null; } + @SuppressWarnings("deprecation") + @Override + public void uncanonicalizeAsync(AttributionSource attributionSource, Uri uri, + RemoteCallback remoteCallback) { + AsyncTask.SERIAL_EXECUTOR.execute(() -> { + try { + final Bundle bundle = new Bundle(); + bundle.putParcelable(ContentResolver.REMOTE_CALLBACK_RESULT, + uncanonicalize(attributionSource, uri)); + remoteCallback.sendResult(bundle); + } catch (RemoteException e) { + // Ignore + } + }); + } + @Override - public boolean refresh(String callingPkg, String callingFeatureId, Uri url, Bundle args, + public boolean refresh(AttributionSource attributionSource, Uri url, Bundle args, ICancellationSignal cancellationSignal) throws RemoteException { return false; } @Override - public int checkUriPermission(String callingPkg, String callingFeatureId, Uri uri, int uid, + public int checkUriPermission(AttributionSource attributionSource, Uri uri, int uid, int modeFlags) throws RemoteException { return PackageManager.PERMISSION_DENIED; } diff --git a/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java index e1e61508a9..73a73d0381 100644 --- a/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java +++ b/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java @@ -18,8 +18,8 @@ package com.android.layoutlib.bridge.android; import com.android.SdkConstants; import com.android.ide.common.rendering.api.AssetRepository; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.ide.common.rendering.api.ILayoutPullParser; -import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.LayoutlibCallback; import com.android.ide.common.rendering.api.RenderResources; import com.android.ide.common.rendering.api.ResourceNamespace; @@ -30,21 +30,23 @@ import com.android.ide.common.rendering.api.ResourceValueImpl; import com.android.ide.common.rendering.api.StyleResourceValue; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.BridgeConstants; -import com.android.layoutlib.bridge.android.view.WindowManagerImpl; import com.android.layoutlib.bridge.impl.ParserFactory; import com.android.layoutlib.bridge.impl.ResourceHelper; import com.android.layoutlib.bridge.impl.Stack; import com.android.resources.ResourceType; -import com.android.util.Pair; +import com.android.utils.Pair; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.ActivityManager; +import android.app.ActivityManager_Accessor; import android.app.SystemServiceRegistry; import android.content.BroadcastReceiver; import android.content.ClipboardManager; +import android.content.ComponentCallbacks; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; @@ -69,6 +71,7 @@ import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; import android.hardware.display.DisplayManager; +import android.net.ConnectivityManager; import android.net.Uri; import android.os.Bundle; import android.os.Handler; @@ -90,6 +93,7 @@ import android.view.DisplayAdjustments; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; +import android.view.WindowManagerImpl; import android.view.accessibility.AccessibilityManager; import android.view.autofill.AutofillManager; import android.view.autofill.IAutoFillManager.Default; @@ -116,7 +120,6 @@ import static com.android.layoutlib.bridge.android.RenderParamsFlags.FLAG_KEY_AP /** * Custom implementation of Context/Activity to handle non compiled resources. */ -@SuppressWarnings("deprecation") // For use of Pair. public class BridgeContext extends Context { private static final String PREFIX_THEME_APPCOMPAT = "Theme.AppCompat"; @@ -166,6 +169,8 @@ public class BridgeContext extends Context { private final DisplayManager mDisplayManager; private final AutofillManager mAutofillManager; private final ClipboardManager mClipboardManager; + private final ActivityManager mActivityManager; + private final ConnectivityManager mConnectivityManager; private final HashMap<View, Integer> mScrollYPos = new HashMap<>(); private final HashMap<View, Integer> mScrollXPos = new HashMap<>(); @@ -253,6 +258,8 @@ public class BridgeContext extends Context { mDisplayManager = new DisplayManager(this); mAutofillManager = new AutofillManager(this, new Default()); mClipboardManager = new ClipboardManager(this, null); + mActivityManager = ActivityManager_Accessor.getActivityManagerInstance(this); + mConnectivityManager = new ConnectivityManager(this, null); if (mLayoutlibCallback.isResourceNamespacingRequired()) { if (mLayoutlibCallback.hasAndroidXAppCompat()) { @@ -522,18 +529,18 @@ public class BridgeContext extends Context { popParser(); } } else { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, String.format("File %s is missing!", path), null, null); } } catch (XmlPullParserException e) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "Failed to parse file " + path, e, null, null /*data*/); // we'll return null below. } finally { mBridgeInflater.setResourceReference(null); } } else { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, String.format("Layout %s%s does not exist.", isPlatformLayout ? "android:" : "", layout.getName()), null, null); } @@ -648,6 +655,12 @@ public class BridgeContext extends Context { case CLIPBOARD_SERVICE: return mClipboardManager; + case ACTIVITY_SERVICE: + return mActivityManager; + + case CONNECTIVITY_SERVICE: + return mConnectivityManager; + case AUDIO_SERVICE: case TEXT_CLASSIFICATION_SERVICE: case CONTENT_CAPTURE_MANAGER_SERVICE: @@ -685,7 +698,7 @@ public class BridgeContext extends Context { } if (style == null) { - Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE, + Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_RESOLVE, "Failed to find style with " + resId, null, null); return null; } @@ -754,7 +767,7 @@ public class BridgeContext extends Context { resolver = Resolver.EMPTY_RESOLVER; } else if (set != null) { // really this should not be happening since its instantiated in Bridge - Bridge.getLog().error(LayoutLog.TAG_BROKEN, + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "Parser is not a BridgeXmlBlockParser!", null, null); return null; } else { @@ -793,7 +806,7 @@ public class BridgeContext extends Context { // This should be rare. Happens trying to map R.style.foo to @style/foo fails. // This will happen if the user explicitly used a non existing int value for // defStyleAttr or there's something wrong with the project structure/build. - Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE, + Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_RESOLVE, "Failed to find the style corresponding to the id " + defStyleAttr, null, null); } else { @@ -952,7 +965,7 @@ public class BridgeContext extends Context { if (reference != null) { val = reference.getResourceUrl().toString(); } - Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_RESOLVE_THEME_ATTR, + Bridge.getLog().warning(ILayoutLog.TAG_RESOURCES_RESOLVE_THEME_ATTR, String.format("Failed to find '%s' in current theme.", val), null, val); } @@ -1005,6 +1018,12 @@ public class BridgeContext extends Context { return mPackageManager; } + @Override + public void registerComponentCallbacks(ComponentCallbacks callback) {} + + @Override + public void unregisterComponentCallbacks(ComponentCallbacks callback) {} + // ------------- private new methods /** @@ -1186,7 +1205,7 @@ public class BridgeContext extends Context { public IBinder getBinder() { if (mBinder == null) { - // create a dummy binder. We only need it be not null. + // create a no-op binder. We only need it be not null. mBinder = new IBinder() { @Override public String getInterfaceDescriptor() throws RemoteException { @@ -1965,7 +1984,7 @@ public class BridgeContext extends Context { @Override public File getObbDir() { - Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "OBB not supported", null, null); + Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED, "OBB not supported", null, null); return null; } diff --git a/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java index 584e8c204e..41e4e2dfd9 100644 --- a/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java +++ b/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java @@ -17,6 +17,7 @@ package com.android.layoutlib.bridge.android; import android.os.BatterySaverPolicyConfig; +import android.os.ParcelDuration; import android.os.IBinder; import android.os.IPowerManager; import android.os.PowerManager; @@ -46,6 +47,16 @@ public class BridgePowerManager implements IPowerManager { } @Override + public BatterySaverPolicyConfig getFullPowerSavePolicy() { + return new BatterySaverPolicyConfig.Builder().build(); + } + + @Override + public boolean setFullPowerSavePolicy(BatterySaverPolicyConfig config) { + return false; + } + + @Override public boolean setDynamicPowerSaveHint(boolean powerSaveHint, int disableThreshold) throws RemoteException { return false; @@ -72,25 +83,44 @@ public class BridgePowerManager implements IPowerManager { } @Override + public void setBatteryDischargePrediction(ParcelDuration timeRemaining, + boolean isPersonalized) { + // pass for now + } + + @Override + public ParcelDuration getBatteryDischargePrediction() { + return null; + } + + @Override + public boolean isBatteryDischargePredictionPersonalized() { + return false; + } + + @Override public IBinder asBinder() { // pass for now. return null; } @Override - public void acquireWakeLock(IBinder arg0, int arg1, String arg2, String arg2_5, WorkSource arg3, String arg4) + public void acquireWakeLock(IBinder arg0, int arg1, String arg2, String arg2_5, WorkSource arg3, + String arg4, int arg5) throws RemoteException { // pass for now. } @Override - public void acquireWakeLockWithUid(IBinder arg0, int arg1, String arg2, String arg2_5, int arg3) - throws RemoteException { + public void acquireWakeLockAsync(IBinder arg0, int arg1, String arg2, String arg2_5, + WorkSource arg3, String arg4) throws RemoteException { // pass for now. } @Override - public void powerHint(int hintId, int data) { + public void acquireWakeLockWithUid(IBinder arg0, int arg1, String arg2, String arg2_5, + int arg3, int arg4) + throws RemoteException { // pass for now. } @@ -150,11 +180,21 @@ public class BridgePowerManager implements IPowerManager { } @Override + public void releaseWakeLockAsync(IBinder arg0, int arg1) throws RemoteException { + // pass for now. + } + + @Override public void updateWakeLockUids(IBinder arg0, int[] arg1) throws RemoteException { // pass for now. } @Override + public void updateWakeLockUidsAsync(IBinder arg0, int[] arg1) throws RemoteException { + // pass for now. + } + + @Override public void setAttentionLight(boolean arg0, int arg1) throws RemoteException { // pass for now. } @@ -176,7 +216,8 @@ public class BridgePowerManager implements IPowerManager { } @Override - public void userActivity(long time, int event, int flags) throws RemoteException { + public void userActivity(int displayId, long time, int event, int flags) + throws RemoteException { // pass for now. } @@ -237,6 +278,11 @@ public class BridgePowerManager implements IPowerManager { } @Override + public boolean isAmbientDisplaySuppressedForTokenByApp(String token, int appUid) { + return false; + } + + @Override public boolean isAmbientDisplaySuppressed() { return false; } diff --git a/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java b/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java index 5f785f5092..92693c69be 100644 --- a/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java +++ b/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java @@ -16,7 +16,7 @@ package com.android.layoutlib.bridge.android.support; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException; @@ -61,7 +61,7 @@ public class DesignLibUtil { try { invoke(getMethod(view.getClass(), "setTitle", CharSequence.class), view, title); } catch (ReflectionException e) { - Bridge.getLog().warning(LayoutLog.TAG_INFO, + Bridge.getLog().warning(ILayoutLog.TAG_INFO, "Error occurred while trying to set title.", null, e); } } diff --git a/bridge/src/com/android/layoutlib/bridge/android/support/DrawerLayoutUtil.java b/bridge/src/com/android/layoutlib/bridge/android/support/DrawerLayoutUtil.java index c41bcae5b4..08e7419a42 100644 --- a/bridge/src/com/android/layoutlib/bridge/android/support/DrawerLayoutUtil.java +++ b/bridge/src/com/android/layoutlib/bridge/android/support/DrawerLayoutUtil.java @@ -16,7 +16,7 @@ package com.android.layoutlib.bridge.android.support; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException; @@ -59,7 +59,7 @@ public class DrawerLayoutUtil { invoke(getMethod(drawerLayout.getClass(), "openDrawer", int.class), drawerLayout, gravity); } catch (ReflectionException e) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to open navigation drawer", + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "Unable to open navigation drawer", getCause(e), null, null); } } diff --git a/bridge/src/com/android/layoutlib/bridge/android/support/FragmentTabHostUtil.java b/bridge/src/com/android/layoutlib/bridge/android/support/FragmentTabHostUtil.java index c77cb572c5..a426b27a12 100644 --- a/bridge/src/com/android/layoutlib/bridge/android/support/FragmentTabHostUtil.java +++ b/bridge/src/com/android/layoutlib/bridge/android/support/FragmentTabHostUtil.java @@ -16,7 +16,7 @@ package com.android.layoutlib.bridge.android.support; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException; @@ -59,7 +59,7 @@ public class FragmentTabHostUtil { } if (fragmentManager == null) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "Unable to find FragmentManager.", null, null); return; } @@ -70,7 +70,7 @@ public class FragmentTabHostUtil { android.R.id.tabcontent); } catch (ReflectionException e) { Throwable cause = getCause(e); - Bridge.getLog().error(LayoutLog.TAG_BROKEN, + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "Error occurred while trying to setup FragmentTabHost.", cause, null, null); } } diff --git a/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java b/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java index 6fc8009b31..ff20fbf6a2 100644 --- a/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java +++ b/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java @@ -16,7 +16,7 @@ package com.android.layoutlib.bridge.android.support; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.ide.common.rendering.api.LayoutlibCallback; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.android.BridgeContext; @@ -72,7 +72,7 @@ public class RecyclerViewUtil { } } catch (ReflectionException e) { Throwable cause = getCause(e); - Bridge.getLog().error(LayoutLog.TAG_BROKEN, + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "Error occurred while trying to setup RecyclerView.", cause, null, null); } } diff --git a/bridge/src/com/android/layoutlib/bridge/android/support/SupportPreferencesUtil.java b/bridge/src/com/android/layoutlib/bridge/android/support/SupportPreferencesUtil.java index 171edb9095..f195a5e593 100644 --- a/bridge/src/com/android/layoutlib/bridge/android/support/SupportPreferencesUtil.java +++ b/bridge/src/com/android/layoutlib/bridge/android/support/SupportPreferencesUtil.java @@ -298,8 +298,8 @@ public class SupportPreferencesUtil { preferenceGroupAdapter); ScrollView scrollView = new ScrollView(context); - scrollView.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, - LayoutParams.WRAP_CONTENT)); + scrollView.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, + LayoutParams.MATCH_PARENT)); scrollView.addView(listView); if (root != null) { diff --git a/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java b/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java index ab88f15222..8ca809e516 100644 --- a/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java +++ b/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java @@ -15,7 +15,7 @@ */ package com.android.layoutlib.bridge.bars; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.ide.common.rendering.api.LayoutlibCallback; import com.android.ide.common.rendering.api.RenderResources; import com.android.ide.common.rendering.api.ResourceReference; @@ -118,7 +118,7 @@ public class AppCompatActionBar extends BridgeActionBar { setupActionBar(); getContentRoot().setId(id.content); } catch (Exception e) { - Bridge.getLog().warning(LayoutLog.TAG_BROKEN, + Bridge.getLog().warning(ILayoutLog.TAG_BROKEN, "Failed to load AppCompat ActionBar with unknown error.", null, e); } } @@ -201,7 +201,7 @@ public class AppCompatActionBar extends BridgeActionBar { if (menuIds.size() > 1) { // Supporting multiple menus means that we would need to instantiate our own supportlib // MenuInflater instances using reflection - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "Support Toolbar does not currently support multiple menus in the preview.", null, null, null); } diff --git a/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java b/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java index 8790cb531f..1f7b187ec7 100644 --- a/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java +++ b/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java @@ -45,7 +45,7 @@ public abstract class BridgeActionBar { private final View mDecorContent; private final ActionBarCallback mCallback; - @SuppressWarnings("NullableProblems") // Should be initialized by subclasses. + @SuppressWarnings("NotNullFieldNotInitialized") // Should be initialized by subclasses. @NonNull private FrameLayout mContentRoot; public BridgeActionBar(@NonNull BridgeContext context, @NonNull SessionParams params) { diff --git a/bridge/src/com/android/layoutlib/bridge/bars/Config.java b/bridge/src/com/android/layoutlib/bridge/bars/Config.java index 7813844133..a49a6643a5 100644 --- a/bridge/src/com/android/layoutlib/bridge/bars/Config.java +++ b/bridge/src/com/android/layoutlib/bridge/bars/Config.java @@ -92,8 +92,8 @@ public class Config { } public static String getTime(int platformVersion) { - if (isGreaterOrEqual(platformVersion, Q)) { - return "10:00"; + if (isGreaterOrEqual(platformVersion, R)) { + return "11:00"; } if (platformVersion < GINGERBREAD) { return "2:20"; @@ -134,6 +134,9 @@ public class Config { if (platformVersion < Q) { return "9:00"; } + if (platformVersion < R) { + return "10:00"; + } // Should never happen. return "4:04"; } diff --git a/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java index 3a5f6331e6..0bb72ed851 100644 --- a/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java +++ b/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java @@ -16,7 +16,7 @@ package com.android.layoutlib.bridge.bars; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.ide.common.rendering.api.RenderResources; import com.android.ide.common.rendering.api.ResourceValue; import com.android.ide.common.rendering.api.StyleResourceValue; @@ -256,7 +256,7 @@ abstract class CustomBar extends LinearLayout { return ResourceHelper.getColor(resource.getValue()); } catch (NumberFormatException e) { // Conversion failed. - Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT, + Bridge.getLog().warning(ILayoutLog.TAG_RESOURCES_FORMAT, "Theme attribute @android:" + attr + " does not reference a color, instead is '" + resource.getValue() + "'.", null, resource); diff --git a/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java b/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java index 230094e2c2..e08f5238ea 100644 --- a/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java +++ b/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java @@ -191,7 +191,7 @@ public class FrameworkActionBar extends BridgeActionBar { // Copied from com.android.internal.view.menu.MenuPopHelper.measureContentWidth() private int measureContentWidth(@NonNull ListAdapter adapter) { - // Menus don't tend to be long, so this is more sane than it looks. + // Menus don't tend to be long, so this is shouldn't be a problem int maxWidth = 0; View itemView = null; int itemType = 0; diff --git a/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java b/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java index f58443a6b6..dc823f7e37 100644 --- a/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java +++ b/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java @@ -16,7 +16,7 @@ package com.android.layoutlib.bridge.bars; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.ide.common.rendering.api.ResourceNamespace; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.android.BridgeContext; @@ -90,7 +90,7 @@ public class StatusBar extends CustomBar { } if (icons.size() != 2 || clockView == null) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to initialize statusbar", null, + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "Unable to initialize statusbar", null, null, null); return; } @@ -126,10 +126,10 @@ public class StatusBar extends CustomBar { imageView.setImageDrawable( Drawable.createFromXml(mContext.getResources(), parser)); } catch (XmlPullParserException e) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to draw wifi icon", e, + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "Unable to draw wifi icon", e, null, null); } catch (IOException e) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to draw wifi icon", e, + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "Unable to draw wifi icon", e, null, null); } } diff --git a/bridge/src/com/android/layoutlib/bridge/bars/ThemePreviewNavigationBar.java b/bridge/src/com/android/layoutlib/bridge/bars/ThemePreviewNavigationBar.java deleted file mode 100644 index 523f14010a..0000000000 --- a/bridge/src/com/android/layoutlib/bridge/bars/ThemePreviewNavigationBar.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2015 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 com.android.layoutlib.bridge.bars; - -import com.android.layoutlib.bridge.android.BridgeContext; -import com.android.resources.Density; - -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.util.AttributeSet; -import android.view.View; -import android.widget.LinearLayout; - -/** - * Navigation Bar for the Theme Editor preview. - * - * For small bars, it is identical to {@link NavigationBar}. - * But wide bars from {@link NavigationBar} are too wide for the Theme Editor preview. - * To solve that problem, {@link ThemePreviewNavigationBar} use the layout for small bars, - * and have no padding on the sides. That way, they have a similar look as the true ones, - * and they fit in the Theme Editor preview. - */ -public class ThemePreviewNavigationBar extends NavigationBar { - private static final int PADDING_WIDTH_SW600 = 0; - - @SuppressWarnings("unused") - public ThemePreviewNavigationBar(Context context, AttributeSet attrs) { - super((BridgeContext) context, - Density.getEnum(((BridgeContext) context).getMetrics().densityDpi), - LinearLayout.HORIZONTAL, // In this mode, it doesn't need to be render vertically - ((BridgeContext) context).getConfiguration().getLayoutDirection() == - View.LAYOUT_DIRECTION_RTL, - (context.getApplicationInfo().flags & ApplicationInfo.FLAG_SUPPORTS_RTL) != 0, - 0, LAYOUT_XML, false); - } - - @Override - protected int getSidePadding(float sw) { - if (sw >= 600) { - return PADDING_WIDTH_SW600; - } - return super.getSidePadding(sw); - } -} diff --git a/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java b/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java index b71a0e28bf..5991eb0721 100644 --- a/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java +++ b/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java @@ -111,7 +111,6 @@ public final class DelegateManager<T> { @GuardedBy("sNativeAllocations") private static long sNativeAllocationsCount = 0; - @SuppressWarnings("FieldCanBeLocal") private final Class<T> mClass; public DelegateManager(Class<T> theClass) { diff --git a/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java b/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java index 959ba77f6a..f3ebd40706 100644 --- a/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java +++ b/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java @@ -16,12 +16,7 @@ package com.android.layoutlib.bridge.impl; -import static java.awt.image.BufferedImage.TYPE_INT_ARGB; -import static java.awt.image.BufferedImage.TYPE_INT_RGB; -import static java.lang.Math.min; -import static java.lang.Math.max; - -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import android.graphics.Bitmap_Delegate; @@ -51,6 +46,11 @@ import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.util.ArrayList; +import static java.awt.image.BufferedImage.TYPE_INT_ARGB; +import static java.awt.image.BufferedImage.TYPE_INT_RGB; +import static java.lang.Math.max; +import static java.lang.Math.min; + /** * Class representing a graphics context snapshot, as well as a context stack as a linked list. * <p> @@ -846,7 +846,7 @@ public class GcSnapshot { g.setPaint(shaderPaint); return; } else { - Bridge.getLog().fidelityWarning(LayoutLog.TAG_SHADER, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_SHADER, shaderDelegate.getSupportMessage(), null, null, null); } } diff --git a/bridge/src/com/android/layoutlib/bridge/impl/Layout.java b/bridge/src/com/android/layoutlib/bridge/impl/Layout.java index 45accb9a2b..c2fb3e1ac7 100644 --- a/bridge/src/com/android/layoutlib/bridge/impl/Layout.java +++ b/bridge/src/com/android/layoutlib/bridge/impl/Layout.java @@ -543,7 +543,6 @@ class Layout extends FrameLayout { } } - @SuppressWarnings("SameParameterValue") private int getDimension(@NonNull ResourceReference attrRef, int defaultValue) { ResourceValue value = mResources.findItemInTheme(attrRef); value = mResources.resolveResValue(value); @@ -557,7 +556,6 @@ class Layout extends FrameLayout { return defaultValue; } - @SuppressWarnings("SameParameterValue") private int getFrameworkAttrDimension(@NonNull String attr, int defaultValue) { return getDimension(BridgeContext.createFrameworkAttrReference(attr), defaultValue); } diff --git a/bridge/src/com/android/layoutlib/bridge/impl/PorterDuffUtility.java b/bridge/src/com/android/layoutlib/bridge/impl/PorterDuffUtility.java index dcbd272960..86f80fee23 100644 --- a/bridge/src/com/android/layoutlib/bridge/impl/PorterDuffUtility.java +++ b/bridge/src/com/android/layoutlib/bridge/impl/PorterDuffUtility.java @@ -16,7 +16,7 @@ package com.android.layoutlib.bridge.impl; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layoutlib.bridge.Bridge; import android.graphics.BlendComposite; @@ -47,7 +47,7 @@ public final class PorterDuffUtility { if (porterDuffMode >= 0 && porterDuffMode < MODES_COUNT) { return PorterDuff.intToMode(porterDuffMode); } - Bridge.getLog().error(LayoutLog.TAG_BROKEN, + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, String.format("Unknown PorterDuff.Mode: %1$d", porterDuffMode), null, null); assert false; return Mode.SRC_OVER; @@ -97,7 +97,7 @@ public final class PorterDuffUtility { case OVERLAY: return BlendComposite.getInstance(BlendingMode.OVERLAY, alpha1); default: - Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN, + Bridge.getLog().fidelityWarning(ILayoutLog.TAG_BROKEN, String.format("Unsupported PorterDuff Mode: %1$s", mode.name()), null, null, null /*data*/); diff --git a/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java b/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java index b24c3833fd..2ab0509b6a 100644 --- a/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java +++ b/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java @@ -17,7 +17,7 @@ package com.android.layoutlib.bridge.impl; import com.android.ide.common.rendering.api.HardwareConfig; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.ide.common.rendering.api.RenderParams; import com.android.ide.common.rendering.api.RenderResources; import com.android.ide.common.rendering.api.Result; @@ -252,7 +252,7 @@ public abstract class RenderAction<T extends RenderParams> { getContext().getMetrics(), Surface.ROTATION_0, hasNavigationBar); WindowManagerGlobal_Delegate.setWindowManagerService(iwm); - LayoutLog currentLog = mParams.getLog(); + ILayoutLog currentLog = mParams.getLog(); Bridge.setLog(currentLog); mContext.getRenderResources().setLogger(currentLog); } @@ -307,7 +307,7 @@ public abstract class RenderAction<T extends RenderParams> { * Returns the log associated with the session. * @return the log or null if there are none. */ - public LayoutLog getLog() { + public ILayoutLog getLog() { if (mParams != null) { return mParams.getLog(); } diff --git a/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java index 1338c1700d..93d3df8640 100644 --- a/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java +++ b/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java @@ -18,8 +18,8 @@ package com.android.layoutlib.bridge.impl; import com.android.ide.common.rendering.api.AdapterBinding; import com.android.ide.common.rendering.api.HardwareConfig; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.ide.common.rendering.api.ILayoutPullParser; -import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.LayoutlibCallback; import com.android.ide.common.rendering.api.RenderSession; import com.android.ide.common.rendering.api.ResourceReference; @@ -46,16 +46,14 @@ import com.android.layoutlib.bridge.android.support.FragmentTabHostUtil; import com.android.layoutlib.bridge.android.support.SupportPreferencesUtil; import com.android.layoutlib.bridge.impl.binding.FakeAdapter; import com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter; -import com.android.tools.layoutlib.java.System_Delegate; -import com.android.tools.idea.validator.ValidatorResult; import com.android.tools.idea.validator.LayoutValidator; import com.android.tools.idea.validator.ValidatorResult; import com.android.tools.idea.validator.ValidatorResult.Builder; -import com.android.util.Pair; +import com.android.tools.layoutlib.java.System_Delegate; +import com.android.utils.Pair; import android.annotation.NonNull; import android.annotation.Nullable; -import android.app.Fragment_Delegate; import android.graphics.Bitmap; import android.graphics.Bitmap_Delegate; import android.graphics.Canvas; @@ -93,6 +91,8 @@ import java.util.IdentityHashMap; import java.util.List; import java.util.Map; +import com.google.android.apps.common.testing.accessibility.framework.uielement.AccessibilityHierarchyAndroid_ViewElementClassNamesAndroid_Delegate; + import static com.android.ide.common.rendering.api.Result.Status.ERROR_INFLATION; import static com.android.ide.common.rendering.api.Result.Status.ERROR_NOT_INFLATED; import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN; @@ -119,7 +119,6 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { private Canvas mCanvas; private int mMeasuredScreenWidth = -1; private int mMeasuredScreenHeight = -1; - private boolean mIsAlphaChannelImage; /** If >= 0, a frame will be executed */ private long mElapsedFrameTimeNanos = -1; /** True if one frame has been already executed to start the animations */ @@ -175,11 +174,6 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { SessionParams params = getParams(); BridgeContext context = getContext(); - // use default of true in case it's not found to use alpha by default - mIsAlphaChannelImage = - ResourceHelper.getBooleanThemeFrameworkAttrValue(params.getResources(), - "windowIsFloating", true); - mLayoutBuilder = new Layout.Builder(params, context); // build the inflater and parser. @@ -209,10 +203,10 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { mMeasuredScreenHeight = hardwareConfig.getScreenHeight(); if (renderingMode != RenderingMode.NORMAL) { - int widthMeasureSpecMode = renderingMode.isHorizExpand() ? + int widthMeasureSpecMode = renderingMode.getHorizAction() == SizeAction.EXPAND ? MeasureSpec.UNSPECIFIED // this lets us know the actual needed size : MeasureSpec.EXACTLY; - int heightMeasureSpecMode = renderingMode.isVertExpand() ? + int heightMeasureSpecMode = renderingMode.getVertAction() == SizeAction.EXPAND ? MeasureSpec.UNSPECIFIED // this lets us know the actual needed size : MeasureSpec.EXACTLY; @@ -233,7 +227,6 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { // first measure the full layout, with EXACTLY to get the size of the // content as it is inside the decor/dialog - @SuppressWarnings("deprecation") Pair<Integer, Integer> exactMeasure = measureView( mViewRoot, measuredView, mMeasuredScreenWidth, MeasureSpec.EXACTLY, @@ -241,7 +234,6 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { // now measure the content only using UNSPECIFIED (where applicable, based on // the rendering mode). This will give us the size the content needs. - @SuppressWarnings("deprecation") Pair<Integer, Integer> neededMeasure = measureView( mContentRoot, mContentRoot.getChildAt(0), mMeasuredScreenWidth, widthMeasureSpecMode, @@ -303,14 +295,14 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { if (Bridge.isLocaleRtl(params.getLocale())) { if (!params.isRtlSupported()) { - Bridge.getLog().warning(LayoutLog.TAG_RTL_NOT_ENABLED, + Bridge.getLog().warning(ILayoutLog.TAG_RTL_NOT_ENABLED, "You are using a right-to-left " + "(RTL) locale but RTL is not enabled", null, null); } else if (params.getSimulatedPlatformVersion() !=0 && params.getSimulatedPlatformVersion() < 17) { // This will render ok because we are using the latest layoutlib but at least // warn the user that this might fail in a real device. - Bridge.getLog().warning(LayoutLog.TAG_RTL_NOT_SUPPORTED, "You are using a " + + Bridge.getLog().warning(ILayoutLog.TAG_RTL_NOT_SUPPORTED, "You are using a " + "right-to-left " + "(RTL) locale but RTL is not supported for API level < 17", null, null); } @@ -505,11 +497,11 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { newImage = true; } - if (params.isBgColorOverridden()) { + if (params.isTransparentBackground()) { // since we override the content, it's the same as if it was a new image. newImage = true; Graphics2D gc = mImage.createGraphics(); - gc.setColor(new Color(params.getOverrideBgColor(), true)); + gc.setColor(new Color(0, true)); gc.setComposite(AlphaComposite.Src); gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight); gc.dispose(); @@ -580,6 +572,9 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { params.getFlag(RenderParamsFlags.FLAG_ENABLE_LAYOUT_VALIDATOR_IMAGE_CHECK)); if (enableLayoutValidation && !getViewInfos().isEmpty()) { + AccessibilityHierarchyAndroid_ViewElementClassNamesAndroid_Delegate.sLayoutlibCallback = + getContext().getLayoutlibCallback(); + BufferedImage imageToPass = enableLayoutValidationImageCheck ? getImage() : null; ValidatorResult validatorResult = @@ -590,6 +585,8 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { ValidatorResult.Builder builder = new Builder(); builder.mMetric.mErrorMessage = e.getMessage(); setValidatorResult(builder.build()); + } finally { + AccessibilityHierarchyAndroid_ViewElementClassNamesAndroid_Delegate.sLayoutlibCallback = null; } // success! @@ -620,7 +617,6 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { * @param heightMode the MeasureSpec mode to use for the height. * @return the measured width/height if measuredView is non-null, null otherwise. */ - @SuppressWarnings("deprecation") // For the use of Pair private static Pair<Integer, Integer> measureView(ViewGroup viewToMeasure, View measuredView, int width, int widthMode, int height, int heightMode) { int w_spec = MeasureSpec.makeMeasureSpec(width, widthMode); @@ -644,7 +640,6 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { * @param layoutlibCallback callback to the project. * @param skip the view and it's children are not processed. */ - @SuppressWarnings("deprecation") // For the use of Pair private void postInflateProcess(View view, LayoutlibCallback layoutlibCallback, View skip) throws PostInflateException { if (view == skip) { @@ -872,7 +867,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { } if (count == 0) { - // Create a dummy child to get a single tab + // Create a placeholder child to get a single tab TabSpec spec = tabHost.newTabSpec("tag") .setIndicator("Tab Label", tabHost.getResources() .getDrawable(android.R.drawable.ic_menu_info_details, null)) @@ -883,9 +878,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { for (int i = 0 ; i < count ; i++) { View child = content.getChildAt(i); String tabSpec = String.format("tab_spec%d", i+1); - @SuppressWarnings("ConstantConditions") // child cannot be null. int id = child.getId(); - @SuppressWarnings("deprecation") ResourceReference resource = layoutlibCallback.resolveResourceId(id); String name; if (resource != null) { @@ -1123,10 +1116,6 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { return mImage; } - public boolean isAlphaChannelImage() { - return mIsAlphaChannelImage; - } - public List<ViewInfo> getViewInfos() { return mViewInfoList; } diff --git a/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java index 8e2ecd6ea5..0a363590a7 100644 --- a/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java +++ b/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java @@ -18,8 +18,8 @@ package com.android.layoutlib.bridge.impl; import com.android.SdkConstants; import com.android.ide.common.rendering.api.AssetRepository; import com.android.ide.common.rendering.api.DensityBasedResourceValue; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.ide.common.rendering.api.ILayoutPullParser; -import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.LayoutlibCallback; import com.android.ide.common.rendering.api.RenderResources; import com.android.ide.common.rendering.api.ResourceNamespace; @@ -161,10 +161,16 @@ public final class ResourceHelper { } // try to load the color state list from an int - try { - int color = getColor(value); - return ColorStateList.valueOf(color); - } catch (NumberFormatException ignored) { + if (value.trim().startsWith("#")) { + try { + int color = getColor(value); + return ColorStateList.valueOf(color); + } catch (NumberFormatException e) { + Bridge.getLog().warning(ILayoutLog.TAG_RESOURCES_FORMAT, + String.format("\"%1$s\" cannot be interpreted as a color.", value), + null, null); + return null; + } } try { @@ -202,13 +208,13 @@ public final class ResourceHelper { } } } catch (XmlPullParserException e) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "Failed to configure parser for " + value, e, null,null /*data*/); // we'll return null below. } catch (Exception e) { // this is an error and not warning since the file existence is // checked before attempting to parse it. - Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ, + Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_READ, "Failed to parse file " + value, e, null, null /*data*/); return null; @@ -311,12 +317,17 @@ public final class ResourceHelper { return null; } - String lowerCaseValue = stringValue.toLowerCase(); // try the simple case first. Attempt to get a color from the value - try { - int color = getColor(stringValue); - return new ColorDrawable(color); - } catch (NumberFormatException ignore) { + if (stringValue.trim().startsWith("#")) { + try { + int color = getColor(stringValue); + return new ColorDrawable(color); + } catch (NumberFormatException e) { + Bridge.getLog().warning(ILayoutLog.TAG_RESOURCES_FORMAT, + String.format("\"%1$s\" cannot be interpreted as a color.", stringValue), + null, null); + return null; + } } Density density = Density.MEDIUM; @@ -327,12 +338,13 @@ public final class ResourceHelper { } } + String lowerCaseValue = stringValue.toLowerCase(); if (lowerCaseValue.endsWith(NinePatch.EXTENSION_9PATCH)) { try { return getNinePatchDrawable(density, value.isFramework(), stringValue, context); } catch (IOException e) { // failed to read the file, we'll return null below. - Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ, + Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_READ, "Failed to load " + stringValue, e, null, null /*data*/); } @@ -393,7 +405,7 @@ public final class ResourceHelper { return new BitmapDrawable(context.getResources(), bitmap); } catch (IOException e) { // we'll return null below - Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ, + Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_READ, "Failed to load " + stringValue, e, null, null /*data*/); } } @@ -633,7 +645,7 @@ public final class ResourceHelper { applyUnit(sUnitNames[1], outValue, sFloatOut); computeTypedValue(outValue, f, sFloatOut[0]); - Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE, + Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_RESOLVE, String.format( "Dimension \"%1$s\" in attribute \"%2$s\" is missing unit!", value, attribute), diff --git a/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java b/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java index 76c5942217..b7f59c4994 100644 --- a/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java +++ b/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java @@ -17,14 +17,14 @@ package com.android.layoutlib.bridge.impl.binding; import com.android.ide.common.rendering.api.DataBindingItem; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.ide.common.rendering.api.LayoutlibCallback; -import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.LayoutlibCallback.ViewAttribute; import com.android.ide.common.rendering.api.ResourceReference; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.android.BridgeContext; import com.android.layoutlib.bridge.impl.RenderAction; -import com.android.util.Pair; +import com.android.utils.Pair; import android.view.View; import android.view.ViewGroup; @@ -38,7 +38,6 @@ import android.widget.TextView; */ public class AdapterHelper { - @SuppressWarnings("deprecation") static Pair<View, Boolean> getView(AdapterItem item, AdapterItem parentItem, ViewGroup parent, LayoutlibCallback callback, ResourceReference adapterRef, boolean skipCallbackParser) { // we don't care about recycling here because we never scroll. @@ -93,7 +92,7 @@ public class AdapterHelper { resolvedRef, ViewAttribute.TEXT, tv.getText().toString()); if (value != null) { if (value.getClass() != ViewAttribute.TEXT.getAttributeClass()) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format( + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, String.format( "Wrong Adapter Item value class for TEXT. Expected String, got %s", value.getClass().getName()), null, null); } else { @@ -113,7 +112,7 @@ public class AdapterHelper { resolvedRef, ViewAttribute.IS_CHECKED, cb.isChecked()); if (value != null) { if (value.getClass() != ViewAttribute.IS_CHECKED.getAttributeClass()) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format( + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, String.format( "Wrong Adapter Item value class for IS_CHECKED. Expected Boolean, got %s", value.getClass().getName()), null, null); } else { @@ -133,7 +132,7 @@ public class AdapterHelper { resolvedRef, ViewAttribute.SRC, iv.getDrawable()); if (value != null) { if (value.getClass() != ViewAttribute.SRC.getAttributeClass()) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format( + Bridge.getLog().error(ILayoutLog.TAG_BROKEN, String.format( "Wrong Adapter Item value class for SRC. Expected Boolean, got %s", value.getClass().getName()), null, null); } else { diff --git a/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java b/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java index 142eac1725..83ff28d05f 100644 --- a/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java +++ b/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java @@ -20,7 +20,7 @@ import com.android.ide.common.rendering.api.AdapterBinding; import com.android.ide.common.rendering.api.DataBindingItem; import com.android.ide.common.rendering.api.LayoutlibCallback; import com.android.ide.common.rendering.api.ResourceReference; -import com.android.util.Pair; +import com.android.utils.Pair; import android.view.View; import android.view.ViewGroup; @@ -110,7 +110,6 @@ public class FakeAdapter extends BaseAdapter { public View getView(int position, View convertView, ViewGroup parent) { // we don't care about recycling here because we never scroll. AdapterItem item = mItems.get(position); - @SuppressWarnings("deprecation") Pair<View, Boolean> pair = AdapterHelper.getView(item, null, parent, mCallback, mAdapterRef, mSkipCallbackParser); mSkipCallbackParser = pair.getSecond(); diff --git a/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java b/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java index 344b17eab0..21679f726e 100644 --- a/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java +++ b/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java @@ -20,7 +20,7 @@ import com.android.ide.common.rendering.api.AdapterBinding; import com.android.ide.common.rendering.api.DataBindingItem; import com.android.ide.common.rendering.api.LayoutlibCallback; import com.android.ide.common.rendering.api.ResourceReference; -import com.android.util.Pair; +import com.android.utils.Pair; import android.database.DataSetObserver; import android.view.View; @@ -31,7 +31,6 @@ import android.widget.HeterogeneousExpandableList; import java.util.ArrayList; import java.util.List; -@SuppressWarnings("deprecation") public class FakeExpandableAdapter implements ExpandableListAdapter, HeterogeneousExpandableList { private final LayoutlibCallback mCallback; diff --git a/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java b/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java index 161bf4155a..16aa058b76 100644 --- a/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java +++ b/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java @@ -17,7 +17,7 @@ package com.android.layoutlib.bridge.util; import com.android.resources.ResourceType; -import com.android.util.Pair; +import com.android.utils.Pair; import android.annotation.NonNull; import android.util.SparseArray; diff --git a/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java b/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java index a2a8aa96b1..dd06e80e60 100644 --- a/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java +++ b/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java @@ -133,6 +133,7 @@ public class SparseWeakArray<E> { if (i != o) { keys[o] = keys[i]; values[o] = val; + values[i] = null; } o++; diff --git a/bridge/src/libcore/icu/ICU_Delegate.java b/bridge/src/libcore/icu/ICU_Delegate.java index 880344f5cc..7bb82ad2c3 100644 --- a/bridge/src/libcore/icu/ICU_Delegate.java +++ b/bridge/src/libcore/icu/ICU_Delegate.java @@ -18,9 +18,6 @@ package libcore.icu; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; -import android.icu.text.DateTimePatternGenerator; -import android.icu.util.ULocale; - import java.util.Locale; /** @@ -34,22 +31,11 @@ public class ICU_Delegate { // --- Native methods accessing ICU's database. @LayoutlibDelegate - /*package*/ static String getBestDateTimePatternNative(String skeleton, String localeName) { - return DateTimePatternGenerator.getInstance(new ULocale(localeName)) - .getBestPattern(skeleton); - } - - @LayoutlibDelegate /*package*/ static String[] getAvailableLocalesNative() { return new String[0]; } @LayoutlibDelegate - /*package*/ static String getCurrencyCode(String locale) { - return ""; - } - - @LayoutlibDelegate /*package*/ static String getISO3Country(String locale) { return ""; } @@ -75,78 +61,22 @@ public class ICU_Delegate { } @LayoutlibDelegate - /*package*/ static boolean initLocaleDataNative(String locale, LocaleData result) { - - // Used by Calendar. - result.firstDayOfWeek = 1; - result.minimalDaysInFirstWeek = 1; - - // Used by DateFormatSymbols. - result.amPm = new String[] { "AM", "PM" }; - result.eras = new String[] { "BC", "AD" }; - - result.longMonthNames = new String[] { "January", "February", "March", "April", "May", - "June", "July", "August", "September", "October", "November", "December" }; - result.shortMonthNames = new String[] { "Jan", "Feb", "Mar", "Apr", "May", - "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - result.longStandAloneMonthNames = result.longMonthNames; - result.shortStandAloneMonthNames = result.shortMonthNames; - - // The platform code expects this to begin at index 1, rather than 0. It maps it directly to - // the constants from java.util.Calendar.<weekday> - result.longWeekdayNames = new String[] { - "", "Sunday", "Monday" ,"Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; - result.shortWeekdayNames = new String[] { - "", "Sun", "Mon" ,"Tue", "Wed", "Thu", "Fri", "Sat" }; - result.tinyWeekdayNames = new String[] { - "", "S", "M", "T", "W", "T", "F", "S" }; - - result.longStandAloneWeekdayNames = result.longWeekdayNames; - result.shortStandAloneWeekdayNames = result.shortWeekdayNames; - result.tinyStandAloneWeekdayNames = result.tinyWeekdayNames; - - result.fullTimeFormat = ""; - result.longTimeFormat = ""; - result.mediumTimeFormat = ""; - result.shortTimeFormat = ""; - - result.fullDateFormat = ""; - result.longDateFormat = ""; - result.mediumDateFormat = ""; - result.shortDateFormat = ""; - - // Used by DecimalFormatSymbols. - result.zeroDigit = '0'; - result.decimalSeparator = '.'; - result.groupingSeparator = ','; - result.patternSeparator = ' '; - result.percent = "%"; - result.perMill = "\u2030"; - result.monetarySeparator = ' '; - result.minusSign = "-"; - result.exponentSeparator = "e"; - result.infinity = "\u221E"; - result.NaN = "NaN"; - // Also used by Currency. - result.currencySymbol = "$"; - result.internationalCurrencySymbol = "USD"; - - // Used by DecimalFormat and NumberFormat. - result.numberPattern = "%f"; - result.integerPattern = "%d"; - result.currencyPattern = "%s"; - result.percentPattern = "%f"; + /*package*/ static String getDefaultLocale() { + return Locale.getDefault().toString(); + } - return true; + @LayoutlibDelegate + /*package*/ static String getCldrVersion() { + return ""; } @LayoutlibDelegate - /*package*/ static void setDefaultLocale(String locale) { - ICU.setDefaultLocale(locale); + /*package*/ static String getIcuVersion() { + return ""; } @LayoutlibDelegate - /*package*/ static String getDefaultLocale() { - return ICU.getDefaultLocale(); + /*package*/ static String getUnicodeVersion() { + return ""; } } diff --git a/bridge/tests/Android.bp b/bridge/tests/Android.bp index 5c51c68a73..7beb94d8a8 100644 --- a/bridge/tests/Android.bp +++ b/bridge/tests/Android.bp @@ -12,6 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + java_test_host { name: "layoutlib-tests", diff --git a/bridge/tests/src/android/content/res/BridgeTypedArrayTest.java b/bridge/tests/src/android/content/res/BridgeTypedArrayTest.java new file mode 100644 index 0000000000..0be3423624 --- /dev/null +++ b/bridge/tests/src/android/content/res/BridgeTypedArrayTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2020 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 org.junit.Test; + +import static android.util.TypedValue.TYPE_ATTRIBUTE; +import static android.util.TypedValue.TYPE_DIMENSION; +import static android.util.TypedValue.TYPE_FLOAT; +import static android.util.TypedValue.TYPE_INT_BOOLEAN; +import static android.util.TypedValue.TYPE_INT_COLOR_ARGB4; +import static android.util.TypedValue.TYPE_INT_COLOR_ARGB8; +import static android.util.TypedValue.TYPE_INT_COLOR_RGB4; +import static android.util.TypedValue.TYPE_INT_COLOR_RGB8; +import static android.util.TypedValue.TYPE_INT_DEC; +import static android.util.TypedValue.TYPE_INT_HEX; +import static android.util.TypedValue.TYPE_NULL; +import static android.util.TypedValue.TYPE_REFERENCE; +import static android.util.TypedValue.TYPE_STRING; +import static org.junit.Assert.assertEquals; + +public class BridgeTypedArrayTest { + + @Test + public void getType() { + assertEquals(TYPE_NULL, BridgeTypedArray.getType(null)); + assertEquals(TYPE_REFERENCE, BridgeTypedArray.getType("@drawable/my_drawable")); + assertEquals(TYPE_ATTRIBUTE, BridgeTypedArray.getType("?attr/colorPrimary")); + assertEquals(TYPE_INT_BOOLEAN, BridgeTypedArray.getType("true")); + assertEquals(TYPE_STRING, BridgeTypedArray.getType("False")); + assertEquals(TYPE_INT_HEX, BridgeTypedArray.getType("0xffa39d")); + assertEquals(TYPE_STRING, BridgeTypedArray.getType("0xnothex")); + assertEquals(TYPE_INT_COLOR_RGB4, BridgeTypedArray.getType("#f34")); + assertEquals(TYPE_INT_COLOR_ARGB4, BridgeTypedArray.getType("#2f34")); + assertEquals(TYPE_INT_COLOR_RGB8, BridgeTypedArray.getType("#f34ab4")); + assertEquals(TYPE_INT_COLOR_ARGB8, BridgeTypedArray.getType("#1f34dc28")); + assertEquals(TYPE_STRING, BridgeTypedArray.getType("#notacolor")); + assertEquals(TYPE_DIMENSION, BridgeTypedArray.getType("16dp")); + assertEquals(TYPE_STRING, BridgeTypedArray.getType("16notaunit")); + assertEquals(TYPE_INT_DEC, BridgeTypedArray.getType("98543")); + assertEquals(TYPE_FLOAT, BridgeTypedArray.getType("43.364")); + assertEquals(TYPE_STRING, BridgeTypedArray.getType("5432dp342")); + } +} diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/FrameworkResources.java b/bridge/tests/src/com/android/ide/common/resources/deprecated/FrameworkResources.java index 2408fa6011..2624df0e1b 100644 --- a/bridge/tests/src/com/android/ide/common/resources/deprecated/FrameworkResources.java +++ b/bridge/tests/src/com/android/ide/common/resources/deprecated/FrameworkResources.java @@ -53,7 +53,7 @@ public class FrameworkResources extends ResourceRepository { private final Map<ResourceType, List<ResourceItem>> mPublicResourceMap = new EnumMap<>(ResourceType.class); - public FrameworkResources(@NotNull IAbstractFolder resFolder) { + public FrameworkResources(@NotNull TestFolderWrapper resFolder) { super(resFolder, true /*isFrameworkRepository*/); } diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/IdGeneratingResourceFile.java b/bridge/tests/src/com/android/ide/common/resources/deprecated/IdGeneratingResourceFile.java index 90d6d647b9..5434cadfb1 100644 --- a/bridge/tests/src/com/android/ide/common/resources/deprecated/IdGeneratingResourceFile.java +++ b/bridge/tests/src/com/android/ide/common/resources/deprecated/IdGeneratingResourceFile.java @@ -53,7 +53,7 @@ public final class IdGeneratingResourceFile extends ResourceFile private final ResourceValue mFileValue; - public IdGeneratingResourceFile(IAbstractFile file, ResourceFolder folder, ResourceType type) { + public IdGeneratingResourceFile(TestFileWrapper file, ResourceFolder folder, ResourceType type) { super(file, folder); mFileType = type; diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/MultiResourceFile.java b/bridge/tests/src/com/android/ide/common/resources/deprecated/MultiResourceFile.java index 3a511344f5..016c6b4088 100644 --- a/bridge/tests/src/com/android/ide/common/resources/deprecated/MultiResourceFile.java +++ b/bridge/tests/src/com/android/ide/common/resources/deprecated/MultiResourceFile.java @@ -52,7 +52,7 @@ public final class MultiResourceFile extends ResourceFile implements IValueResou private Collection<ResourceType> mResourceTypeList = null; - public MultiResourceFile(IAbstractFile file, ResourceFolder folder) { + public MultiResourceFile(TestFileWrapper file, ResourceFolder folder) { super(file, folder); } diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceFile.java b/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceFile.java index c7eaa81f9a..30fbd0b153 100644 --- a/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceFile.java +++ b/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceFile.java @@ -19,7 +19,6 @@ package com.android.ide.common.resources.deprecated; import com.android.ide.common.rendering.api.ResourceValue; import com.android.ide.common.resources.configuration.Configurable; import com.android.ide.common.resources.configuration.FolderConfiguration; -import com.android.io.IAbstractFile; import com.android.resources.ResourceType; /** @@ -29,10 +28,10 @@ import com.android.resources.ResourceType; @Deprecated public abstract class ResourceFile implements Configurable { - private final IAbstractFile mFile; + private final TestFileWrapper mFile; private final ResourceFolder mFolder; - protected ResourceFile(IAbstractFile file, ResourceFolder folder) { + protected ResourceFile(TestFileWrapper file, ResourceFolder folder) { mFile = file; mFolder = folder; } @@ -48,7 +47,7 @@ public abstract class ResourceFile implements Configurable { /** * Returns the IFile associated with the ResourceFile. */ - public final IAbstractFile getFile() { + public final TestFileWrapper getFile() { return mFile; } diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceFolder.java b/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceFolder.java index fe708f39d2..5fc2c195ec 100644 --- a/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceFolder.java +++ b/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceFolder.java @@ -63,7 +63,7 @@ public final class ResourceFolder implements Configurable { * as a place to stash errors encountered * @return the {@link ResourceFile} that was created. */ - public ResourceFile processFile(IAbstractFile file, ResourceDeltaKind kind, + public ResourceFile processFile(TestFileWrapper file, ResourceDeltaKind kind, ScanningContext context) { // look for this file if it's already been created ResourceFile resFile = getFile(file, context); @@ -84,7 +84,7 @@ public final class ResourceFolder implements Configurable { return resFile; } - private ResourceFile createResourceFile(IAbstractFile file) { + private ResourceFile createResourceFile(TestFileWrapper file) { // check if that's a single or multi resource type folder. We have a special case // for ID generating resource types (layout/menu, and XML drawables, etc.). // MultiResourceFile handles the case when several resource types come from a single file @@ -130,7 +130,7 @@ public final class ResourceFolder implements Configurable { * as a place to stash errors encountered * @return the {@link ResourceFile} or null if no match was found. */ - private ResourceFile getFile(IAbstractFile file, ScanningContext context) { + private ResourceFile getFile(TestFileWrapper file, ScanningContext context) { assert mFolder.equals(file.getParentFolder()); // If the file actually exists, the resource folder may not have been diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceRepository.java b/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceRepository.java index d8204d5411..fca0862922 100644 --- a/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceRepository.java +++ b/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceRepository.java @@ -19,7 +19,6 @@ import com.android.SdkConstants; import com.android.ide.common.rendering.api.ResourceValue; import com.android.ide.common.resources.ResourceValueMap; import com.android.ide.common.resources.configuration.FolderConfiguration; -import com.android.io.IAbstractFile; import com.android.io.IAbstractFolder; import com.android.io.IAbstractResource; import com.android.resources.ResourceFolderType; @@ -40,7 +39,7 @@ import java.util.Map; */ @Deprecated public abstract class ResourceRepository { - private final IAbstractFolder mResourceFolder; + private final TestFolderWrapper mResourceFolder; private Map<ResourceFolderType, List<ResourceFolder>> mFolderMap = new EnumMap<>(ResourceFolderType.class); @@ -58,13 +57,13 @@ public abstract class ResourceRepository { * @param resFolder the resource folder of the repository. * @param isFrameworkRepository whether the repository is for framework resources. */ - protected ResourceRepository(@NotNull IAbstractFolder resFolder, + protected ResourceRepository(@NotNull TestFolderWrapper resFolder, boolean isFrameworkRepository) { mResourceFolder = resFolder; mFrameworkRepository = isFrameworkRepository; } - public IAbstractFolder getResFolder() { + public TestFolderWrapper getResFolder() { return mResourceFolder; } @@ -92,8 +91,8 @@ public abstract class ResourceRepository { IAbstractResource[] resources = mResourceFolder.listMembers(); for (IAbstractResource res : resources) { - if (res instanceof IAbstractFolder) { - IAbstractFolder folder = (IAbstractFolder)res; + if (res instanceof TestFolderWrapper) { + TestFolderWrapper folder = (TestFolderWrapper)res; ResourceFolder resFolder = processFolder(folder); if (resFolder != null) { @@ -101,8 +100,8 @@ public abstract class ResourceRepository { IAbstractResource[] files = folder.listMembers(); for (IAbstractResource fileRes : files) { - if (fileRes instanceof IAbstractFile) { - IAbstractFile file = (IAbstractFile)fileRes; + if (fileRes instanceof TestFileWrapper) { + TestFileWrapper file = (TestFileWrapper) fileRes; resFolder.processFile(file, ResourceDeltaKind.ADDED, context); } @@ -250,7 +249,7 @@ public abstract class ResourceRepository { * @return the ResourceFolder created from this folder, or null if the process failed. */ @Nullable - private ResourceFolder processFolder(@NotNull IAbstractFolder folder) { + private ResourceFolder processFolder(@NotNull TestFolderWrapper folder) { ensureInitialized(); // split the name of the folder in segments. @@ -308,7 +307,7 @@ public abstract class ResourceRepository { return map; } - /** + /** * Loads the resources. */ public void loadResources() { diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/SingleResourceFile.java b/bridge/tests/src/com/android/ide/common/resources/deprecated/SingleResourceFile.java index e7a3f90835..38d975dab4 100644 --- a/bridge/tests/src/com/android/ide/common/resources/deprecated/SingleResourceFile.java +++ b/bridge/tests/src/com/android/ide/common/resources/deprecated/SingleResourceFile.java @@ -42,7 +42,7 @@ public class SingleResourceFile extends ResourceFile { private final ResourceType mType; private final ResourceValue mValue; - public SingleResourceFile(IAbstractFile file, ResourceFolder folder) { + public SingleResourceFile(TestFileWrapper file, ResourceFolder folder) { super(file, folder); // we need to infer the type of the resource from the folder type. diff --git a/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/PressedButton.java b/bridge/tests/src/com/android/ide/common/resources/deprecated/TestFileWrapper.java index 432015725a..f1f3f1743a 100644 --- a/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/PressedButton.java +++ b/bridge/tests/src/com/android/ide/common/resources/deprecated/TestFileWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 The Android Open Source Project + * Copyright (C) 2020 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. @@ -14,18 +14,23 @@ * limitations under the License. */ -package com.android.tools.idea.editors.theme.widgets; +package com.android.ide.common.resources.deprecated; -import android.content.Context; -import android.util.AttributeSet; -import android.widget.Button; +import com.android.io.FileWrapper; +import com.android.io.IAbstractFolder; -@SuppressWarnings("unused") -public class PressedButton extends Button { - public PressedButton(Context context, AttributeSet attrs) { - super(context, attrs); +import java.io.File; - setPressed(true); - jumpDrawablesToCurrentState(); +public class TestFileWrapper extends FileWrapper { + public TestFileWrapper(File file) { + super(file); + } + + public IAbstractFolder getParentFolder() { + String p = this.getParent(); + if (p == null) { + return null; + } + return new TestFolderWrapper(p); } } diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/TestFolderWrapper.java b/bridge/tests/src/com/android/ide/common/resources/deprecated/TestFolderWrapper.java new file mode 100644 index 0000000000..f945d3c650 --- /dev/null +++ b/bridge/tests/src/com/android/ide/common/resources/deprecated/TestFolderWrapper.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2020 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 com.android.ide.common.resources.deprecated; + +import com.android.io.FolderWrapper; +import com.android.io.IAbstractResource; + +import java.io.File; + +public class TestFolderWrapper extends FolderWrapper { + + public TestFolderWrapper(String pathname) { + super(pathname); + } + + public TestFolderWrapper(File file) { + super(file.getAbsolutePath()); + } + + public IAbstractResource[] listMembers() { + File[] files = listFiles(); + final int count = files == null ? 0 : files.length; + IAbstractResource[] afiles = new IAbstractResource[count]; + + if (files != null) { + for (int i = 0 ; i < count ; i++) { + File f = files[i]; + if (f.isFile()) { + afiles[i] = new TestFileWrapper(f); + } else if (f.isDirectory()) { + afiles[i] = new TestFolderWrapper(f); + } + } + } + + return afiles; + } + + public TestFolderWrapper getFolder(String name) { + return new TestFolderWrapper(new File(this, name)); + } +} diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java index e43531a09d..be57b88ade 100644 --- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java +++ b/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java @@ -29,6 +29,7 @@ import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; +import android.content.res.BridgeTypedArrayTest; import android.content.res.Resources_DelegateTest; import android.graphics.Color_DelegateTest; import android.graphics.Matrix_DelegateTest; @@ -47,7 +48,7 @@ import android.util.imagepool.ImagePoolImplTest; BridgeRenderSessionTest.class, ResourceHelperTest.class, BridgeContextTest.class, Resources_DelegateTest.class, Color_DelegateTest.class, ImagePoolHelperTest.class, ImagePoolImplTest.class, HighQualityShadowsRenderTests.class, - LayoutValidatorTests.class, AccessibilityValidatorTests.class + LayoutValidatorTests.class, AccessibilityValidatorTests.class, BridgeTypedArrayTest.class }) public class Main { } diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java b/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java index a22c3bcd88..67bb7af0b9 100644 --- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java +++ b/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java @@ -16,7 +16,7 @@ package com.android.layoutlib.bridge.intensive; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.ide.common.rendering.api.RenderSession; import com.android.ide.common.rendering.api.Result; import com.android.ide.common.rendering.api.SessionParams; @@ -24,7 +24,7 @@ import com.android.ide.common.rendering.api.SessionParams.RenderingMode; import com.android.ide.common.resources.deprecated.FrameworkResources; import com.android.ide.common.resources.deprecated.ResourceItem; import com.android.ide.common.resources.deprecated.ResourceRepository; -import com.android.io.FolderWrapper; +import com.android.ide.common.resources.deprecated.TestFolderWrapper; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.android.RenderParamsFlags; import com.android.layoutlib.bridge.impl.DelegateManager; @@ -115,7 +115,7 @@ public class RenderTestBase { protected static Bridge sBridge; /** List of log messages generated by a render call. It can be used to find specific errors */ protected static ArrayList<String> sRenderMessages = Lists.newArrayList(); - private static LayoutLog sLayoutLibLog; + private static ILayoutLog sLayoutLibLog; private static FrameworkResources sFrameworkRepo; private static ResourceRepository sProjectResources; private static ILogger sLogger; @@ -303,12 +303,12 @@ public class RenderTestBase { public static void beforeClass() { File data_dir = new File(PLATFORM_DIR, "data"); File res = new File(data_dir, "res"); - sFrameworkRepo = new FrameworkResources(new FolderWrapper(res)); + sFrameworkRepo = new FrameworkResources(new TestFolderWrapper(res)); sFrameworkRepo.loadResources(); sFrameworkRepo.loadPublicResources(getLogger()); sProjectResources = - new ResourceRepository(new FolderWrapper(TEST_RES_DIR + "/" + APP_TEST_RES), + new ResourceRepository(new TestFolderWrapper(TEST_RES_DIR + "/" + APP_TEST_RES), false) { @NonNull @Override @@ -433,9 +433,9 @@ public class RenderTestBase { return RenderTestBase.renderAndVerify(params, goldenFileName, -1); } - protected static LayoutLog getLayoutLog() { + protected static ILayoutLog getLayoutLog() { if (sLayoutLibLog == null) { - sLayoutLibLog = new LayoutLog() { + sLayoutLibLog = new ILayoutLog() { @Override public void warning(String tag, String message, Object cookie, Object data) { System.out.println("Warning " + tag + ": " + message); @@ -474,7 +474,7 @@ public class RenderTestBase { } protected static void ignoreAllLogging() { - sLayoutLibLog = new LayoutLog(); + sLayoutLibLog = new ILayoutLog() {}; sLogger = new ILogger() { @Override public void error(Throwable t, String msgFormat, Object... args) { diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java b/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java index a6389acfde..9faa0a64ae 100644 --- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java +++ b/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java @@ -72,7 +72,7 @@ public class LayoutLibTestCallback extends LayoutlibCallback { Class<?> rClass = mModuleClassLoader.loadClass(PACKAGE_NAME + ".R"); Class<?>[] nestedClasses = rClass.getDeclaredClasses(); for (Class<?> resClass : nestedClasses) { - final ResourceType resType = ResourceType.getEnum(resClass.getSimpleName()); + final ResourceType resType = ResourceType.fromClassName(resClass.getSimpleName()); if (resType != null) { for (Field field : resClass.getDeclaredFields()) { diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/SessionParamsBuilder.java b/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/SessionParamsBuilder.java index baadc621ed..396880eb00 100644 --- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/SessionParamsBuilder.java +++ b/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/SessionParamsBuilder.java @@ -19,7 +19,7 @@ package com.android.layoutlib.bridge.intensive.util; import com.android.SdkConstants; import com.android.ide.common.rendering.api.AssetRepository; import com.android.ide.common.rendering.api.IImageFactory; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.ide.common.rendering.api.LayoutlibCallback; import com.android.ide.common.rendering.api.ResourceNamespace; import com.android.ide.common.rendering.api.ResourceReference; @@ -56,7 +56,7 @@ public class SessionParamsBuilder { private LayoutlibCallback mLayoutlibCallback; private int mTargetSdk; private int mMinSdk = 0; - private LayoutLog mLayoutLog; + private ILayoutLog mLayoutLog; private Map<SessionParams.Key, Object> mFlags = new HashMap<>(); private AssetRepository mAssetRepository = null; private boolean mDecor = true; @@ -136,7 +136,7 @@ public class SessionParamsBuilder { } @NonNull - public SessionParamsBuilder setLayoutLog(@NonNull LayoutLog layoutLog) { + public SessionParamsBuilder setLayoutLog(@NonNull ILayoutLog layoutLog) { mLayoutLog = layoutLog; return this; } diff --git a/common/Android.bp b/common/Android.bp index a256ae2f09..b33e75630f 100644 --- a/common/Android.bp +++ b/common/Android.bp @@ -14,6 +14,10 @@ // limitations under the License. // +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + java_library_host { name: "layoutlib-common", diff --git a/create/Android.bp b/create/Android.bp index 44179a9771..0fc219d7c0 100644 --- a/create/Android.bp +++ b/create/Android.bp @@ -14,6 +14,16 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_layoutlib_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + // SPDX-license-identifier-EPL + default_applicable_licenses: ["frameworks_layoutlib_license"], +} + java_binary_host { name: "layoutlib_create", diff --git a/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/create/src/com/android/tools/layoutlib/create/CreateInfo.java index bbe985e55d..44046eb9eb 100644 --- a/create/src/com/android/tools/layoutlib/create/CreateInfo.java +++ b/create/src/com/android/tools/layoutlib/create/CreateInfo.java @@ -168,11 +168,14 @@ public final class CreateInfo implements ICreateInfo { "android.graphics.drawable.GradientDrawable#buildRing", "android.graphics.drawable.AdaptiveIconDrawable#<init>", "android.graphics.drawable.DrawableInflater#inflateFromClass", + "android.graphics.drawable.NinePatchDrawable#getOpacity", "android.graphics.FontFamily#addFont", + "com.google.android.apps.common.testing.accessibility.framework.uielement" + + ".AccessibilityHierarchyAndroid$ViewElementClassNamesAndroid#getClassByName", "android.graphics.Typeface#create", "android.graphics.Typeface$Builder#createAssetUid", "android.graphics.fonts.Font$Builder#createBuffer", - "android.graphics.fonts.SystemFonts#buildSystemFallback", + "android.graphics.fonts.SystemFonts#getSystemFontConfigInternal", "android.os.Binder#getNativeBBinderHolder", "android.os.Binder#getNativeFinalizer", "android.os.Handler#sendMessageAtTime", @@ -314,6 +317,7 @@ public final class CreateInfo implements ICreateInfo { "android.os.ServiceManager", "android.os._Original_ServiceManager", "android.view.textservice.TextServicesManager", "android.view.textservice._Original_TextServicesManager", "android.view.SurfaceView", "android.view._Original_SurfaceView", + "android.view.WindowManagerImpl", "android.view._Original_WindowManagerImpl", "android.view.accessibility.AccessibilityManager", "android.view.accessibility._Original_AccessibilityManager", "android.view.accessibility.AccessibilityNodeIdManager", "android.view.accessibility._Original_AccessibilityNodeIdManager", "android.webkit.WebView", "android.webkit._Original_WebView", diff --git a/create/src/com/android/tools/layoutlib/create/Main.java b/create/src/com/android/tools/layoutlib/create/Main.java index b56416e5aa..4acc754d42 100644 --- a/create/src/com/android/tools/layoutlib/create/Main.java +++ b/create/src/com/android/tools/layoutlib/create/Main.java @@ -129,7 +129,9 @@ public class Main { "android.app.DatePickerDialog", // b.android.com/28318 "android.app.TimePickerDialog", // b.android.com/61515 "com.android.internal.view.menu.ActionMenu", + "libcore.icu.ICU", // needed by ICU_Delegate in LayoutLib "android.icu.**", // needed by LayoutLib + "libcore.io.*", // needed to load /usr/share/zoneinfo "android.annotation.NonNull", // annotations "android.annotation.Nullable", // annotations "com.android.internal.transition.EpicenterTranslateClipReveal", diff --git a/create/src/com/android/tools/layoutlib/java/System_Delegate.java b/create/src/com/android/tools/layoutlib/java/System_Delegate.java index be937445c3..335f566cd4 100644 --- a/create/src/com/android/tools/layoutlib/java/System_Delegate.java +++ b/create/src/com/android/tools/layoutlib/java/System_Delegate.java @@ -22,7 +22,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; /** - * Provides dummy implementation of methods that don't exist on the host VM. + * Provides alternative implementations of methods that don't exist on the host VM. * This also providers a time control that allows to set a specific system time. * * @see ReplaceMethodCallsAdapter diff --git a/create/tests/Android.bp b/create/tests/Android.bp index c765707175..31fbe22abd 100644 --- a/create/tests/Android.bp +++ b/create/tests/Android.bp @@ -12,6 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_layoutlib_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + // SPDX-license-identifier-EPL + default_applicable_licenses: ["frameworks_layoutlib_license"], +} + java_test_host { name: "layoutlib-create-tests", diff --git a/create/tests/res/data/mock_android.jar b/create/tests/res/data/mock_android.jar Binary files differindex 580e6f1693..3fd699920d 100644 --- a/create/tests/res/data/mock_android.jar +++ b/create/tests/res/data/mock_android.jar diff --git a/create/tests/res/mock_data/mock_android/dummy/DummyClass.java b/create/tests/res/mock_data/mock_android/fake/FakeClass.java index de3b0e0ebd..c8b01465ac 100644 --- a/create/tests/res/mock_data/mock_android/dummy/DummyClass.java +++ b/create/tests/res/mock_data/mock_android/fake/FakeClass.java @@ -14,8 +14,8 @@ * limitations under the License. */ -package mock_android.dummy; +package mock_android.fake; -public class DummyClass { +public class FakeClass { }
\ No newline at end of file diff --git a/create/tests/res/mock_data/mock_android/dummy/InnerTest.java b/create/tests/res/mock_data/mock_android/fake/InnerTest.java index d3a1d05b98..254b35dc24 100644 --- a/create/tests/res/mock_data/mock_android/dummy/InnerTest.java +++ b/create/tests/res/mock_data/mock_android/fake/InnerTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package mock_android.dummy; +package mock_android.fake; import java.util.ArrayList; import java.util.Collection; diff --git a/create/tests/res/mock_data/mock_android/dummy/subpackage/SubpackageClassA.java b/create/tests/res/mock_data/mock_android/fake/subpackage/SubpackageClassA.java index eaf1302d25..3381c8dceb 100644 --- a/create/tests/res/mock_data/mock_android/dummy/subpackage/SubpackageClassA.java +++ b/create/tests/res/mock_data/mock_android/fake/subpackage/SubpackageClassA.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package mock_android.dummy.subpackage; +package mock_android.fake.subpackage; public class SubpackageClassA { diff --git a/create/tests/res/mock_data/mock_android/dummy/subpackage/SubpackageClassB.java b/create/tests/res/mock_data/mock_android/fake/subpackage/SubpackageClassB.java index 7f67db1094..5567b08a15 100644 --- a/create/tests/res/mock_data/mock_android/dummy/subpackage/SubpackageClassB.java +++ b/create/tests/res/mock_data/mock_android/fake/subpackage/SubpackageClassB.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package mock_android.dummy.subpackage; +package mock_android.fake.subpackage; public class SubpackageClassB { diff --git a/create/tests/res/mock_data/mock_android/dummy/subpackage/SubpackageClassC.java b/create/tests/res/mock_data/mock_android/fake/subpackage/SubpackageClassC.java index e45643224e..dac163303d 100644 --- a/create/tests/res/mock_data/mock_android/dummy/subpackage/SubpackageClassC.java +++ b/create/tests/res/mock_data/mock_android/fake/subpackage/SubpackageClassC.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package mock_android.dummy.subpackage; +package mock_android.fake.subpackage; public class SubpackageClassC { public static class StaticInnerClass { diff --git a/create/tests/res/mock_data/mock_android/dummy2/DummyClass.java b/create/tests/res/mock_data/mock_android/fake2/FakeClass.java index 9f7cfde11a..e1496b0238 100644 --- a/create/tests/res/mock_data/mock_android/dummy2/DummyClass.java +++ b/create/tests/res/mock_data/mock_android/fake2/FakeClass.java @@ -14,8 +14,8 @@ * limitations under the License. */ -package mock_android.dummy2; +package mock_android.fake2; -public class DummyClass { +public class FakeClass { }
\ No newline at end of file diff --git a/create/tests/res/mock_data/mock_android/dummy2/keep/DoNotRemove.java b/create/tests/res/mock_data/mock_android/fake2/keep/DoNotRemove.java index 8a232a6e82..2e4fa9c2fb 100644 --- a/create/tests/res/mock_data/mock_android/dummy2/keep/DoNotRemove.java +++ b/create/tests/res/mock_data/mock_android/fake2/keep/DoNotRemove.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package mock_android.dummy2.keep; +package mock_android.fake2.keep; public class DoNotRemove { diff --git a/create/tests/src/com/android/tools/layoutlib/create/AsmAnalyzerTest.java b/create/tests/src/com/android/tools/layoutlib/create/AsmAnalyzerTest.java index c2372b73b3..327bbb7615 100644 --- a/create/tests/src/com/android/tools/layoutlib/create/AsmAnalyzerTest.java +++ b/create/tests/src/com/android/tools/layoutlib/create/AsmAnalyzerTest.java @@ -66,22 +66,22 @@ public class AsmAnalyzerTest { getDefaultAnalyzer().parseZip(MOCK_ANDROID_JAR, map, filesFound); assertArrayEquals(new String[] { - "mock_android.dummy.DummyClass", - "mock_android.dummy.InnerTest", - "mock_android.dummy.InnerTest$1", - "mock_android.dummy.InnerTest$DerivingClass", - "mock_android.dummy.InnerTest$MyGenerics1", - "mock_android.dummy.InnerTest$MyIntEnum", - "mock_android.dummy.InnerTest$MyStaticInnerClass", - "mock_android.dummy.InnerTest$NotStaticInner1", - "mock_android.dummy.InnerTest$NotStaticInner2", - "mock_android.dummy.subpackage.SubpackageClassA", - "mock_android.dummy.subpackage.SubpackageClassB", - "mock_android.dummy.subpackage.SubpackageClassC", - "mock_android.dummy.subpackage.SubpackageClassC$InnerClass", - "mock_android.dummy.subpackage.SubpackageClassC$StaticInnerClass", - "mock_android.dummy2.DummyClass", - "mock_android.dummy2.keep.DoNotRemove", + "mock_android.fake.FakeClass", + "mock_android.fake.InnerTest", + "mock_android.fake.InnerTest$1", + "mock_android.fake.InnerTest$DerivingClass", + "mock_android.fake.InnerTest$MyGenerics1", + "mock_android.fake.InnerTest$MyIntEnum", + "mock_android.fake.InnerTest$MyStaticInnerClass", + "mock_android.fake.InnerTest$NotStaticInner1", + "mock_android.fake.InnerTest$NotStaticInner2", + "mock_android.fake.subpackage.SubpackageClassA", + "mock_android.fake.subpackage.SubpackageClassB", + "mock_android.fake.subpackage.SubpackageClassC", + "mock_android.fake.subpackage.SubpackageClassC$InnerClass", + "mock_android.fake.subpackage.SubpackageClassC$StaticInnerClass", + "mock_android.fake2.FakeClass", + "mock_android.fake2.keep.DoNotRemove", "mock_android.util.EmptyArray", "mock_android.util.NotNeeded", "mock_android.view.View", @@ -122,29 +122,29 @@ public class AsmAnalyzerTest { AsmAnalyzer analyzer = new AsmAnalyzer(new MockLog(), MOCK_ANDROID_JAR, null, new String[] { "mock_android.util.EmptyArray", // Single class select - "mock_android.dummy.**", // Multi package select - "mock_android.dummy2.*", // Exclude subpackages select + "mock_android.fake.**", // Multi package select + "mock_android.fake2.*", // Exclude subpackages select }, DEFAULT_EXCLUDES, DEFAULT_INCLUDE_FILES); Result result = analyzer.analyze(); assertArrayEquals(new String[] { - "mock_android.dummy.DummyClass", - "mock_android.dummy.InnerTest$MyIntEnum", + "mock_android.fake.InnerTest$NotStaticInner1", + "mock_android.fake.FakeClass", "mock_android.util.EmptyArray", - "mock_android.dummy.InnerTest$DerivingClass", - "mock_android.dummy2.DummyClass", - "mock_android.dummy.subpackage.SubpackageClassC$InnerClass", - "mock_android.dummy.InnerTest$MyGenerics1", - "mock_android.dummy.subpackage.SubpackageClassC$StaticInnerClass", - "mock_android.dummy.InnerTest$MyStaticInnerClass", - "mock_android.dummy.InnerTest$NotStaticInner1", - "mock_android.dummy.InnerTest$NotStaticInner2", - "mock_android.dummy.subpackage.SubpackageClassA", - "mock_android.dummy.InnerTest", - "mock_android.dummy.InnerTest$1", - "mock_android.dummy.subpackage.SubpackageClassC", - "mock_android.dummy.subpackage.SubpackageClassB", + "mock_android.fake2.FakeClass", + "mock_android.fake.InnerTest$DerivingClass", + "mock_android.fake.InnerTest$NotStaticInner2", + "mock_android.fake.subpackage.SubpackageClassC$InnerClass", + "mock_android.fake.InnerTest$MyGenerics1", + "mock_android.fake.InnerTest$MyIntEnum", + "mock_android.fake.InnerTest$MyStaticInnerClass", + "mock_android.fake.InnerTest", + "mock_android.fake.subpackage.SubpackageClassB", + "mock_android.fake.subpackage.SubpackageClassA", + "mock_android.fake.InnerTest$1", + "mock_android.fake.subpackage.SubpackageClassC$StaticInnerClass", + "mock_android.fake.subpackage.SubpackageClassC", }, result.getFound().keySet().toArray()); } diff --git a/create/tests/src/com/android/tools/layoutlib/create/AsmGeneratorTest.java b/create/tests/src/com/android/tools/layoutlib/create/AsmGeneratorTest.java index 0d6e5d97f9..3f5e8f6306 100644 --- a/create/tests/src/com/android/tools/layoutlib/create/AsmGeneratorTest.java +++ b/create/tests/src/com/android/tools/layoutlib/create/AsmGeneratorTest.java @@ -215,8 +215,8 @@ public class AsmGeneratorTest { @Override public String[] getExcludedClasses() { return new String[] { - "mock_android.dummy2.*", - "mock_android.dummy.**", + "mock_android.fake2.*", + "mock_android.fake.**", "mock_android.util.NotNeeded", JAVA_CLASS_NAME }; @@ -235,10 +235,10 @@ public class AsmGeneratorTest { }); agen.setAnalysisResult(aa.analyze()); Map<String, byte[]> output = agen.generate(); - // Everything in .dummy.** should be filtered - // Only things is .dummy2.* should be filtered + // Everything in .fake.** should be filtered + // Only things is .fake2.* should be filtered assertArrayEquals(new String[] { - "mock_android.dummy2.keep.DoNotRemove", + "mock_android.fake2.keep.DoNotRemove", "mock_android.util.EmptyArray", "mock_android.view.View", "mock_android.view.ViewGroup", diff --git a/create/tests/src/com/android/tools/layoutlib/create/ClassHasNativeVisitorTest.java b/create/tests/src/com/android/tools/layoutlib/create/ClassHasNativeVisitorTest.java index f3dc876fa3..86228821a8 100644 --- a/create/tests/src/com/android/tools/layoutlib/create/ClassHasNativeVisitorTest.java +++ b/create/tests/src/com/android/tools/layoutlib/create/ClassHasNativeVisitorTest.java @@ -76,7 +76,7 @@ public class ClassHasNativeVisitorTest { } /** - * Dummy test class with a native method. + * Fake test class with a native method. */ public static class ClassWithNative { public ClassWithNative() { @@ -90,7 +90,7 @@ public class ClassHasNativeVisitorTest { } /** - * Dummy test class with no native method. + * Fake test class with no native method. */ public static class ClassWithoutNative { public ClassWithoutNative() { diff --git a/create/tests/src/com/android/tools/layoutlib/create/StubMethodAdapterTest.java b/create/tests/src/com/android/tools/layoutlib/create/StubMethodAdapterTest.java index a7f156b3b2..3782173999 100644 --- a/create/tests/src/com/android/tools/layoutlib/create/StubMethodAdapterTest.java +++ b/create/tests/src/com/android/tools/layoutlib/create/StubMethodAdapterTest.java @@ -38,7 +38,7 @@ public class StubMethodAdapterTest { private static final String STUB_CLASS_NAME = StubClass.class.getName(); /** - * Load a dummy class, stub one of its method and ensure that the modified class works as + * Load a mock class, stub one of its method and ensure that the modified class works as * intended. */ @Test diff --git a/create/tests/src/com/android/tools/layoutlib/create/dataclass/ClassWithNative.java b/create/tests/src/com/android/tools/layoutlib/create/dataclass/ClassWithNative.java index 6867ec0b55..f7f9535edf 100644 --- a/create/tests/src/com/android/tools/layoutlib/create/dataclass/ClassWithNative.java +++ b/create/tests/src/com/android/tools/layoutlib/create/dataclass/ClassWithNative.java @@ -19,7 +19,7 @@ package com.android.tools.layoutlib.create.dataclass; import com.android.tools.layoutlib.create.DelegateClassAdapterTest; /** - * Dummy test class with a native method. + * Fake test class with a native method. * The native method is not defined and any attempt to invoke it will * throw an {@link UnsatisfiedLinkError}. * diff --git a/remote/client/src/com/android/layoutlib/bridge/remote/client/RemoteBridgeClient.java b/remote/client/src/com/android/layoutlib/bridge/remote/client/RemoteBridgeClient.java index 051fb8529a..d63c9f6b87 100644 --- a/remote/client/src/com/android/layoutlib/bridge/remote/client/RemoteBridgeClient.java +++ b/remote/client/src/com/android/layoutlib/bridge/remote/client/RemoteBridgeClient.java @@ -18,12 +18,11 @@ package com.android.layoutlib.bridge.remote.client; import com.android.ide.common.rendering.api.Bridge; import com.android.ide.common.rendering.api.DrawableParams; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.ide.common.rendering.api.RenderSession; import com.android.ide.common.rendering.api.Result; import com.android.ide.common.rendering.api.SessionParams; import com.android.layout.remote.api.RemoteBridge; -import com.android.layout.remote.api.RemoteDrawableParams; import com.android.layout.remote.api.RemoteSessionParams; import com.android.layoutlib.bridge.remote.client.adapters.RemoteDrawableParamsAdapter; import com.android.layoutlib.bridge.remote.client.adapters.RemoteLayoutLogAdapter; @@ -60,7 +59,7 @@ public class RemoteBridgeClient extends Bridge { String nativeLibPath, String icuDataPath, Map<String, Map<String, Integer>> enumValueMap, - LayoutLog log) { + ILayoutLog log) { try { return mDelegate.init(platformProperties, fontLocation, nativeLibPath, icuDataPath, enumValueMap, RemoteLayoutLogAdapter.create(log)); diff --git a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteLayoutLogAdapter.java b/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteLayoutLogAdapter.java index 23d36bc208..2ea91023e8 100644 --- a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteLayoutLogAdapter.java +++ b/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteLayoutLogAdapter.java @@ -16,7 +16,7 @@ package com.android.layoutlib.bridge.remote.client.adapters; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layout.remote.api.RemoteLayoutLog; import com.android.tools.layoutlib.annotations.NotNull; @@ -25,13 +25,13 @@ import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; public class RemoteLayoutLogAdapter implements RemoteLayoutLog { - private final LayoutLog mLog; + private final ILayoutLog mLog; - private RemoteLayoutLogAdapter(@NotNull LayoutLog log) { + private RemoteLayoutLogAdapter(@NotNull ILayoutLog log) { mLog = log; } - public static RemoteLayoutLog create(@NotNull LayoutLog log) throws RemoteException { + public static RemoteLayoutLog create(@NotNull ILayoutLog log) throws RemoteException { return (RemoteLayoutLog) UnicastRemoteObject.exportObject(new RemoteLayoutLogAdapter(log), 0); } @@ -56,4 +56,9 @@ public class RemoteLayoutLogAdapter implements RemoteLayoutLog { public void error(String tag, String message, Throwable throwable, Object viewCookie, Serializable data) { mLog.error(tag, message, throwable, viewCookie, null); } + + @Override + public void logAndroidFramework(int priority, String tag, String message) { + mLog.logAndroidFramework(priority, tag, message); + } } diff --git a/remote/common/src/com/android/layout/remote/api/RemoteBridge.java b/remote/common/src/com/android/layout/remote/api/RemoteBridge.java index 3634fff756..4ef9d9751a 100644 --- a/remote/common/src/com/android/layout/remote/api/RemoteBridge.java +++ b/remote/common/src/com/android/layout/remote/api/RemoteBridge.java @@ -17,7 +17,7 @@ package com.android.layout.remote.api; import com.android.ide.common.rendering.api.Bridge; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.ide.common.rendering.api.RenderSession; import com.android.ide.common.rendering.api.Result; import com.android.tools.layoutlib.annotations.NotNull; @@ -43,7 +43,7 @@ public interface RemoteBridge extends Remote { * @param icuDataPath the location of the ICU data used natively. * @param enumValueMap map attrName ⇒ { map enumFlagName ⇒ Integer value }. This is typically * read from attrs.xml in the SDK target. - * @param log a {@link LayoutLog} object. Can be null. + * @param log a {@link ILayoutLog} object. Can be null. * * @return true if success. */ diff --git a/remote/common/src/com/android/layout/remote/api/RemoteLayoutLog.java b/remote/common/src/com/android/layout/remote/api/RemoteLayoutLog.java index 01add5398a..335cf9dbe6 100644 --- a/remote/common/src/com/android/layout/remote/api/RemoteLayoutLog.java +++ b/remote/common/src/com/android/layout/remote/api/RemoteLayoutLog.java @@ -16,14 +16,14 @@ package com.android.layout.remote.api; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import java.io.Serializable; import java.rmi.Remote; import java.rmi.RemoteException; /** - * Remote version of the {@link LayoutLog} class + * Remote version of the {@link ILayoutLog} class */ public interface RemoteLayoutLog extends Remote { /** @@ -72,4 +72,13 @@ public interface RemoteLayoutLog extends Remote { */ void error(String tag, String message, Throwable throwable, Object viewCookie, Serializable data) throws RemoteException; + + /** + * Logs messages coming from the Android Framework. + * + * @param priority the priority level of the message + * @param tag a tag describing the type of the error + * @param message the message of the error + */ + void logAndroidFramework(int priority, String tag, String message) throws RemoteException; } diff --git a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteLayoutLogAdapter.java b/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteLayoutLogAdapter.java index 90da0832f9..5c48aef252 100644 --- a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteLayoutLogAdapter.java +++ b/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteLayoutLogAdapter.java @@ -16,13 +16,13 @@ package com.android.layoutlib.bridge.remote.server.adapters; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.layout.remote.api.RemoteLayoutLog; import com.android.tools.layoutlib.annotations.NotNull; import java.rmi.RemoteException; -public class RemoteLayoutLogAdapter extends LayoutLog { +public class RemoteLayoutLogAdapter implements ILayoutLog { private final RemoteLayoutLog mLog; public RemoteLayoutLogAdapter(@NotNull RemoteLayoutLog log) { @@ -66,4 +66,13 @@ public class RemoteLayoutLogAdapter extends LayoutLog { throw new RuntimeException(e); } } + + @Override + public void logAndroidFramework(int priority, String tag, String message) { + try { + mLog.logAndroidFramework(priority, tag, message); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } } diff --git a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteRenderResourcesAdapter.java b/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteRenderResourcesAdapter.java index 2e19bf7422..0b9797a770 100644 --- a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteRenderResourcesAdapter.java +++ b/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteRenderResourcesAdapter.java @@ -16,7 +16,7 @@ package com.android.layoutlib.bridge.remote.server.adapters; -import com.android.ide.common.rendering.api.LayoutLog; +import com.android.ide.common.rendering.api.ILayoutLog; import com.android.ide.common.rendering.api.RenderResources; import com.android.ide.common.rendering.api.ResourceReference; import com.android.ide.common.rendering.api.ResourceValue; @@ -37,7 +37,7 @@ public class RemoteRenderResourcesAdapter extends RenderResources { } @Override - public void setLogger(LayoutLog logger) { + public void setLogger(ILayoutLog logger) { // Ignored for remote operations. } diff --git a/rename_font/build_font.py b/rename_font/build_font.py index a53ebbc25c..db0c98a3fe 100755 --- a/rename_font/build_font.py +++ b/rename_font/build_font.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (C) 2014 The Android Open Source Project # @@ -96,7 +96,7 @@ def main(argv): def convert_font(input_path): filename = os.path.basename(input_path) - print 'Converting font: ' + filename + print('Converting font: ' + filename) # the path to the output file. The file name is the fontfilename.ttx ttx_path = os.path.join(dest_dir, filename) ttx_path = ttx_path[:-1] + 'x' @@ -116,11 +116,11 @@ def convert_font(input_path): ttx.main(ttx_args) except InvalidFontException: # In case of invalid fonts, we exit. - print filename + ' is not a valid font' + print(filename + ' is not a valid font') raise except Exception as e: - print 'Error converting font: ' + filename - print e + print('Error converting font: ' + filename) + print(e) # Some fonts are too big to be handled by the ttx library. # Just copy paste them. shutil.copy(input_path, dest_dir) @@ -136,7 +136,7 @@ def get_font_info(tag): found in the name table of the font. """ fonts = [] font = None - last_name_id = sys.maxint + last_name_id = sys.maxsize for namerecord in tag.iter('namerecord'): if 'nameID' in namerecord.attrib: name_id = int(namerecord.attrib['nameID']) @@ -164,14 +164,14 @@ def get_font_info(tag): def update_tag(tag, fonts): - last_name_id = sys.maxint + last_name_id = sys.maxsize fonts_iterator = fonts.__iter__() font = None for namerecord in tag.iter('namerecord'): if 'nameID' in namerecord.attrib: name_id = int(namerecord.attrib['nameID']) if name_id <= last_name_id: - font = fonts_iterator.next() + font = next(fonts_iterator) font = update_font_name(font) last_name_id = name_id if name_id == NAMEID_FAMILY: @@ -192,7 +192,7 @@ def update_font_name(font): new_family = font.family + font.version else: new_family = font.family - if font.style is 'Regular' and not font.ends_in_regular: + if font.style == 'Regular' and not font.ends_in_regular: font.fullname = new_family else: font.fullname = new_family + ' ' + font.style @@ -205,7 +205,7 @@ def ends_in_regular(string): 'Regular' for plain fonts. However, some fonts don't obey this rule. We keep the style info, to minimize the diff. """ string = string.strip().split()[-1] - return string is 'Regular' + return string == 'Regular' def get_version(string): diff --git a/rename_font/build_font_single.py b/rename_font/build_font_single.py index 22d7fdf1a0..b25407241f 100755 --- a/rename_font/build_font_single.py +++ b/rename_font/build_font_single.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (C) 2014 The Android Open Source Project # @@ -71,7 +71,7 @@ EXTENSIONS = ['.ttf', '.ttc', '.otf', '.xml'] def main(argv): if len(argv) < 2: - print 'Incorrect usage: ' + str(argv) + print('Incorrect usage: ' + str(argv)) sys.exit('Usage: build_font_single.py /path/to/input/font.ttf /path/to/out/font.ttf') dest_path = argv[-1] input_path = argv[0] @@ -85,7 +85,7 @@ def main(argv): def convert_font(input_path, dest_path): filename = os.path.basename(input_path) - print 'Converting font: ' + filename + print('Converting font: ' + filename) # the path to the output file. The file name is the fontfilename.ttx ttx_path = dest_path[:-1] + 'x' try: @@ -104,11 +104,11 @@ def convert_font(input_path, dest_path): ttx.main(ttx_args) except InvalidFontException: # assume, like for .ttc and .otf that font might be valid, but warn. - print 'Family and/or Style nameIDs not found in '+ filename + print('Family and/or Style nameIDs not found in '+ filename) shutil.copy(input_path, dest_path) except Exception as e: - print 'Error converting font: ' + filename - print e + print('Error converting font: ' + filename) + print(e) # Some fonts are too big to be handled by the ttx library. # Just copy paste them. shutil.copy(input_path, dest_path) @@ -124,7 +124,7 @@ def get_font_info(tag): found in the name table of the font. """ fonts = [] font = None - last_name_id = sys.maxint + last_name_id = sys.maxsize for namerecord in tag.iter('namerecord'): if 'nameID' in namerecord.attrib: name_id = int(namerecord.attrib['nameID']) @@ -155,7 +155,7 @@ def get_font_info(tag): def update_tag(tag, fonts): - last_name_id = sys.maxint + last_name_id = sys.maxsize fonts_iterator = fonts.__iter__() font = None for namerecord in tag.iter('namerecord'): @@ -165,7 +165,7 @@ def update_tag(tag, fonts): if name_id < NAMEID_LIST_MIN or name_id > NAMEID_LIST_MAX: continue if name_id <= last_name_id: - font = fonts_iterator.next() + font = next(fonts_iterator) font = update_font_name(font) last_name_id = name_id if name_id == NAMEID_FAMILY: @@ -186,7 +186,7 @@ def update_font_name(font): new_family = font.family + font.version else: new_family = font.family - if font.style is 'Regular' and not font.ends_in_regular: + if font.style == 'Regular' and not font.ends_in_regular: font.fullname = new_family else: font.fullname = new_family + ' ' + font.style @@ -199,7 +199,7 @@ def ends_in_regular(string): 'Regular' for plain fonts. However, some fonts don't obey this rule. We keep the style info, to minimize the diff. """ string = string.strip().split()[-1] - return string is 'Regular' + return string == 'Regular' def get_version(string): diff --git a/rename_font/test.py b/rename_font/test.py index 2ffddf4b3c..cf26ee9780 100755 --- a/rename_font/test.py +++ b/rename_font/test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """Tests build_font.py by renaming a font. @@ -22,10 +22,10 @@ class MyTest(unittest.TestCase): def test(self): font_name = "Roboto-Regular.ttf" srcdir = tempfile.mkdtemp() - print "srcdir: " + srcdir + print("srcdir: " + srcdir) shutil.copy(font_name, srcdir) destdir = tempfile.mkdtemp() - print "destdir: " + destdir + print("destdir: " + destdir) self.assertTrue(build_font.main([srcdir, destdir]) is None) out_path = os.path.join(destdir, font_name) ttx.main([out_path]) diff --git a/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ErrorCatcher.java b/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ErrorCatcher.java deleted file mode 100644 index 519b12714d..0000000000 --- a/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ErrorCatcher.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2015 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 com.android.tools.idea.editors.theme.widgets; - -import com.android.ide.common.rendering.api.LayoutLog; -import com.android.layoutlib.bridge.Bridge; - -import android.content.Context; -import android.graphics.Canvas; -import android.util.AttributeSet; -import android.view.View; -import android.view.ViewGroup; - -/** - * {@link ViewGroup} that wraps another view and catches any possible exceptions that the child view - * might generate. - * This is used by the theme editor to stop custom views from breaking the preview. - */ -// TODO: This view is just a temporary solution that will be replaced by adding a try / catch -// for custom views in the ClassConverter -public class ErrorCatcher extends ViewGroup { - public ErrorCatcher(Context context) { - super(context); - } - - public ErrorCatcher(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public ErrorCatcher(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - public ErrorCatcher(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - assert getChildCount() == 1 : "ErrorCatcher can only have one child"; - - View child = getChildAt(0); - try { - measureChild(child, widthMeasureSpec, heightMeasureSpec); - - setMeasuredDimension(resolveSize(child.getMeasuredWidth(), widthMeasureSpec), - resolveSize(child.getMeasuredHeight(), heightMeasureSpec)); - } catch (Throwable t) { - Bridge.getLog().warning(LayoutLog.TAG_BROKEN, "Failed to do onMeasure for view " + - child.getClass().getCanonicalName(), null, t); - setMeasuredDimension(resolveSize(0, widthMeasureSpec), - resolveSize(0, heightMeasureSpec)); - } - } - - @Override - protected boolean drawChild(Canvas canvas, View child, long drawingTime) { - try { - return super.drawChild(canvas, child, drawingTime); - } catch (Throwable t) { - Bridge.getLog().warning(LayoutLog.TAG_BROKEN, "Failed to draw for view " + - child.getClass().getCanonicalName(), null, t); - } - - return false; - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - assert getChildCount() == 1 : "ErrorCatcher can only have one child"; - - View child = getChildAt(0); - try { - child.layout(0, 0, child.getMeasuredWidth(), child.getMeasuredHeight()); - } catch (Throwable e) { - Bridge.getLog().warning(LayoutLog.TAG_BROKEN, "Failed to do onLayout for view " + - child.getClass().getCanonicalName(), null, e); - } - } -} diff --git a/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ThemePreviewLayout.java b/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ThemePreviewLayout.java deleted file mode 100644 index af89910f7c..0000000000 --- a/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ThemePreviewLayout.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (C) 2015 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 com.android.tools.idea.editors.theme.widgets; - -import android.content.Context; -import android.util.AttributeSet; -import android.util.DisplayMetrics; -import android.util.TypedValue; -import android.view.View; -import android.view.ViewGroup; - -/** - * Custom layout used in the theme editor to display the component preview. It arranges the child - * Views as a grid of cards. - * <p/> - * The Views are measured and the maximum width and height are used to dimension all the child - * components. Any margin attributes from the children are ignored and only the item_margin element - * is used. - */ -@SuppressWarnings("unused") -public class ThemePreviewLayout extends ViewGroup { - private final int mMaxColumns; - private final int mMaxColumnWidth; - private final int mMinColumnWidth; - private final int mItemHorizontalMargin; - private final int mItemVerticalMargin; - - /** Item width to use for every card component. This includes margins. */ - private int mItemWidth; - /** Item height to use for every card component. This includes margins. */ - private int mItemHeight; - - /** Calculated number of columns */ - private int mNumColumns; - - public ThemePreviewLayout(Context context) { - this(context, null); - } - - public ThemePreviewLayout(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public ThemePreviewLayout(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - - if (attrs == null) { - mMaxColumnWidth = Integer.MAX_VALUE; - mMinColumnWidth = 0; - mMaxColumns = Integer.MAX_VALUE; - mItemHorizontalMargin = 0; - mItemVerticalMargin = 0; - return; - } - - DisplayMetrics dm = getResources().getDisplayMetrics(); - int maxColumnWidth = attrs.getAttributeIntValue(null, "max_column_width", Integer - .MAX_VALUE); - int minColumnWidth = attrs.getAttributeIntValue(null, "min_column_width", 0); - int itemHorizontalMargin = attrs.getAttributeIntValue(null, "item_horizontal_margin", 0); - int itemVerticalMargin = attrs.getAttributeIntValue(null, "item_vertical_margin", 0); - - mMaxColumnWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, - maxColumnWidth, - dm); - mMinColumnWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, - minColumnWidth, - dm); - mItemHorizontalMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, - itemHorizontalMargin, - dm); - mItemVerticalMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, - itemVerticalMargin, - dm); - mMaxColumns = attrs.getAttributeIntValue(null, "max_columns", Integer.MAX_VALUE); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - // Measure the column size. - // The column has a minimum width that will be used to calculate the maximum number of - // columns that we can fit in the available space. - // - // Once we have the maximum number of columns, we will span all columns width evenly to fill - // all the available space. - int wSize = MeasureSpec.getSize(widthMeasureSpec) - mPaddingLeft - mPaddingRight; - - // Calculate the desired width of all columns and take the maximum. - // This step can be skipped if we have a fixed column height so we do not have to - // dynamically calculate it. - int childWidthSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - int childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - int itemWidth = 0; - int itemHeight = 0; - for (int i = 0; i < getChildCount(); i++) { - View v = getChildAt(i); - - if (v.getVisibility() == GONE) { - continue; - } - - measureChild(v, childWidthSpec, childHeightSpec); - - itemWidth = Math.max(itemWidth, v.getMeasuredWidth()); - itemHeight = Math.max(itemHeight, v.getMeasuredHeight()); - } - - itemWidth = Math.min(Math.max(itemWidth, mMinColumnWidth), mMaxColumnWidth); - mNumColumns = Math.min((int) Math.ceil((double) wSize / itemWidth), mMaxColumns); - - // Check how much space this distribution would take taking into account the margins. - // If it's bigger than what we have, remove one column. - int wSizeNeeded = mNumColumns * itemWidth + (mNumColumns - 1) * mItemHorizontalMargin; - if (wSizeNeeded > wSize && mNumColumns > 1) { - mNumColumns--; - } - - if (getChildCount() < mNumColumns) { - mNumColumns = getChildCount(); - } - if (mNumColumns == 0) { - mNumColumns = 1; - } - - // Inform each child of the measurement - childWidthSpec = MeasureSpec.makeMeasureSpec(itemWidth, MeasureSpec.EXACTLY); - childHeightSpec = MeasureSpec.makeMeasureSpec(itemHeight, MeasureSpec.EXACTLY); - for (int i = 0; i < getChildCount(); i++) { - View v = getChildAt(i); - - if (v.getVisibility() == GONE) { - continue; - } - - measureChild(v, childWidthSpec, childHeightSpec); - } - - // Calculate the height of the first column to measure our own size - int firstColumnItems = getChildCount() / mNumColumns + ((getChildCount() % mNumColumns) > 0 - ? 1 : 0); - - int horizontalMarginsTotalWidth = (mNumColumns - 1) * mItemHorizontalMargin; - int verticalMarginsTotalHeight = (firstColumnItems - 1) * mItemVerticalMargin; - int totalWidth = mNumColumns * itemWidth + horizontalMarginsTotalWidth + - mPaddingRight + mPaddingLeft; - int totalHeight = firstColumnItems * itemHeight + verticalMarginsTotalHeight + - mPaddingBottom + mPaddingTop; - - setMeasuredDimension(resolveSize(totalWidth, widthMeasureSpec), - resolveSize(totalHeight, heightMeasureSpec)); - - mItemWidth = itemWidth; - mItemHeight = itemHeight; - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - int itemsPerColumn = getChildCount() / mNumColumns; - // The remainder items are distributed one per column. - int remainderItems = getChildCount() % mNumColumns; - - int x = mPaddingLeft; - int y = mPaddingTop; - int position = 1; - for (int i = 0; i < getChildCount(); i++) { - View v = getChildAt(i); - v.layout(x, - y, - x + mItemWidth, - y + mItemHeight); - - if (position == itemsPerColumn + (remainderItems > 0 ? 1 : 0)) { - // Break column - position = 1; - remainderItems--; - x += mItemWidth + mItemHorizontalMargin; - y = mPaddingTop; - } else { - position++; - y += mItemHeight + mItemVerticalMargin; - } - } - } -} - - diff --git a/studio-custom-widgets/studio-android-widgets.iml b/studio-custom-widgets/studio-android-widgets.iml deleted file mode 100644 index b0363d7ccd..0000000000 --- a/studio-custom-widgets/studio-android-widgets.iml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<module type="JAVA_MODULE" version="4"> - <component name="NewModuleRootManager" inherit-compiler-output="true"> - <exclude-output /> - <content url="file://$MODULE_DIR$"> - <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> - </content> - <orderEntry type="inheritedJdk" /> - <orderEntry type="sourceFolder" forTests="false" /> - <orderEntry type="library" name="layoutlib_api-prebuilt" level="project" /> - <orderEntry type="library" name="framework.jar" level="project" /> - <orderEntry type="module" module-name="bridge" /> - </component> -</module>
\ No newline at end of file diff --git a/validator/Android.bp b/validator/Android.bp index 0eff99b19e..ca68179d92 100644 --- a/validator/Android.bp +++ b/validator/Android.bp @@ -14,6 +14,10 @@ // limitations under the License. // +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + java_library_host { name: "layoutlib-validator", @@ -23,6 +27,7 @@ java_library_host { libs: [ "tools-common-prebuilt", "temp_layoutlib", + "layoutlib_api-prebuilt", "layoutlib-common", "guava", ], diff --git a/validator/resources/strings.properties b/validator/resources/strings.properties index af7d02004b..7855142697 100644 --- a/validator/resources/strings.properties +++ b/validator/resources/strings.properties @@ -32,8 +32,15 @@ check_title_text_contrast = Text contrast check_title_text_style = Text Style check_title_touch_target_size = Touch target check_view_banned_word = Banned word +checkbox_item_type = checkbox +checkbox_item_type_separate_words = check box +checked_state = checked +click_action = click clickable = clickable clickable_and_long_clickable = clickable and long clickable +description_remove_view_attribute = Remove the view attribute <tt>%1$s</tt>. +description_set_view_attribute = Set the view attribute <tt>%1$s</tt> to <tt>%2$s</tt>. +description_set_view_attribute_with_an_empty_string = Set the view attribute <tt>%1$s</tt> to a meaningful non-empty string or resource reference. italic_text = italic italic_underline_text = italic and underline long_clickable = long clickable @@ -74,7 +81,9 @@ result_message_class_name_is_unknown = This item\'s type could not be determined result_message_class_name_not_supported_brief = This item\'s type may not be supported. result_message_class_name_not_supported_detail = This item\'s type <tt>%1$s</tt> may not be resolvable by accessibility services. Consider using a type defined by the Android SDK. result_message_clickablespan_no_determined_type = This item\'s type is undetermined. +result_message_content_desc_contains_action = This item\'s <tt>android:contentDescription</tt>, \"<tt>%1$s</tt>\", contains the action \"<tt>%2$s</tt>\". result_message_content_desc_contains_redundant_word = This item\'s <tt>android:contentDescription</tt>, \"<tt>%1$s</tt>\" contains the item type \"<tt>%2$s</tt>\". +result_message_content_desc_contains_state = This item\'s <tt>android:contentDescription</tt>, \"<tt>%1$s</tt>\", contains the state \"<tt>%2$s</tt>\". result_message_content_desc_ends_with_view_type = This item\'s <tt>android:contentDescription</tt>, \"<tt>%1$s</tt>\" ends with the item\'s type. result_message_could_not_get_background_color = This item\'s background color could not be determined. result_message_could_not_get_text_color = This item\'s text color could not be determined. @@ -121,11 +130,16 @@ result_message_textview_heuristic_contrast_not_sufficient = The item\'s text con result_message_textview_heuristic_contrast_not_sufficient_confirmed = The item\'s text contrast ratio is %1$.2f. This ratio is based on the provided foreground color of <tt>#%2$06X</tt> and provided background color of <tt>#%3$06X</tt>. Consider using colors that result in a contrast ratio greater than %4$.2f for small text, or %5$.2f for large text. result_message_textview_heuristic_customized_contrast_not_sufficient = The item\'s text contrast ratio is %1$.2f. This ratio is based on an estimated foreground color of <tt>#%2$06X</tt> and an estimated background color of <tt>#%3$06X</tt>. Consider increasing this item\'s text contrast ratio to the configured ratio of %4$.2f or greater. result_message_textview_heuristic_customized_contrast_not_sufficient_confirmed = The item\'s text contrast ratio is %1$.2f. This ratio is based on the provided foreground color of <tt>#%2$06X</tt> and provided background color of <tt>#%3$06X</tt>. Consider increasing this item\'s text contrast ratio to the configured ratio of %4$.2f or greater. -result_message_traversal_cycle = This item may be part of a traversal ordering cycle due to its <tt>%1$s</tt> attribute. Traversal behavior with screen readers may be unpredictable. +result_message_traversal_cycle = This item may be part of a traversal ordering cycle due to its <tt>%1$s</tt> attribute. Traversal behavior with screen readers may be unpredictable. result_message_traversal_over_constrained = Traversal ordering for this item may be over constrained based on its <tt>android:accessibilityTraversalBefore</tt> and <tt>android:accessibilityTraversalAfter</tt> attributes. Traversal behavior with screen readers may be unpredictable. result_message_urlspan_invalid_url = Verify that the URL within this item\'s <tt>URLSpan</tt> is valid. result_message_urlspan_not_clickablespan = This item should use a <tt>URLSpan</tt> in place of a <tt>ClickableSpan</tt>. result_message_view_bounds = This %1$s item also has an on-screen location of <tt>%2$s</tt>. result_message_view_not_within_screencapture = This item\'s on-screen location (<tt>%1$s</tt>) were not within the screen capture on-screen location (<tt>%2$s</tt>). result_message_web_content = Web content is not evaluated. +selected_state = selected +swipe_action = swipe +tap_action = tap +unchecked_state = unchecked underline_text = underline +unselected_state = unselected diff --git a/validator/resources/values.xml b/validator/resources/values.xml index ae49a3c5f5..55dcf57ffa 100644 --- a/validator/resources/values.xml +++ b/validator/resources/values.xml @@ -33,8 +33,15 @@ <string description="The title of a check on the styling of text. [CHAR LIMIT=50]" name="check_title_text_style">Text Style</string> <string description="The title of a check describing that the size of this clickable view (UI element) is below minimum requirements. [CHAR LIMIT=50]" name="check_title_touch_target_size">Touch target</string> <string description="The title of a check used to detect banned words within the text of a view. [CHAR LIMIT=50]" name="check_view_banned_word">Banned word</string> + <string description="The term for a UI element that functions as a checkbox, as a single word (ex. 'checkbox' instead of 'check box' in English). If there isn't a single word representation in the target language, use multiple words. [CHAR LIMIT=NONE]" name="checkbox_item_type">checkbox</string> + <string description="The term for a UI element that functions as a checkbox, as separate words (ex. 'check box' instead of 'checkbox' in English). If there isn't a multiple word representation in the target language, use a single word. [CHAR LIMIT=NONE]" name="checkbox_item_type_separate_words">check box</string> + <string description="Adjective describing a checkbox that is selected. [CHAR LIMIT=NONE]" name="checked_state">checked</string> + <string description="An action in a UI, as in the imperative 'click to send'. [CHAR LIMIT=NONE]" name="click_action">click</string> <string description="Describes a UI element that is clickable [CHAR LIMIT=NONE]" name="clickable">clickable</string> <string description="Describes a UI element that is both clickable and long clickable [CHAR LIMIT=NONE]" name="clickable_and_long_clickable">clickable and long clickable</string> + <string description="The description for a fix suggestion which recommends removing a view attribute [CHAR LIMIT=NONE]" name="description_remove_view_attribute" translatable="false">Remove the view attribute <tt><ns1:g example="android:contentDescription" id="view_attribute_fully_qualified_name">%1$s</ns1:g></tt>.</string> + <string description="The description for a fix suggestion which recommends setting a value to a view attribute [CHAR LIMIT=NONE]" name="description_set_view_attribute" translatable="false">Set the view attribute <tt><ns1:g example="android:contentDescription" id="view_attribute_fully_qualified_name">%1$s</ns1:g></tt> to <tt><ns1:g example="#FFFFFF" id="suggested_value">%2$s</ns1:g></tt>.</string> + <string description="The description for a fix suggestion which recommends asking the developer to set the view attribute to a meaningful non-empty String literal or relevant resource [CHAR LIMIT=NONE]" name="description_set_view_attribute_with_an_empty_string" translatable="false">Set the view attribute <tt><ns1:g example="android:contentDescription" id="view_attribute_fully_qualified_name">%1$s</ns1:g></tt> to a meaningful non-empty string or resource reference.</string> <string description="Describes italic text styling. [CHAR LIMIT=NONE]" name="italic_text">italic</string> <string description="Describes text with both italic and underlined styling. [CHAR LIMIT=NONE]" name="italic_underline_text">italic and underline</string> <string description="Describes a UI element that is long clickable [CHAR LIMIT=NONE]" name="long_clickable">long clickable</string> @@ -64,7 +71,7 @@ <string description="The brief result message of a check describing that an element is not exposed to accessibility services [CHAR LIMIT=NONE]" name="result_message_brief_is_unexposed_item_screen_region">Consider exposing items in this region to accessibility services.</string> <string description="The brief result message of a check describing that link text is not descriptive. [CHAR LIMIT=NONE]" name="result_message_brief_link_text_not_descriptive">Consider using more descriptive text in the link.</string> <string description="The brief result message if text has a low readability score. [CHAR LIMIT=NONE]" name="result_message_brief_low_reading_score">This text may have a low readability score.</string> - <string description="The brief result message of a check describing that multiple items (UI elements) share the same description that would be spoken by a screen reader. [CHAR LIMIT=NONE}" name="result_message_brief_same_speakable_text">Multiple items have the same description.</string> + <string description="The brief result message of a check describing that multiple items (UI elements) share the same description that would be spoken by a screen reader. [CHAR LIMIT=NONE]" name="result_message_brief_same_speakable_text">Multiple items have the same description.</string> <string description="The brief result message of a check describing that multiple actionable items (UI elements) share the same space on the screen. [CHAR LIMIT=NONE]" name="result_message_brief_same_view_bounds">Multiple <ns1:g example="clickable and long clickable" id="clickability">%1$s</ns1:g> items share this location on the screen.</string> <string description="The brief result message of a check describing that the size of this view (UI element) may be too small to be touched or interacted with reliably. [CHAR LIMIT=NONE]" name="result_message_brief_small_touch_target">Consider making this clickable item larger.</string> <string description="The brief message describing that using bold typeface is ideal. [CHAR LIMIT=NONE]" name="result_message_brief_styled_text">Consider removing <ns1:g example="italic" id="style_info">%1$s</ns1:g> styling on longer passages of text.</string> @@ -75,7 +82,17 @@ <string description="The result message of a check describing that the class name is not supported by the accessibility service. [CHAR LIMIT=NONE]" name="result_message_class_name_not_supported_brief">This item\'s type may not be supported.</string> <string description="The result message of a check describing that the class name is not supported by the accessibility service. [CHAR LIMIT=NONE]" name="result_message_class_name_not_supported_detail">This item\'s type <ns1:g example="com.example.MyButton" id="class_name"><tt>%1$s</tt></ns1:g> may not be resolvable by accessibility services. Consider using a type defined by the Android SDK.</string> <string description="The result message of a check describing the specific android class of the view (UI element) could not be determined. [CHAR LIMIT=NONE]" name="result_message_clickablespan_no_determined_type">This item\'s type is undetermined.</string> + <string description="The result message of a check stating that a description of a view (UI element) might specify an available action within its 'android:contentDescription' attribute. [CHAR LIMIT=NONE]" name="result_message_content_desc_contains_action"> + This item\'s <ns1:g example="android:contentDescription" id="content_description_attr"><tt>android:contentDescription</tt></ns1:g>, + \"<ns1:g example="Tap to send" id="content_desc"><tt>%1$s</tt></ns1:g>\", + contains the action \"<ns1:g example="tap" id="item_action"><tt>%2$s</tt></ns1:g>\". + </string> <string description="The result message of a check stating that a description of a view (UI element) has redundant or unnecessary text (ex: a view of type Button whose 'android:contentDescription' is 'Save button'). [CHAR LIMIT=NONE]" name="result_message_content_desc_contains_redundant_word">This item\'s <ns1:g example="android:contentDescription" id="content_description_attr"><tt>android:contentDescription</tt></ns1:g>, \"<ns1:g example="Save button" id="content_desc"><tt>%1$s</tt></ns1:g>\" contains the item type \"<ns1:g example="button" id="item_type"><tt>%2$s</tt></ns1:g>\".</string> + <string description="The result message of a check stating that a description of a view (UI element) might specify an element state within its 'android:contentDescription' attribute. [CHAR LIMIT=NONE]" name="result_message_content_desc_contains_state"> + This item\'s <ns1:g example="android:contentDescription" id="content_description_attr"><tt>android:contentDescription</tt></ns1:g>, + \"<ns1:g example="Rush delivery selected" id="content_desc"><tt>%1$s</tt></ns1:g>\", + contains the state \"<ns1:g example="selected" id="item_state"><tt>%2$s</tt></ns1:g>\". + </string> <string description="The result message of a check stating that a description of a view (UI element) ends with that view's type (ex: a view of type Button whose 'android:contentDescription' is 'Save button'). [CHAR LIMIT=NONE]" name="result_message_content_desc_ends_with_view_type">This item\'s <ns1:g example="android:contentDescription" id="content_description_attr"><tt>android:contentDescription</tt></ns1:g>, \"<ns1:g example="Save button" id="content_desc"><tt>%1$s</tt></ns1:g>\" ends with the item\'s type.</string> <string description="The result message of a check describing that the background color of a view (UI element) could not be determined. [CHAR LIMIT=NONE]" name="result_message_could_not_get_background_color">This item\'s background color could not be determined.</string> <string description="The result message of a check describing that the color of the text within a view (UI element) could not be determined. [CHAR LIMIT=NONE]" name="result_message_could_not_get_text_color">This item\'s text color could not be determined.</string> @@ -126,8 +143,13 @@ <string description="The result message of a check describing that this view (UI element) may be presented incorrectly to the user when traversed with a screen reader. [CHAR LIMIT=NONE]" name="result_message_traversal_over_constrained">Traversal ordering for this item may be over constrained based on its <ns1:g example="android:accessibilityTraversalBefore" id="traversal_before_attr"><tt>android:accessibilityTraversalBefore</tt></ns1:g> and <ns1:g example="android:accessibilityTraversalAfter" id="traversal_after_attr"><tt>android:accessibilityTraversalAfter</tt></ns1:g> attributes. Traversal behavior with screen readers may be unpredictable.</string> <string description="The result message of a check describing that the view has text marked up with an android URLSpan (a hyperlink), which has an invalid URL. [CHAR LIMIT=NONE]" name="result_message_urlspan_invalid_url">Verify that the URL within this item\'s <ns1:g example="URLSpan" id="url_span_class"><tt>URLSpan</tt></ns1:g> is valid.</string> <string description="The result message of a check describing that views should use the android concept of a 'URLSpan' instead of a 'ClickableSpan', for improved accessibility. [CHAR LIMIT=NONE]" name="result_message_urlspan_not_clickablespan">This item should use a <ns1:g example="URLSpan" id="url_span_class"><tt>URLSpan</tt></ns1:g> in place of a <ns1:g example="ClickableSpan" id="clickable_span_class"><tt>ClickableSpan</tt></ns1:g>.</string> - <string description="The result message of a check describing the position of this view (UI element) on the screen." name="result_message_view_bounds">This <ns1:g example="clickable and long clickable" id="clickability">%1$s</ns1:g> item also has an on-screen location of <ns1:g example="[0,0][100,100]" id="view_bounds"><tt>%2$s</tt></ns1:g>.</string> + <string description="The result message of a check describing the position of this view (UI element) on the screen. [CHAR LIMIT=NONE]" name="result_message_view_bounds">This <ns1:g example="clickable and long clickable" id="clickability">%1$s</ns1:g> item also has an on-screen location of <ns1:g example="[0,0][100,100]" id="view_bounds"><tt>%2$s</tt></ns1:g>.</string> <string description="The result message of a check describing that all or part of the view (UI element) was off the screen when the screenshot was taken. [CHAR LIMIT=NONE]" name="result_message_view_not_within_screencapture">This item\'s on-screen location (<ns1:g example="[0,0][100,100]" id="view_bounds"><tt>%1$s</tt></ns1:g>) were not within the screen capture on-screen location (<ns1:g example="[0,0][1920,1080]" id="capture_bounds"><tt>%2$s</tt></ns1:g>).</string> <string description="The result message of a check describing that web content (UI element shown within a browser) was not evaluated. [CHAR LIMIT=NONE]" name="result_message_web_content">Web content is not evaluated.</string> + <string description="Adjective describing a view that is selected. [CHAR LIMIT=NONE]" name="selected_state">selected</string> + <string description="An action in a UI, as in the imperative 'swipe to unlock'. [CHAR LIMIT=NONE]" name="swipe_action">swipe</string> + <string description="An action in a UI, as in the imperative 'tap to select'. [CHAR LIMIT=NONE]" name="tap_action">tap</string> + <string description="Adjective describing a checkbox that is not selected. [CHAR LIMIT=NONE]" name="unchecked_state">unchecked</string> <string description="Describes underlined text styling. [CHAR LIMIT=NONE]" name="underline_text">underline</string> + <string description="Adjective describing a view that is not selected. [CHAR LIMIT=NONE]" name="unselected_state">unselected</string> </resources>
\ No newline at end of file diff --git a/validator/src/ResourceConverter.java b/validator/src/ResourceConverter.java index 18ffda8266..6b9d73e255 100644 --- a/validator/src/ResourceConverter.java +++ b/validator/src/ResourceConverter.java @@ -102,13 +102,19 @@ public class ResourceConverter { */ for (int j = 0; j < node.getChildNodes().getLength(); j++) { Node child = node.getChildNodes().item(j); + String toAdd = null; if ("ns1:g".equals(child.getNodeName())) { - valueBuilder.append(child.getFirstChild().getNodeValue()); + toAdd = child.getFirstChild().getNodeValue(); } else { - valueBuilder.append(child.getNodeValue()); + toAdd = child.getNodeValue(); } + // Replace all tab, newline and multi indentations. + toAdd = toAdd.replaceAll("[\n\t]", ""); + toAdd = toAdd.replaceAll("[ ]+", " "); + valueBuilder.append(toAdd); } - toReturn.put(name, valueBuilder.toString()); + String finalString = valueBuilder.toString().trim(); + toReturn.put(name, finalString); } return toReturn; } diff --git a/validator/src/com/android/tools/idea/validator/ValidatorData.java b/validator/src/com/android/tools/idea/validator/ValidatorData.java index 6d9d6b6422..49f0e307f5 100644 --- a/validator/src/com/android/tools/idea/validator/ValidatorData.java +++ b/validator/src/com/android/tools/idea/validator/ValidatorData.java @@ -79,6 +79,8 @@ public class ValidatorData { */ public static class Issue { @NotNull + public final String mCategory; + @NotNull public final Type mType; @NotNull public final String mMsg; @@ -94,6 +96,7 @@ public class ValidatorData { public final String mHelpfulUrl; private Issue( + @NotNull String category, @NotNull Type type, @NotNull String msg, @NotNull Level level, @@ -101,6 +104,7 @@ public class ValidatorData { @Nullable Fix fix, @NotNull String sourceClass, @Nullable String helpfulUrl) { + mCategory = category; mType = type; mMsg = msg; mLevel = level; @@ -111,6 +115,7 @@ public class ValidatorData { } public static class IssueBuilder { + private String mCategory; private Type mType = Type.ACCESSIBILITY; private String mMsg; private Level mLevel; @@ -119,6 +124,11 @@ public class ValidatorData { private String mSourceClass; private String mHelpfulUrl; + public IssueBuilder setCategory(String category) { + mCategory = category; + return this; + } + public IssueBuilder setType(Type type) { mType = type; return this; @@ -155,11 +165,19 @@ public class ValidatorData { } public Issue build() { + assert(mCategory != null); assert(mType != null); assert(mMsg != null); assert(mLevel != null); assert(mSourceClass != null); - return new Issue(mType, mMsg, mLevel, mSrcId, mFix, mSourceClass, mHelpfulUrl); + return new Issue(mCategory, + mType, + mMsg, + mLevel, + mSrcId, + mFix, + mSourceClass, + mHelpfulUrl); } } } diff --git a/validator/src/com/android/tools/idea/validator/accessibility/AccessibilityValidator.java b/validator/src/com/android/tools/idea/validator/accessibility/AccessibilityValidator.java index a2ec2c45a8..859e5bc1f7 100644 --- a/validator/src/com/android/tools/idea/validator/accessibility/AccessibilityValidator.java +++ b/validator/src/com/android/tools/idea/validator/accessibility/AccessibilityValidator.java @@ -95,6 +95,8 @@ public class AccessibilityValidator { policy.mChecks); for (AccessibilityHierarchyCheckResult result : results) { + String category = getCheckClassCategory(result.getSourceCheckClass()); + ValidatorData.Level level = convertLevel(result.getType()); if (!filter.contains(level)) { continue; @@ -102,6 +104,7 @@ public class AccessibilityValidator { try { IssueBuilder issueBuilder = new IssueBuilder() + .setCategory(category) .setMsg(result.getMessage(Locale.ENGLISH).toString()) .setLevel(level) .setFix(generateFix(result)) @@ -119,6 +122,7 @@ public class AccessibilityValidator { builder.mIssues.add(issueBuilder.build()); } catch (Exception e) { builder.mIssues.add(new IssueBuilder() + .setCategory(category) .setType(Type.INTERNAL_ERROR) .setMsg(e.getMessage()) .setLevel(Level.ERROR) @@ -130,6 +134,19 @@ public class AccessibilityValidator { } @NotNull + private static String getCheckClassCategory(@NotNull Class<?> checkClass) { + try { + Class<? extends AccessibilityHierarchyCheck> subClass = + checkClass.asSubclass(AccessibilityHierarchyCheck.class); + AccessibilityHierarchyCheck check = + AccessibilityCheckPreset.getHierarchyCheckForClass(subClass); + return (check == null) ? "Accessibility" : check.getCategory().name(); + } catch (ClassCastException e) { + return "Accessibility"; + } + } + + @NotNull private static ValidatorData.Level convertLevel(@NotNull AccessibilityCheckResultType type) { switch (type) { case ERROR: diff --git a/validator/src/com/google/android/apps/common/testing/accessibility/framework/uielement/AccessibilityHierarchyAndroid_ViewElementClassNamesAndroid_Delegate.java b/validator/src/com/google/android/apps/common/testing/accessibility/framework/uielement/AccessibilityHierarchyAndroid_ViewElementClassNamesAndroid_Delegate.java new file mode 100644 index 0000000000..025bd77a77 --- /dev/null +++ b/validator/src/com/google/android/apps/common/testing/accessibility/framework/uielement/AccessibilityHierarchyAndroid_ViewElementClassNamesAndroid_Delegate.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 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 com.google.android.apps.common.testing.accessibility.framework.uielement; + +import com.android.ide.common.rendering.api.LayoutlibCallback; +import com.android.tools.layoutlib.annotations.LayoutlibDelegate; + +public class AccessibilityHierarchyAndroid_ViewElementClassNamesAndroid_Delegate { + + public static LayoutlibCallback sLayoutlibCallback; + + @LayoutlibDelegate + public static Class<?> getClassByName(ViewHierarchyElementAndroid view, String className) { + Class toReturn = AccessibilityHierarchyAndroid + .ViewElementClassNamesAndroid.getClassByName_Original(view, className); + if (toReturn == null && sLayoutlibCallback != null) { + try { + return sLayoutlibCallback.findClass(className); + } catch (ClassNotFoundException ignore) { + } + } + + return toReturn; + } +} diff --git a/validator/validator.iml b/validator/validator.iml index f580aa31c0..6d92c11dfd 100644 --- a/validator/validator.iml +++ b/validator/validator.iml @@ -41,5 +41,6 @@ <SOURCES /> </library> </orderEntry> + <orderEntry type="library" name="layoutlib_api-prebuilt" level="project" /> </component> </module>
\ No newline at end of file |