aboutsummaryrefslogtreecommitdiff
path: root/create/src/com/android
diff options
context:
space:
mode:
Diffstat (limited to 'create/src/com/android')
-rw-r--r--create/src/com/android/tools/layoutlib/create/AsmGenerator.java10
-rw-r--r--create/src/com/android/tools/layoutlib/create/CreateInfo.java16
-rw-r--r--create/src/com/android/tools/layoutlib/create/DeferStaticInitializerClassAdapter.java2
-rw-r--r--create/src/com/android/tools/layoutlib/create/ICreateInfo.java7
-rw-r--r--create/src/com/android/tools/layoutlib/create/RemoveFinalModifierFieldClassAdapter.java46
-rw-r--r--create/src/com/android/tools/layoutlib/create/StubExceptionMethodAdapter.java2
6 files changed, 81 insertions, 2 deletions
diff --git a/create/src/com/android/tools/layoutlib/create/AsmGenerator.java b/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
index 98055e3a90..55de0afe0f 100644
--- a/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
+++ b/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
@@ -94,6 +94,8 @@ public class AsmGenerator {
private final Set<MethodReplacer> mMethodReplacers;
private boolean mKeepAllNativeClasses;
+ /** A map { FQCN => set { field names } } which should have their final modifier removed */
+ private final Map<String, Set<String>> mRemoveFinalModifierFields;
/**
* Creates a new generator that can generate the output JAR with the stubbed classes.
@@ -218,6 +220,9 @@ public class AsmGenerator {
mRenameStaticInitializerClasses =
Arrays.stream(createInfo.getDeferredStaticInitializerClasses()).collect(Collectors.toSet());
+
+ mRemoveFinalModifierFields = new HashMap<>();
+ addToMap(createInfo.getRemovedFinalModifierFields(), mRemoveFinalModifierFields);
}
/**
@@ -427,6 +432,11 @@ public class AsmGenerator {
cv = new DeferStaticInitializerClassAdapter(cv);
}
+ Set<String> removeFinalModifierFields = mRemoveFinalModifierFields.get(className);
+ if (removeFinalModifierFields != null && !removeFinalModifierFields.isEmpty()) {
+ cv = new RemoveFinalModifierFieldClassAdapter(cv, removeFinalModifierFields);
+ }
+
// Make sure no class file has a version above 55 (corresponding to Java 11),
// so that layoutlib can be run with JDK 11.
cv = new ChangeFileVersionAdapter(mLog, 55, cv);
diff --git a/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index fb50c46ff1..fbfd66895f 100644
--- a/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -129,6 +129,11 @@ public final class CreateInfo implements ICreateInfo {
return DEFERRED_STATIC_INITIALIZER_CLASSES;
}
+ @Override
+ public String[] getRemovedFinalModifierFields() {
+ return REMOVED_FINAL_MODIFIER_FIELDS;
+ }
+
//-----
private static final MethodReplacer[] METHOD_REPLACERS = new MethodReplacer[] {
@@ -331,6 +336,11 @@ public final class CreateInfo implements ICreateInfo {
"android.view.Choreographer#mCallbackQueues", // required for tests only
"android.view.Choreographer$CallbackQueue#mHead", // required for tests only
"android.view.ViewRootImpl#mTmpFrames",
+ "android.view.accessibility.AccessibilityInteractionClient#sCaches",
+ "android.view.accessibility.AccessibilityInteractionClient#sClients",
+ "android.view.accessibility.AccessibilityInteractionClient#sConnectionCache",
+ "android.view.accessibility.AccessibilityInteractionClient#sDirectConnectionCount",
+ "android.view.accessibility.AccessibilityInteractionClient#sScrollingWindows",
"com.android.internal.util.ArrayUtils#sCache",
};
@@ -381,6 +391,12 @@ public final class CreateInfo implements ICreateInfo {
private final static Map<String, InjectMethodRunnable> INJECTED_METHODS = Map.of(
"android.content.Context", InjectMethodRunnables.CONTEXT_GET_FRAMEWORK_CLASS_LOADER);
+ /**
+ * List of fields for which we will remove the final modifier.
+ */
+ private final static String[] REMOVED_FINAL_MODIFIER_FIELDS =
+ new String[]{"android.animation.AnimationHandler#sAnimatorHandler"};
+
public static class LinkedHashMapEldestReplacer implements MethodReplacer {
private final String VOID_TO_MAP_ENTRY =
diff --git a/create/src/com/android/tools/layoutlib/create/DeferStaticInitializerClassAdapter.java b/create/src/com/android/tools/layoutlib/create/DeferStaticInitializerClassAdapter.java
index b5c331d838..3ce901a10b 100644
--- a/create/src/com/android/tools/layoutlib/create/DeferStaticInitializerClassAdapter.java
+++ b/create/src/com/android/tools/layoutlib/create/DeferStaticInitializerClassAdapter.java
@@ -47,7 +47,7 @@ public class DeferStaticInitializerClassAdapter extends ClassVisitor {
// Java 9 does not allow static final field to be modified outside of <clinit>.
// So if a field is static, it has to be non-final.
if ((access & Opcodes.ACC_STATIC) != 0 ) {
- access = access & ~Opcodes.ACC_FINAL;;
+ access = access & ~Opcodes.ACC_FINAL;
}
return super.visitField(access, name, desc, signature, value);
}
diff --git a/create/src/com/android/tools/layoutlib/create/ICreateInfo.java b/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
index 83c5b24523..e536bdc903 100644
--- a/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
+++ b/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
@@ -129,6 +129,13 @@ public interface ICreateInfo {
String[] getDeferredStaticInitializerClasses();
+ /**
+ * Returns a list of fields which should have their final modifier removed.
+ * The array values are in the form of the binary FQCN of the class containing the field and
+ * the field name separated by a '#'.
+ */
+ String[] getRemovedFinalModifierFields();
+
interface MethodReplacer {
boolean isNeeded(String owner, String name, String desc, String sourceClass);
diff --git a/create/src/com/android/tools/layoutlib/create/RemoveFinalModifierFieldClassAdapter.java b/create/src/com/android/tools/layoutlib/create/RemoveFinalModifierFieldClassAdapter.java
new file mode 100644
index 0000000000..2f2d6007c7
--- /dev/null
+++ b/create/src/com/android/tools/layoutlib/create/RemoveFinalModifierFieldClassAdapter.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 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.layoutlib.create;
+
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+
+import java.util.Set;
+
+import static org.objectweb.asm.Opcodes.ACC_FINAL;
+
+/**
+ * Removes the final modifier from the given fields.
+ */
+public class RemoveFinalModifierFieldClassAdapter extends ClassVisitor {
+
+ private final Set<String> mFieldNames;
+
+ public RemoveFinalModifierFieldClassAdapter(ClassVisitor cv, Set<String> fieldNames) {
+ super(Main.ASM_VERSION, cv);
+ mFieldNames = fieldNames;
+ }
+
+ @Override
+ public FieldVisitor visitField(int access, String name, String desc, String signature,
+ Object value) {
+ if (mFieldNames.contains(name)) {
+ access = access & ~ACC_FINAL;
+ }
+ return super.visitField(access, name, desc, signature, value);
+ }
+}
diff --git a/create/src/com/android/tools/layoutlib/create/StubExceptionMethodAdapter.java b/create/src/com/android/tools/layoutlib/create/StubExceptionMethodAdapter.java
index 73a57a2190..322f0656a3 100644
--- a/create/src/com/android/tools/layoutlib/create/StubExceptionMethodAdapter.java
+++ b/create/src/com/android/tools/layoutlib/create/StubExceptionMethodAdapter.java
@@ -24,7 +24,7 @@ import org.objectweb.asm.Type;
/**
- * {@link MethodVisitor} that replaces the method the implementation of the method with
+ * {@link MethodVisitor} that replaces the implementation of the method with
* <code>
* throw new RuntimeException("Stub!");
* </code>