Revert "Use codegen to catch LinkageErrors from plugins"

Revert submission 28801121-codegen-plugin

Reason for revert: Droidmonitor created revert due to b/368040334.

Reverted changes: /q/submissionid:28801121-codegen-plugin

Change-Id: I7888264372acdbb7352f80317926aab84be140da
diff --git a/packages/SystemUI/plugin/Android.bp b/packages/SystemUI/plugin/Android.bp
index a26cf12..682a68f 100644
--- a/packages/SystemUI/plugin/Android.bp
+++ b/packages/SystemUI/plugin/Android.bp
@@ -23,7 +23,9 @@
 }
 
 java_library {
+
     name: "SystemUIPluginLib",
+
     srcs: [
         "bcsmartspace/src/**/*.java",
         "bcsmartspace/src/**/*.kt",
@@ -38,8 +40,6 @@
         export_proguard_flags_files: true,
     },
 
-    plugins: ["PluginAnnotationProcessor"],
-
     // If you add a static lib here, you may need to also add the package to the ClassLoaderFilter
     // in PluginInstance. That will ensure that loaded plugins have access to the related classes.
     // You should also add it to proguard_common.flags so that proguard does not remove the portions
@@ -53,6 +53,7 @@
         "SystemUILogLib",
         "androidx.annotation_annotation",
     ],
+
 }
 
 android_app {
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt
index 6d27b6f..8dc4815 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt
@@ -21,11 +21,7 @@
 import com.android.internal.annotations.Keep
 import com.android.systemui.log.core.MessageBuffer
 import com.android.systemui.plugins.Plugin
-import com.android.systemui.plugins.annotations.GeneratedImport
-import com.android.systemui.plugins.annotations.ProtectedInterface
-import com.android.systemui.plugins.annotations.ProtectedReturn
 import com.android.systemui.plugins.annotations.ProvidesInterface
-import com.android.systemui.plugins.annotations.SimpleProperty
 import java.io.PrintWriter
 import java.util.Locale
 import java.util.TimeZone
@@ -35,7 +31,6 @@
 typealias ClockId = String
 
 /** A Plugin which exposes the ClockProvider interface */
-@ProtectedInterface
 @ProvidesInterface(action = ClockProviderPlugin.ACTION, version = ClockProviderPlugin.VERSION)
 interface ClockProviderPlugin : Plugin, ClockProvider {
     companion object {
@@ -45,42 +40,31 @@
 }
 
 /** Interface for building clocks and providing information about those clocks */
-@ProtectedInterface
-@GeneratedImport("java.util.List")
-@GeneratedImport("java.util.ArrayList")
 interface ClockProvider {
     /** Initializes the clock provider with debug log buffers */
     fun initialize(buffers: ClockMessageBuffers?)
 
-    @ProtectedReturn("return new ArrayList<ClockMetadata>();")
     /** Returns metadata for all clocks this provider knows about */
     fun getClocks(): List<ClockMetadata>
 
-    @ProtectedReturn("return null;")
     /** Initializes and returns the target clock design */
-    fun createClock(settings: ClockSettings): ClockController?
+    fun createClock(settings: ClockSettings): ClockController
 
-    @ProtectedReturn("return new ClockPickerConfig(\"\", \"\", \"\", null);")
     /** Settings configuration parameters for the clock */
     fun getClockPickerConfig(id: ClockId): ClockPickerConfig
 }
 
 /** Interface for controlling an active clock */
-@ProtectedInterface
 interface ClockController {
-    @get:SimpleProperty
     /** A small version of the clock, appropriate for smaller viewports */
     val smallClock: ClockFaceController
 
-    @get:SimpleProperty
     /** A large version of the clock, appropriate when a bigger viewport is available */
     val largeClock: ClockFaceController
 
-    @get:SimpleProperty
     /** Determines the way the hosting app should behave when rendering either clock face */
     val config: ClockConfig
 
-    @get:SimpleProperty
     /** Events that clocks may need to respond to */
     val events: ClockEvents
 
@@ -92,26 +76,19 @@
 }
 
 /** Interface for a specific clock face version rendered by the clock */
-@ProtectedInterface
 interface ClockFaceController {
-    @get:SimpleProperty
-    @Deprecated("Prefer use of layout")
     /** View that renders the clock face */
     val view: View
 
-    @get:SimpleProperty
     /** Layout specification for this clock */
     val layout: ClockFaceLayout
 
-    @get:SimpleProperty
     /** Determines the way the hosting app should behave when rendering this clock face */
     val config: ClockFaceConfig
 
-    @get:SimpleProperty
     /** Events specific to this clock face */
     val events: ClockFaceEvents
 
-    @get:SimpleProperty
     /** Triggers for various animations */
     val animations: ClockAnimations
 }
@@ -130,21 +107,14 @@
 
 data class AodClockBurnInModel(val scale: Float, val translationX: Float, val translationY: Float)
 
-/** Specifies layout information for the clock face */
-@ProtectedInterface
-@GeneratedImport("java.util.ArrayList")
-@GeneratedImport("android.view.View")
+/** Specifies layout information for the */
 interface ClockFaceLayout {
-    @get:ProtectedReturn("return new ArrayList<View>();")
     /** All clock views to add to the root constraint layout before applying constraints. */
     val views: List<View>
 
-    @ProtectedReturn("return constraints;")
     /** Custom constraints to apply to Lockscreen ConstraintLayout. */
     fun applyConstraints(constraints: ConstraintSet): ConstraintSet
 
-    @ProtectedReturn("return constraints;")
-    /** Custom constraints to apply to preview ConstraintLayout. */
     fun applyPreviewConstraints(constraints: ConstraintSet): ConstraintSet
 
     fun applyAodBurnIn(aodBurnInModel: AodClockBurnInModel)
@@ -175,9 +145,7 @@
 }
 
 /** Events that should call when various rendering parameters change */
-@ProtectedInterface
 interface ClockEvents {
-    @get:ProtectedReturn("return false;")
     /** Set to enable or disable swipe interaction */
     var isReactiveTouchInteractionEnabled: Boolean
 
@@ -219,7 +187,6 @@
 )
 
 /** Methods which trigger various clock animations */
-@ProtectedInterface
 interface ClockAnimations {
     /** Runs an enter animation (if any) */
     fun enter()
@@ -263,7 +230,6 @@
 }
 
 /** Events that have specific data about the related face */
-@ProtectedInterface
 interface ClockFaceEvents {
     /** Call every time tick */
     fun onTimeTick()
@@ -304,9 +270,7 @@
 /** Some data about a clock design */
 data class ClockMetadata(val clockId: ClockId)
 
-data class ClockPickerConfig
-@JvmOverloads
-constructor(
+data class ClockPickerConfig(
     val id: String,
 
     /** Localized name of the clock */
@@ -374,7 +338,7 @@
     /** Transition to AOD should move smartspace like large clock instead of small clock */
     val useAlternateSmartspaceAODTransition: Boolean = false,
 
-    /** Deprecated version of isReactiveToTone; moved to ClockPickerConfig */
+    /** Use ClockPickerConfig.isReactiveToTone instead */
     @Deprecated("TODO(b/352049256): Remove in favor of ClockPickerConfig.isReactiveToTone")
     val isReactiveToTone: Boolean = true,
 
diff --git a/packages/SystemUI/plugin_core/Android.bp b/packages/SystemUI/plugin_core/Android.bp
index 31fbda5..521c019 100644
--- a/packages/SystemUI/plugin_core/Android.bp
+++ b/packages/SystemUI/plugin_core/Android.bp
@@ -24,42 +24,8 @@
 
 java_library {
     sdk_version: "current",
-    name: "PluginAnnotationLib",
-    host_supported: true,
-    device_supported: true,
-    srcs: [
-        "src/**/annotations/*.java",
-        "src/**/annotations/*.kt",
-    ],
-    optimize: {
-        proguard_flags_files: ["proguard.flags"],
-        // Ensure downstream clients that reference this as a shared lib
-        // inherit the appropriate flags to preserve annotations.
-        export_proguard_flags_files: true,
-    },
-
-    // Enforce that the library is built against java 8 so that there are
-    // no compatibility issues with launcher
-    java_version: "1.8",
-}
-
-java_library {
-    sdk_version: "current",
     name: "PluginCoreLib",
-    device_supported: true,
-    srcs: [
-        "src/**/*.java",
-        "src/**/*.kt",
-    ],
-    exclude_srcs: [
-        "src/**/annotations/*.java",
-        "src/**/annotations/*.kt",
-        "src/**/processor/*.java",
-        "src/**/processor/*.kt",
-    ],
-    static_libs: [
-        "PluginAnnotationLib",
-    ],
+    srcs: ["src/**/*.java"],
     optimize: {
         proguard_flags_files: ["proguard.flags"],
         // Ensure downstream clients that reference this as a shared lib
@@ -71,30 +37,3 @@
     // no compatibility issues with launcher
     java_version: "1.8",
 }
-
-java_library {
-    java_version: "1.8",
-    name: "PluginAnnotationProcessorLib",
-    host_supported: true,
-    device_supported: false,
-    srcs: [
-        "src/**/processor/*.java",
-        "src/**/processor/*.kt",
-    ],
-    plugins: ["auto_service_plugin"],
-    static_libs: [
-        "androidx.annotation_annotation",
-        "auto_service_annotations",
-        "auto_common",
-        "PluginAnnotationLib",
-        "guava",
-        "jsr330",
-    ],
-}
-
-java_plugin {
-    name: "PluginAnnotationProcessor",
-    processor_class: "com.android.systemui.plugins.processor.ProtectedPluginProcessor",
-    static_libs: ["PluginAnnotationProcessorLib"],
-    java_version: "1.8",
-}
diff --git a/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/Plugin.java b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/Plugin.java
index 84040f9..8ff6c11 100644
--- a/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/Plugin.java
+++ b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/Plugin.java
@@ -15,7 +15,6 @@
 
 import android.content.Context;
 
-import com.android.systemui.plugins.annotations.ProtectedReturn;
 import com.android.systemui.plugins.annotations.Requires;
 
 /**
@@ -117,8 +116,6 @@
      * @deprecated
      * @see Requires
      */
-    @Deprecated
-    @ProtectedReturn(statement = "return -1;")
     default int getVersion() {
         // Default of -1 indicates the plugin supports the new Requires model.
         return -1;
diff --git a/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/ProtectedPluginListener.kt b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/ProtectedPluginListener.kt
deleted file mode 100644
index 425d00a..0000000
--- a/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/ProtectedPluginListener.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2024 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.systemui.plugins
-
-/** Listener for events from proxy types generated by [ProtectedPluginProcessor]. */
-interface ProtectedPluginListener {
-    /**
-     * Called when a method call produces a [LinkageError] before returning. This callback is
-     * provided so that the host application can terminate the plugin or log the error as
-     * appropraite.
-     *
-     * @return true to terminate all methods within this object; false if the error is recoverable
-     *   and the proxied plugin should continue to operate as normal.
-     */
-    fun onFail(className: String, methodName: String, failure: LinkageError): Boolean
-}
diff --git a/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/ProtectedInterface.kt b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/ProtectedInterface.kt
deleted file mode 100644
index 12a977d..0000000
--- a/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/ProtectedInterface.kt
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2024 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.systemui.plugins.annotations
-
-/**
- * This annotation marks denotes that an interface should use a proxy layer to protect the plugin
- * host from crashing due to [LinkageError]s originating within the plugin's implementation.
- */
-@Target(AnnotationTarget.CLASS)
-@Retention(AnnotationRetention.BINARY)
-annotation class ProtectedInterface
-
-/**
- * This annotation specifies any additional imports that the processor will require when generating
- * the proxy implementation for the target interface. The interface in question must still be
- * annotated with [ProtectedInterface].
- */
-@Repeatable
-@Target(AnnotationTarget.CLASS)
-@Retention(AnnotationRetention.BINARY)
-annotation class GeneratedImport(val extraImport: String)
-
-/**
- * This annotation provides default values to return when the proxy implementation catches a
- * [LinkageError]. The string specified should be a simple but valid java statement. In most cases
- * it should be a return statement of the appropriate type, but in some cases throwing a known
- * exception type may be preferred.
- *
- * This annotation is not required for methods that return void, but will behave the same way.
- */
-@Target(
-    AnnotationTarget.FUNCTION,
-    AnnotationTarget.PROPERTY,
-    AnnotationTarget.PROPERTY_GETTER,
-    AnnotationTarget.PROPERTY_SETTER,
-)
-@Retention(AnnotationRetention.BINARY)
-annotation class ProtectedReturn(val statement: String)
-
-/**
- * Some very simple properties and methods need not be protected by the proxy implementation. This
- * annotation can be used to omit the normal try-catch wrapper the proxy is using. These members
- * will instead be a direct passthrough.
- *
- * It should only be used for members where the plugin implementation is expected to be exceedingly
- * simple. Any member marked with this annotation should be no more complex than kotlin's automatic
- * properties, and make no other method calls whatsoever.
- */
-@Target(
-    AnnotationTarget.FUNCTION,
-    AnnotationTarget.PROPERTY,
-    AnnotationTarget.PROPERTY_GETTER,
-    AnnotationTarget.PROPERTY_SETTER,
-)
-@Retention(AnnotationRetention.BINARY)
-annotation class SimpleProperty
diff --git a/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/processor/ProtectedPluginProcessor.kt b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/processor/ProtectedPluginProcessor.kt
deleted file mode 100644
index 8266de5..0000000
--- a/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/processor/ProtectedPluginProcessor.kt
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * Copyright (C) 2024 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.systemui.plugins.processor
-
-import com.android.systemui.plugins.annotations.GeneratedImport
-import com.android.systemui.plugins.annotations.ProtectedInterface
-import com.android.systemui.plugins.annotations.ProtectedReturn
-import com.android.systemui.plugins.annotations.SimpleProperty
-import com.google.auto.service.AutoService
-import javax.annotation.processing.AbstractProcessor
-import javax.annotation.processing.ProcessingEnvironment
-import javax.annotation.processing.RoundEnvironment
-import javax.lang.model.element.Element
-import javax.lang.model.element.ElementKind
-import javax.lang.model.element.ExecutableElement
-import javax.lang.model.element.PackageElement
-import javax.lang.model.element.TypeElement
-import javax.lang.model.type.TypeKind
-import javax.lang.model.type.TypeMirror
-import javax.tools.Diagnostic.Kind
-import kotlin.collections.ArrayDeque
-
-/**
- * [ProtectedPluginProcessor] generates a proxy implementation for interfaces annotated with
- * [ProtectedInterface] which catches [LinkageError]s generated by the proxied target. This protects
- * the plugin host from crashing due to out-of-date plugin code, where some call has changed so that
- * the [ClassLoader] can no longer resolve it correctly.
- *
- * [PluginInstance] observes these failures via [ProtectedMethodListener] and unloads the plugin in
- * question to prevent further issues. This persists through further load/unload requests.
- *
- * To centralize access to the proxy types, an additional type [PluginProtector] is also generated.
- * This class provides static methods which wrap an instance of the target interface in the proxy
- * type if it is not already an instance of the proxy.
- */
-@AutoService(ProtectedPluginProcessor::class)
-class ProtectedPluginProcessor : AbstractProcessor() {
-    private lateinit var procEnv: ProcessingEnvironment
-
-    override fun init(procEnv: ProcessingEnvironment) {
-        this.procEnv = procEnv
-    }
-
-    override fun getSupportedAnnotationTypes(): Set<String> =
-        setOf("com.android.systemui.plugins.annotations.ProtectedInterface")
-
-    private data class TargetData(
-        val attribute: TypeElement,
-        val sourceType: Element,
-        val sourcePkg: String,
-        val sourceName: String,
-        val outputName: String,
-    )
-
-    override fun process(annotations: Set<TypeElement>, roundEnv: RoundEnvironment): Boolean {
-        val targets = mutableMapOf<String, TargetData>() // keyed by fully-qualified source name
-        val additionalImports = mutableSetOf<String>()
-        for (attr in annotations) {
-            for (target in roundEnv.getElementsAnnotatedWith(attr)) {
-                val sourceName = "${target.simpleName}"
-                val outputName = "${sourceName}Protector"
-                val pkg = (target.getEnclosingElement() as PackageElement).qualifiedName.toString()
-                targets.put("$target", TargetData(attr, target, pkg, sourceName, outputName))
-
-                // This creates excessive imports, but it should be fine
-                additionalImports.add("$pkg.$sourceName")
-                additionalImports.add("$pkg.$outputName")
-            }
-        }
-
-        if (targets.size <= 0) return false
-        for ((_, sourceType, sourcePkg, sourceName, outputName) in targets.values) {
-            // Find all methods in this type and all super types to that need to be implemented
-            val types = ArrayDeque<TypeMirror>().apply { addLast(sourceType.asType()) }
-            val impAttrs = mutableListOf<GeneratedImport>()
-            val methods = mutableListOf<ExecutableElement>()
-            while (types.size > 0) {
-                val typeMirror = types.removeLast()
-                if (typeMirror.toString() == "java.lang.Object") continue
-                val type = procEnv.typeUtils.asElement(typeMirror)
-                for (member in type.enclosedElements) {
-                    if (member.kind != ElementKind.METHOD) continue
-                    methods.add(member as ExecutableElement)
-                }
-
-                impAttrs.addAll(type.getAnnotationsByType(GeneratedImport::class.java))
-                types.addAll(procEnv.typeUtils.directSupertypes(typeMirror))
-            }
-
-            val file = procEnv.filer.createSourceFile("$outputName")
-            TabbedWriter.writeTo(file.openWriter()) {
-                line("package $sourcePkg;")
-                line()
-
-                // Imports used by the proxy implementation
-                line("import android.util.Log;")
-                line("import java.lang.LinkageError;")
-                line("import com.android.systemui.plugins.ProtectedPluginListener;")
-                line()
-
-                // Imports of other generated types
-                if (additionalImports.size > 0) {
-                    for (impTarget in additionalImports) {
-                        line("import $impTarget;")
-                    }
-                    line()
-                }
-
-                // Imports declared via @GeneratedImport
-                if (impAttrs.size > 0) {
-                    for (impAttr in impAttrs) {
-                        line("import ${impAttr.extraImport};")
-                    }
-                    line()
-                }
-
-                braceBlock("public class $outputName implements $sourceName") {
-                    line("private static final String CLASS = \"$sourceName\";")
-
-                    // Static factory method to prevent wrapping the same object twice
-                    parenBlock("public static $outputName protect") {
-                        line("$sourceName instance,")
-                        line("ProtectedPluginListener listener")
-                    }
-                    braceBlock {
-                        line("if (instance instanceof $outputName)")
-                        line("    return ($outputName)instance;")
-                        line("return new $outputName(instance, listener);")
-                    }
-                    line()
-
-                    // Member Fields
-                    line("private $sourceName mInstance;")
-                    line("private ProtectedPluginListener mListener;")
-                    line("private boolean mHasError = false;")
-                    line()
-
-                    // Constructor
-                    parenBlock("private $outputName") {
-                        line("$sourceName instance,")
-                        line("ProtectedPluginListener listener")
-                    }
-                    braceBlock {
-                        line("mInstance = instance;")
-                        line("mListener = listener;")
-                    }
-                    line()
-
-                    // Method implementations
-                    for (method in methods) {
-                        val methodName = method.simpleName
-                        val returnTypeName = method.returnType.toString()
-                        val callArgs = StringBuilder()
-                        var isFirst = true
-
-                        line("@Override")
-                        parenBlock("public $returnTypeName $methodName") {
-                            // While copying the method signature for the proxy type, we also
-                            // accumulate arguments for the nested callsite.
-                            for (param in method.parameters) {
-                                if (!isFirst) completeLine(",")
-                                startLine("${param.asType()} ${param.simpleName}")
-                                isFirst = false
-
-                                if (callArgs.length > 0) callArgs.append(", ")
-                                callArgs.append(param.simpleName)
-                            }
-                        }
-
-                        val isVoid = method.returnType.kind == TypeKind.VOID
-                        val nestedCall = "mInstance.$methodName($callArgs)"
-                        val callStatement =
-                            when {
-                                isVoid -> "$nestedCall;"
-                                targets.containsKey(returnTypeName) -> {
-                                    val targetType = targets.get(returnTypeName)!!.outputName
-                                    "return $targetType.protect($nestedCall, mListener);"
-                                }
-                                else -> "return $nestedCall;"
-                            }
-
-                        // Simple property methods forgo protection
-                        val simpleAttr = method.getAnnotation(SimpleProperty::class.java)
-                        if (simpleAttr != null) {
-                            braceBlock {
-                                line("final String METHOD = \"$methodName\";")
-                                line(callStatement)
-                            }
-                            line()
-                            continue
-                        }
-
-                        // Standard implementation wraps nested call in try-catch
-                        braceBlock {
-                            val retAttr = method.getAnnotation(ProtectedReturn::class.java)
-                            val errorStatement =
-                                when {
-                                    retAttr != null -> retAttr.statement
-                                    isVoid -> "return;"
-                                    else -> {
-                                        // Non-void methods must be annotated.
-                                        procEnv.messager.printMessage(
-                                            Kind.ERROR,
-                                            "$outputName.$methodName must be annotated with " +
-                                                "@ProtectedReturn or @SimpleProperty",
-                                        )
-                                        "throw ex;"
-                                    }
-                                }
-
-                            line("final String METHOD = \"$methodName\";")
-
-                            // Return immediately if any previous call has failed.
-                            braceBlock("if (mHasError)") { line(errorStatement) }
-
-                            // Protect callsite in try/catch block
-                            braceBlock("try") { line(callStatement) }
-
-                            // Notify listener when a LinkageError is caught
-                            braceBlock("catch (LinkageError ex)") {
-                                line("Log.wtf(CLASS, \"Failed to execute: \" + METHOD, ex);")
-                                line("mHasError = mListener.onFail(CLASS, METHOD, ex);")
-                                line(errorStatement)
-                            }
-                        }
-                        line()
-                    }
-                }
-            }
-        }
-
-        // Write a centralized static factory type to its own file. This is for convience so that
-        // PluginInstance need not resolve each generated type at runtime as plugins are loaded.
-        val factoryFile = procEnv.filer.createSourceFile("PluginProtector")
-        TabbedWriter.writeTo(factoryFile.openWriter()) {
-            line("package com.android.systemui.plugins;")
-            line()
-
-            line("import java.util.Map;")
-            line("import java.util.ArrayList;")
-            line("import java.util.HashSet;")
-            line("import static java.util.Map.entry;")
-            line()
-
-            for (impTarget in additionalImports) {
-                line("import $impTarget;")
-            }
-            line()
-
-            braceBlock("public final class PluginProtector") {
-                line("private PluginProtector() { }")
-                line()
-
-                // Untyped factory SAM, private to this type.
-                braceBlock("private interface Factory") {
-                    line("Object create(Object plugin, ProtectedPluginListener listener);")
-                }
-                line()
-
-                // Store a reference to each `protect` method in a map by interface type.
-                parenBlock("private static final Map<Class, Factory> sFactories = Map.ofEntries") {
-                    var isFirst = true
-                    for (target in targets.values) {
-                        if (!isFirst) completeLine(",")
-                        target.apply {
-                            startLine("entry($sourceName.class, ")
-                            appendLine("(p, h) -> $outputName.protect(($sourceName)p, h))")
-                        }
-                        isFirst = false
-                    }
-                }
-                completeLine(";")
-                line()
-
-                // Lookup the relevant factory based on the instance type, if not found return null.
-                parenBlock("public static <T> T tryProtect") {
-                    line("T target,")
-                    line("ProtectedPluginListener listener")
-                }
-                braceBlock {
-                    // Accumulate interfaces from type and all base types
-                    line("HashSet<Class> interfaces = new HashSet<Class>();")
-                    line("Class current = target.getClass();")
-                    braceBlock("while (current != null)") {
-                        braceBlock("for (Class cls : current.getInterfaces())") {
-                            line("interfaces.add(cls);")
-                        }
-                        line("current = current.getSuperclass();")
-                    }
-                    line()
-
-                    // Check if any of the interfaces are marked protectable
-                    line("int candidateCount = 0;")
-                    line("Factory candidateFactory = null;")
-                    braceBlock("for (Class cls : interfaces)") {
-                        line("Factory factory = sFactories.get(cls);")
-                        braceBlock("if (factory != null)") {
-                            line("candidateFactory = factory;")
-                            line("candidateCount++;")
-                        }
-                    }
-                    line()
-
-                    // No match, return null
-                    braceBlock("if (candidateFactory == null)") { line("return null;") }
-
-                    // Multiple matches, not supported
-                    braceBlock("if (candidateCount >= 2)") {
-                        var error = "Plugin implements more than one protected interface"
-                        line("throw new UnsupportedOperationException(\"$error\");")
-                    }
-
-                    // Call the factory and wrap the target object
-                    line("return (T)candidateFactory.create(target, listener);")
-                }
-                line()
-
-                // Wraps the target with the appropriate generated proxy if it exists.
-                parenBlock("public static <T> T protectIfAble") {
-                    line("T target,")
-                    line("ProtectedPluginListener listener")
-                }
-                braceBlock {
-                    line("T result = tryProtect(target, listener);")
-                    line("return result != null ? result : target;")
-                }
-                line()
-            }
-        }
-
-        return true
-    }
-}
diff --git a/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/processor/TabbedWriter.kt b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/processor/TabbedWriter.kt
deleted file mode 100644
index 941b2c2..0000000
--- a/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/processor/TabbedWriter.kt
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2024 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.systemui.plugins.processor
-
-import java.io.BufferedWriter
-import java.io.Writer
-
-/**
- * [TabbedWriter] is a convience class which tracks and writes correctly tabbed lines for generating
- * source files. These files don't need to be correctly tabbed as they're ephemeral and not part of
- * the source tree, but correct tabbing makes debugging much easier when the build fails.
- */
-class TabbedWriter(writer: Writer) : AutoCloseable {
-    private val target = BufferedWriter(writer)
-    private var isInProgress = false
-    var tabCount: Int = 0
-        private set
-
-    override fun close() = target.close()
-
-    fun line() {
-        target.newLine()
-        isInProgress = false
-    }
-
-    fun line(str: String) {
-        if (isInProgress) {
-            target.newLine()
-        }
-
-        target.append("    ".repeat(tabCount))
-        target.append(str)
-        target.newLine()
-        isInProgress = false
-    }
-
-    fun completeLine(str: String) {
-        if (!isInProgress) {
-            target.newLine()
-            target.append("    ".repeat(tabCount))
-        }
-
-        target.append(str)
-        target.newLine()
-        isInProgress = false
-    }
-
-    fun startLine(str: String) {
-        if (isInProgress) {
-            target.newLine()
-        }
-
-        target.append("    ".repeat(tabCount))
-        target.append(str)
-        isInProgress = true
-    }
-
-    fun appendLine(str: String) {
-        if (!isInProgress) {
-            target.append("    ".repeat(tabCount))
-        }
-
-        target.append(str)
-        isInProgress = true
-    }
-
-    fun braceBlock(str: String = "", write: TabbedWriter.() -> Unit) {
-        block(str, " {", "}", true, write)
-    }
-
-    fun parenBlock(str: String = "", write: TabbedWriter.() -> Unit) {
-        block(str, "(", ")", false, write)
-    }
-
-    private fun block(
-        str: String,
-        start: String,
-        end: String,
-        newLineForEnd: Boolean,
-        write: TabbedWriter.() -> Unit,
-    ) {
-        appendLine(str)
-        completeLine(start)
-
-        tabCount++
-        this.write()
-        tabCount--
-
-        if (newLineForEnd) {
-            line(end)
-        } else {
-            startLine(end)
-        }
-    }
-
-    companion object {
-        fun writeTo(writer: Writer, write: TabbedWriter.() -> Unit) {
-            TabbedWriter(writer).use { it.write() }
-        }
-    }
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstance.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstance.java
index 5a9e021..87cc86f 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstance.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstance.java
@@ -32,8 +32,6 @@
 import com.android.systemui.plugins.PluginFragment;
 import com.android.systemui.plugins.PluginLifecycleManager;
 import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.PluginProtector;
-import com.android.systemui.plugins.ProtectedPluginListener;
 
 import dalvik.system.PathClassLoader;
 
@@ -51,8 +49,7 @@
  *
  * @param <T> The type of plugin that this contains.
  */
-public class PluginInstance<T extends Plugin>
-        implements PluginLifecycleManager, ProtectedPluginListener {
+public class PluginInstance<T extends Plugin> implements PluginLifecycleManager {
     private static final String TAG = "PluginInstance";
 
     private final Context mAppContext;
@@ -61,7 +58,6 @@
     private final PluginFactory<T> mPluginFactory;
     private final String mTag;
 
-    private boolean mHasError = false;
     private BiConsumer<String, String> mLogConsumer = null;
     private Context mPluginContext;
     private T mPlugin;
@@ -91,11 +87,6 @@
         return mTag;
     }
 
-    /** */
-    public boolean hasError() {
-        return mHasError;
-    }
-
     public void setLogFunc(BiConsumer logConsumer) {
         mLogConsumer = logConsumer;
     }
@@ -106,21 +97,8 @@
         }
     }
 
-    @Override
-    public synchronized boolean onFail(String className, String methodName, LinkageError failure) {
-        mHasError = true;
-        unloadPlugin();
-        mListener.onPluginDetached(this);
-        return true;
-    }
-
     /** Alerts listener and plugin that the plugin has been created. */
     public synchronized void onCreate() {
-        if (mHasError) {
-            log("Previous LinkageError detected for plugin class");
-            return;
-        }
-
         boolean loadPlugin = mListener.onPluginAttached(this);
         if (!loadPlugin) {
             if (mPlugin != null) {
@@ -148,12 +126,6 @@
 
     /** Alerts listener and plugin that the plugin is being shutdown. */
     public synchronized void onDestroy() {
-        if (mHasError) {
-            // Detached in error handler
-            log("onDestroy - no-op");
-            return;
-        }
-
         log("onDestroy");
         unloadPlugin();
         mListener.onPluginDetached(this);
@@ -162,25 +134,20 @@
     /** Returns the current plugin instance (if it is loaded). */
     @Nullable
     public T getPlugin() {
-        return mHasError ? null : mPlugin;
+        return mPlugin;
     }
 
     /**
      * Loads and creates the plugin if it does not exist.
      */
     public synchronized void loadPlugin() {
-        if (mHasError) {
-            log("Previous LinkageError detected for plugin class");
-            return;
-        }
-
         if (mPlugin != null) {
             log("Load request when already loaded");
             return;
         }
 
         // Both of these calls take about 1 - 1.5 seconds in test runs
-        mPlugin = mPluginFactory.createPlugin(this);
+        mPlugin = mPluginFactory.createPlugin();
         mPluginContext = mPluginFactory.createPluginContext();
         if (mPlugin == null || mPluginContext == null) {
             Log.e(mTag, "Requested load, but failed");
@@ -397,16 +364,20 @@
         }
 
         /** Creates the related plugin object from the factory */
-        public T createPlugin(ProtectedPluginListener listener) {
+        public T createPlugin() {
             try {
                 ClassLoader loader = mClassLoaderFactory.get();
                 Class<T> instanceClass = (Class<T>) Class.forName(
                         mComponentName.getClassName(), true, loader);
                 T result = (T) mInstanceFactory.create(instanceClass);
                 Log.v(TAG, "Created plugin: " + result);
-                return PluginProtector.protectIfAble(result, listener);
-            } catch (ReflectiveOperationException ex) {
-                Log.wtf(TAG, "Failed to load plugin", ex);
+                return result;
+            } catch (ClassNotFoundException ex) {
+                Log.e(TAG, "Failed to load plugin", ex);
+            } catch (IllegalAccessException ex) {
+                Log.e(TAG, "Failed to load plugin", ex);
+            } catch (InstantiationException ex) {
+                Log.e(TAG, "Failed to load plugin", ex);
             }
             return null;
         }
@@ -426,7 +397,7 @@
         /** Check Version and create VersionInfo for instance */
         public VersionInfo checkVersion(T instance) {
             if (instance == null) {
-                instance = createPlugin(null);
+                instance = createPlugin();
             }
             return mVersionChecker.checkVersion(
                     (Class<T>) instance.getClass(), mPluginClass, instance);