Add intDef annotation processor to generate mapping

Test: Run 'mp :framework-all' and check if mapping file is properly
generated

Change-Id: I58f7ea5894e8ec994a74781663654508205c4db1
diff --git a/Android.bp b/Android.bp
index aae78a0..ded666f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -626,6 +626,9 @@
         // Additional dependencies needed to build the ike API classes.
         "ike-internals",
     ],
+    plugins: [
+        "intdef-annotation-processor",
+    ],
     libs: ["icing-java-proto-lite"],
     apex_available: ["//apex_available:platform"],
     visibility: [
@@ -886,6 +889,7 @@
     exclude_srcs: [
         "core/proto/android/privacy.proto",
         "core/proto/android/section.proto",
+        "core/proto/android/typedef.proto",
     ],
     sdk_version: "9",
     srcs: [
@@ -911,6 +915,7 @@
     exclude_srcs: [
         "core/proto/android/privacy.proto",
         "core/proto/android/section.proto",
+        "core/proto/android/typedef.proto",
     ],
     sdk_version: "core_current",
     // Protos have lots of MissingOverride and similar.
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2168fe3..3d594b4 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4323,9 +4323,46 @@
                     equals = STATUS_BAR_TRANSPARENT,
                     name = "STATUS_BAR_TRANSPARENT")
     }, formatToHexString = true)
+    @SystemUiVisibility
     int mSystemUiVisibility;
 
     /**
+     * @hide
+     */
+    @IntDef(flag = true, prefix = "", value = {
+            SYSTEM_UI_FLAG_LOW_PROFILE,
+            SYSTEM_UI_FLAG_HIDE_NAVIGATION,
+            SYSTEM_UI_FLAG_FULLSCREEN,
+            SYSTEM_UI_FLAG_LAYOUT_STABLE,
+            SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION,
+            SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN,
+            SYSTEM_UI_FLAG_IMMERSIVE,
+            SYSTEM_UI_FLAG_IMMERSIVE_STICKY,
+            SYSTEM_UI_FLAG_LIGHT_STATUS_BAR,
+            SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR,
+            STATUS_BAR_DISABLE_EXPAND,
+            STATUS_BAR_DISABLE_NOTIFICATION_ICONS,
+            STATUS_BAR_DISABLE_NOTIFICATION_ALERTS,
+            STATUS_BAR_DISABLE_NOTIFICATION_TICKER,
+            STATUS_BAR_DISABLE_SYSTEM_INFO,
+            STATUS_BAR_DISABLE_HOME,
+            STATUS_BAR_DISABLE_BACK,
+            STATUS_BAR_DISABLE_CLOCK,
+            STATUS_BAR_DISABLE_RECENT,
+            STATUS_BAR_DISABLE_SEARCH,
+            STATUS_BAR_TRANSIENT,
+            NAVIGATION_BAR_TRANSIENT,
+            STATUS_BAR_UNHIDE,
+            NAVIGATION_BAR_UNHIDE,
+            STATUS_BAR_TRANSLUCENT,
+            NAVIGATION_BAR_TRANSLUCENT,
+            NAVIGATION_BAR_TRANSPARENT,
+            STATUS_BAR_TRANSPARENT,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SystemUiVisibility {}
+
+    /**
      * Reference count for transient state.
      * @see #setHasTransientState(boolean)
      */
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 795e8f3..1d54d92 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1229,32 +1229,54 @@
          * @hide
          */
         @IntDef(prefix = "TYPE_", value = {
-                TYPE_ACCESSIBILITY_OVERLAY,
-                TYPE_APPLICATION,
-                TYPE_APPLICATION_ATTACHED_DIALOG,
-                TYPE_APPLICATION_MEDIA,
-                TYPE_APPLICATION_OVERLAY,
-                TYPE_APPLICATION_PANEL,
-                TYPE_APPLICATION_STARTING,
-                TYPE_APPLICATION_SUB_PANEL,
                 TYPE_BASE_APPLICATION,
+                TYPE_APPLICATION,
+                TYPE_APPLICATION_STARTING,
                 TYPE_DRAWN_APPLICATION,
+                TYPE_APPLICATION_PANEL,
+                TYPE_APPLICATION_MEDIA,
+                TYPE_APPLICATION_SUB_PANEL,
+                TYPE_APPLICATION_ATTACHED_DIALOG,
+                TYPE_APPLICATION_MEDIA_OVERLAY,
+                TYPE_APPLICATION_ABOVE_SUB_PANEL,
+                TYPE_STATUS_BAR,
+                TYPE_SEARCH_BAR,
+                TYPE_PHONE,
+                TYPE_SYSTEM_ALERT,
+                TYPE_KEYGUARD,
+                TYPE_TOAST,
+                TYPE_SYSTEM_OVERLAY,
+                TYPE_PRIORITY_PHONE,
+                TYPE_SYSTEM_DIALOG,
+                TYPE_KEYGUARD_DIALOG,
+                TYPE_SYSTEM_ERROR,
                 TYPE_INPUT_METHOD,
                 TYPE_INPUT_METHOD_DIALOG,
-                TYPE_KEYGUARD,
-                TYPE_KEYGUARD_DIALOG,
-                TYPE_PHONE,
-                TYPE_PRIORITY_PHONE,
-                TYPE_PRIVATE_PRESENTATION,
-                TYPE_SEARCH_BAR,
-                TYPE_STATUS_BAR,
-                TYPE_STATUS_BAR_PANEL,
-                TYPE_SYSTEM_ALERT,
-                TYPE_SYSTEM_DIALOG,
-                TYPE_SYSTEM_ERROR,
-                TYPE_SYSTEM_OVERLAY,
-                TYPE_TOAST,
                 TYPE_WALLPAPER,
+                TYPE_STATUS_BAR_PANEL,
+                TYPE_SECURE_SYSTEM_OVERLAY,
+                TYPE_DRAG,
+                TYPE_STATUS_BAR_SUB_PANEL,
+                TYPE_POINTER,
+                TYPE_NAVIGATION_BAR,
+                TYPE_VOLUME_OVERLAY,
+                TYPE_BOOT_PROGRESS,
+                TYPE_INPUT_CONSUMER,
+                TYPE_NAVIGATION_BAR_PANEL,
+                TYPE_DISPLAY_OVERLAY,
+                TYPE_MAGNIFICATION_OVERLAY,
+                TYPE_PRIVATE_PRESENTATION,
+                TYPE_VOICE_INTERACTION,
+                TYPE_ACCESSIBILITY_OVERLAY,
+                TYPE_VOICE_INTERACTION_STARTING,
+                TYPE_DOCK_DIVIDER,
+                TYPE_QS_DIALOG,
+                TYPE_SCREENSHOT,
+                TYPE_PRESENTATION,
+                TYPE_APPLICATION_OVERLAY,
+                TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY,
+                TYPE_NOTIFICATION_SHADE,
+                TYPE_STATUS_BAR_ADDITIONAL
         })
         @Retention(RetentionPolicy.SOURCE)
         public @interface WindowType {}
@@ -1715,6 +1737,46 @@
         public static final int FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS = 0x80000000;
 
         /**
+         * @hide
+         */
+        @IntDef(flag = true, prefix = "FLAG_", value = {
+                FLAG_ALLOW_LOCK_WHILE_SCREEN_ON,
+                FLAG_DIM_BEHIND,
+                FLAG_BLUR_BEHIND,
+                FLAG_NOT_FOCUSABLE,
+                FLAG_NOT_TOUCHABLE,
+                FLAG_NOT_TOUCH_MODAL,
+                FLAG_TOUCHABLE_WHEN_WAKING,
+                FLAG_KEEP_SCREEN_ON,
+                FLAG_LAYOUT_IN_SCREEN,
+                FLAG_LAYOUT_NO_LIMITS,
+                FLAG_FULLSCREEN,
+                FLAG_FORCE_NOT_FULLSCREEN,
+                FLAG_DITHER,
+                FLAG_SECURE,
+                FLAG_SCALED,
+                FLAG_IGNORE_CHEEK_PRESSES,
+                FLAG_LAYOUT_INSET_DECOR,
+                FLAG_ALT_FOCUSABLE_IM,
+                FLAG_WATCH_OUTSIDE_TOUCH,
+                FLAG_SHOW_WHEN_LOCKED,
+                FLAG_SHOW_WALLPAPER,
+                FLAG_TURN_SCREEN_ON,
+                FLAG_DISMISS_KEYGUARD,
+                FLAG_SPLIT_TOUCH,
+                FLAG_HARDWARE_ACCELERATED,
+                FLAG_LAYOUT_IN_OVERSCAN,
+                FLAG_TRANSLUCENT_STATUS,
+                FLAG_TRANSLUCENT_NAVIGATION,
+                FLAG_LOCAL_FOCUS_MODE,
+                FLAG_SLIPPERY,
+                FLAG_LAYOUT_ATTACHED_IN_DECOR,
+                FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface Flags {}
+
+        /**
          * Various behavioral options/flags.  Default is none.
          *
          * @see #FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
@@ -1809,6 +1871,7 @@
             @ViewDebug.FlagToString(mask = FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, equals = FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
                     name = "DRAWS_SYSTEM_BAR_BACKGROUNDS")
         }, formatToHexString = true)
+        @Flags
         public int flags;
 
         /**
@@ -2027,6 +2090,7 @@
          * @hide
          */
         public static final int PRIVATE_FLAG_TRUSTED_OVERLAY = 0x20000000;
+
         /**
          * An internal annotation for flags that can be specified to {@link #softInputMode}.
          *
@@ -2041,6 +2105,38 @@
         public @interface SystemFlags {}
 
         /**
+         * @hide
+         */
+        @IntDef(flag = true, prefix="PRIVATE_FLAG_", value = {
+                PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED,
+                PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED,
+                PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS,
+                SYSTEM_FLAG_SHOW_FOR_ALL_USERS,
+                PRIVATE_FLAG_NO_MOVE_ANIMATION,
+                PRIVATE_FLAG_COMPATIBLE_WINDOW,
+                PRIVATE_FLAG_SYSTEM_ERROR,
+                PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS,
+                PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR,
+                PRIVATE_FLAG_PRESERVE_GEOMETRY,
+                PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY,
+                PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH,
+                PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME,
+                PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS,
+                PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE,
+                SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,
+                PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY,
+                PRIVATE_FLAG_IS_SCREEN_DECOR,
+                PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION,
+                PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC,
+                PRIVATE_FLAG_USE_BLAST,
+                PRIVATE_FLAG_APPEARANCE_CONTROLLED,
+                PRIVATE_FLAG_BEHAVIOR_CONTROLLED,
+                PRIVATE_FLAG_FIT_INSETS_CONTROLLED,
+                PRIVATE_FLAG_TRUSTED_OVERLAY,
+        })
+        public @interface PrivateFlags {}
+
+        /**
          * Control flags that are private to the platform.
          * @hide
          */
@@ -2127,6 +2223,10 @@
                         equals = PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC,
                         name = "COLOR_SPACE_AGNOSTIC"),
                 @ViewDebug.FlagToString(
+                        mask = PRIVATE_FLAG_USE_BLAST,
+                        equals = PRIVATE_FLAG_USE_BLAST,
+                        name = "USE_BLAST"),
+                @ViewDebug.FlagToString(
                         mask = PRIVATE_FLAG_APPEARANCE_CONTROLLED,
                         equals = PRIVATE_FLAG_APPEARANCE_CONTROLLED,
                         name = "APPEARANCE_CONTROLLED"),
@@ -2143,6 +2243,7 @@
                         equals = PRIVATE_FLAG_TRUSTED_OVERLAY,
                         name = "TRUSTED_OVERLAY")
         })
+        @PrivateFlags
         @TestApi
         public int privateFlags;
 
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 02213ed..c216638 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -28,6 +28,7 @@
 import "frameworks/base/core/proto/android/view/surface.proto";
 import "frameworks/base/core/proto/android/view/windowlayoutparams.proto";
 import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/typedef.proto";
 
 package com.android.server.wm;
 
@@ -43,8 +44,8 @@
     optional string focused_app = 4;
     optional IdentifierProto input_method_window = 5;
     optional bool display_frozen = 6;
-    optional int32 rotation = 7;
-    optional int32 last_orientation = 8;
+    optional int32 rotation = 7 [(.android.typedef) = "android.view.Surface.Rotation"];
+    optional int32 last_orientation = 8 [(.android.typedef) = "android.content.pm.ActivityInfo.ScreenOrientation"];
     optional int32 focused_display_id = 9;
 }
 
@@ -177,7 +178,7 @@
     repeated WindowTokenProto ime_windows = 8 [deprecated=true];
     optional int32 dpi = 9;
     optional .android.view.DisplayInfoProto display_info = 10;
-    optional int32 rotation = 11;
+    optional int32 rotation = 11 [(.android.typedef) = "android.view.Surface.Rotation"];
     optional ScreenRotationAnimationProto screen_rotation_animation = 12;
     optional DisplayFramesProto display_frames = 13;
     optional int32 surface_size = 14 [deprecated=true];
@@ -264,8 +265,8 @@
 
     optional int32 display_id = 15;
     optional int32 root_task_id = 16;
-    optional int32 activity_type = 17;
-    optional int32 resize_mode = 18;
+    optional int32 activity_type = 17 [(.android.typedef) = "android.app.WindowConfiguration.ActivityType"];
+    optional int32 resize_mode = 18 [(.android.typedef) = "android.appwidget.AppWidgetProviderInfo.ResizeModeFlags"];
     optional int32 min_width = 19;
     optional int32 min_height = 20;
 
@@ -351,7 +352,7 @@
     optional .android.graphics.RectProto surface_position = 16;
     optional int32 requested_width = 18;
     optional int32 requested_height = 19;
-    optional int32 view_visibility = 20;
+    optional int32 view_visibility = 20 [(.android.typedef) = "android.view.View.Visibility"];
     optional int32 system_ui_visibility = 21;
     optional bool has_surface = 22;
     optional bool is_ready_for_display = 23;
@@ -424,7 +425,7 @@
     option (.android.msg_privacy).dest = DEST_AUTOMATIC;
 
     optional ConfigurationContainerProto configuration_container = 1;
-    optional int32 orientation = 2;
+    optional int32 orientation = 2 [(.android.typedef) = "android.content.pm.ActivityInfo.ScreenOrientation"];
     optional bool visible = 3;
     optional SurfaceAnimatorProto surface_animator = 4;
     repeated WindowContainerChildProto children = 5;
diff --git a/core/proto/android/typedef.proto b/core/proto/android/typedef.proto
new file mode 100644
index 0000000..be8742d
--- /dev/null
+++ b/core/proto/android/typedef.proto
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+syntax = "proto2";
+
+package android;
+
+import "google/protobuf/descriptor.proto";
+
+extend google.protobuf.FieldOptions {
+  // Used to specify the IntDef annotation type so that ints
+  // can be associated with their string representation
+
+  // 60001 is a random field numbers assigned to the custom options
+  // numbers between 50000 and 99999 are reserved for internal use within individual organizations
+  optional string typedef = 60001;
+}
diff --git a/core/proto/android/view/windowlayoutparams.proto b/core/proto/android/view/windowlayoutparams.proto
index 272a245..64e6da8 100644
--- a/core/proto/android/view/windowlayoutparams.proto
+++ b/core/proto/android/view/windowlayoutparams.proto
@@ -19,6 +19,7 @@
 import "frameworks/base/core/proto/android/graphics/pixelformat.proto";
 import "frameworks/base/core/proto/android/view/display.proto";
 import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/typedef.proto";
 
 package android.view;
 option java_multiple_files = true;
@@ -27,15 +28,15 @@
 message WindowLayoutParamsProto {
     option (.android.msg_privacy).dest = DEST_AUTOMATIC;
 
-    optional int32 type = 1;
+    optional int32 type = 1 [(.android.typedef) = "android.view.WindowManager.LayoutParams.WindowType"];
     optional int32 x = 2;
     optional int32 y = 3;
     optional int32 width = 4;
     optional int32 height = 5;
     optional float horizontal_margin = 6;
     optional float vertical_margin = 7;
-    optional int32 gravity = 8;
-    optional int32 soft_input_mode = 9;
+    optional int32 gravity = 8; // TODO (b/160129453): Add IntDef
+    optional int32 soft_input_mode = 9 [(.android.typedef) = "android.view.WindowManager.LayoutParams.SoftInputModeFlags"];
     optional .android.graphics.PixelFormatProto.Format format = 10;
     optional int32 window_animations = 11;
     optional float alpha = 12;
@@ -53,17 +54,17 @@
     optional float preferred_refresh_rate = 16;
     optional int32 preferred_display_mode_id = 17;
     optional bool has_system_ui_listeners = 18;
-    optional uint32 input_feature_flags = 19;
+    optional uint32 input_feature_flags = 19; // TODO (b/160129453): Add IntDef
     optional int64 user_activity_timeout = 20;
 
     optional DisplayProto.ColorMode color_mode = 23;
-    optional uint32 flags = 24;
-    optional uint32 private_flags = 26;
-    optional uint32 system_ui_visibility_flags = 27;
-    optional uint32 subtree_system_ui_visibility_flags = 28;
-    optional uint32 appearance = 29;
-    optional uint32 behavior = 30;
-    optional uint32 fit_insets_types = 31;
-    optional uint32 fit_insets_sides = 32;
+    optional uint32 flags = 24 [(.android.typedef) = "android.view.WindowManager.LayoutParams.Flags"];
+    optional uint32 private_flags = 26 [(.android.typedef) = "android.view.WindowManager.LayoutParams.PrivateFlags"];
+    optional uint32 system_ui_visibility_flags = 27; // TODO (b/160129453): Add IntDef
+    optional uint32 subtree_system_ui_visibility_flags = 28; // TODO (b/160129453): Add IntDef
+    optional uint32 appearance = 29 [(.android.typedef) = "android.view.WindowInsetsController.Appearance"];
+    optional uint32 behavior = 30 [(.android.typedef) = "android.view.WindowInsetsController.Behavior"];
+    optional uint32 fit_insets_types = 31 [(.android.typedef) = "android.view.WindowInsets.Type.InsetsType"];
+    optional uint32 fit_insets_sides = 32 [(.android.typedef) = "android.view.WindowInsets.Side.InsetsSide"];
     optional bool fit_ignore_visibility = 33;
 }
diff --git a/tools/processors/intdef_mappings/Android.bp b/tools/processors/intdef_mappings/Android.bp
new file mode 100644
index 0000000..e255f7c
--- /dev/null
+++ b/tools/processors/intdef_mappings/Android.bp
@@ -0,0 +1,33 @@
+java_plugin {
+    name: "intdef-annotation-processor",
+
+    processor_class: "android.processor.IntDefProcessor",
+
+    srcs: [
+        ":framework-annotations",
+        "src/**/*.java",
+        "src/**/*.kt"
+    ],
+
+    use_tools_jar: true,
+}
+
+java_test_host {
+    name: "intdef-annotation-processor-test",
+
+    srcs: [
+        "test/**/*.java",
+        "test/**/*.kt"
+     ],
+    java_resource_dirs: ["test/resources"],
+
+    static_libs: [
+        "compile-testing-prebuilt",
+        "truth-prebuilt",
+        "junit",
+        "guava",
+        "intdef-annotation-processor"
+    ],
+
+    test_suites: ["general-tests"],
+}
\ No newline at end of file
diff --git a/tools/processors/intdef_mappings/src/android/processor/IntDefProcessor.kt b/tools/processors/intdef_mappings/src/android/processor/IntDefProcessor.kt
new file mode 100644
index 0000000..84faeea
--- /dev/null
+++ b/tools/processors/intdef_mappings/src/android/processor/IntDefProcessor.kt
@@ -0,0 +1,190 @@
+/*
+ * 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.processor
+
+import android.annotation.IntDef
+import com.sun.source.tree.IdentifierTree
+import com.sun.source.tree.MemberSelectTree
+import com.sun.source.tree.NewArrayTree
+import com.sun.source.util.SimpleTreeVisitor
+import com.sun.source.util.Trees
+import java.io.IOException
+import java.io.Writer
+import javax.annotation.processing.AbstractProcessor
+import javax.annotation.processing.RoundEnvironment
+import javax.lang.model.SourceVersion
+import javax.lang.model.element.AnnotationValue
+import javax.lang.model.element.TypeElement
+import javax.tools.Diagnostic.Kind
+import javax.tools.StandardLocation.CLASS_OUTPUT
+import kotlin.collections.set
+
+
+/**
+ * The IntDefProcessor is intended to generate a mapping from ints to their respective string
+ * identifier for each IntDef for use by Winscope or any other tool which requires such a mapping.
+ *
+ * The processor will run when building :frameworks-all and dump all the IntDef mappings found the
+ * files the make up :frameworks-all as json to outputPath.
+ */
+class IntDefProcessor : AbstractProcessor() {
+    private val outputName = "intDefMapping.json"
+
+    override fun getSupportedSourceVersion(): SourceVersion = SourceVersion.latest()
+
+    // Define what the annotation we care about are for compiler optimization
+    override fun getSupportedAnnotationTypes() = LinkedHashSet<String>().apply {
+        add(IntDef::class.java.name)
+    }
+
+    override fun process(annotations: Set<TypeElement>, roundEnv: RoundEnvironment): Boolean {
+        // There should only be one matching annotation definition for intDef
+        val annotationType = annotations.firstOrNull() ?: return false
+        val annotatedElements = roundEnv.getElementsAnnotatedWith(annotationType)
+
+        val annotationTypeToIntDefMapping = annotatedElements.associate { annotatedElement ->
+            val type = (annotatedElement as TypeElement).qualifiedName.toString()
+            val mapping = generateIntDefMapping(annotatedElement, annotationType)
+            val intDef = annotatedElement.getAnnotation(IntDef::class.java)
+            type to IntDefMapping(mapping, intDef.flag)
+        }
+
+        try {
+            outputToFile(annotationTypeToIntDefMapping)
+        } catch (e: IOException) {
+            error("Failed to write IntDef mappings :: $e")
+        }
+        return false
+    }
+
+    private fun generateIntDefMapping(
+            annotatedElement: TypeElement,
+            annotationType: TypeElement
+    ): Map<Int, String> {
+        // LinkedHashMap makes sure ordering is the same as in the code
+        val mapping = LinkedHashMap<Int, String>()
+
+        val annotationMirror = annotatedElement.annotationMirrors
+                // Should only ever be one matching this condition
+                .first { it.annotationType.asElement() == annotationType }
+
+        val value = annotationMirror.elementValues.entries
+                .first { entry -> entry.key.simpleName.contentEquals("value") }
+                .value
+
+        val trees = Trees.instance(processingEnv)
+        val tree = trees.getTree(annotatedElement, annotationMirror, value)
+
+        val identifiers = ArrayList<String>()
+        tree.accept(IdentifierVisitor(), identifiers)
+
+        val values = value.value as List<AnnotationValue>
+
+        for (i in identifiers.indices) {
+            mapping[values[i].value as Int] = identifiers[i]
+        }
+
+        return mapping
+    }
+
+    private class IdentifierVisitor : SimpleTreeVisitor<Void, ArrayList<String>>() {
+        override fun visitNewArray(node: NewArrayTree, indentifiers: ArrayList<String>): Void? {
+            for (initializer in node.initializers) {
+                initializer.accept(this, indentifiers)
+            }
+
+            return null
+        }
+
+        override fun visitMemberSelect(node: MemberSelectTree, indentifiers: ArrayList<String>):
+                Void? {
+            indentifiers.add(node.identifier.toString())
+
+            return null
+        }
+
+        override fun visitIdentifier(node: IdentifierTree, indentifiers: ArrayList<String>): Void? {
+            indentifiers.add(node.name.toString())
+
+            return null
+        }
+    }
+
+    @Throws(IOException::class)
+    private fun outputToFile(annotationTypeToIntDefMapping: Map<String, IntDefMapping>) {
+        val resource = processingEnv.filer.createResource(
+                CLASS_OUTPUT, "com.android.winscope", outputName)
+        val writer = resource.openWriter()
+        serializeTo(annotationTypeToIntDefMapping, writer)
+        writer.close()
+    }
+
+    private fun error(message: String) {
+        processingEnv.messager.printMessage(Kind.ERROR, message)
+    }
+
+    private fun note(message: String) {
+        processingEnv.messager.printMessage(Kind.NOTE, message)
+    }
+
+    class IntDefMapping(val mapping: Map<Int, String>, val flag: Boolean) {
+        val size
+            get() = this.mapping.size
+
+        val entries
+            get() = this.mapping.entries
+    }
+
+    companion object {
+        fun serializeTo(
+                annotationTypeToIntDefMapping: Map<String, IntDefMapping>,
+                writer: Writer
+        ) {
+            val indent = "  "
+
+            writer.appendln("{")
+
+            val intDefTypesCount = annotationTypeToIntDefMapping.size
+            var currentIntDefTypesCount = 0
+            for ((field, intDefMapping) in annotationTypeToIntDefMapping) {
+                writer.appendln("""$indent"$field": {""")
+
+                // Start IntDef
+
+                writer.appendln("""$indent$indent"flag": ${intDefMapping.flag},""")
+
+                writer.appendln("""$indent$indent"values": {""")
+                intDefMapping.entries.joinTo(writer, separator = ",\n") { (value, identifier) ->
+                    """$indent$indent$indent"$value": "$identifier""""
+                }
+                writer.appendln()
+                writer.appendln("$indent$indent}")
+
+                // End IntDef
+
+                writer.append("$indent}")
+                if (++currentIntDefTypesCount < intDefTypesCount) {
+                    writer.appendln(",")
+                } else {
+                    writer.appendln("")
+                }
+            }
+
+            writer.appendln("}")
+        }
+    }
+}
diff --git a/tools/processors/intdef_mappings/test/android/processor/IntDefProcessorTest.kt b/tools/processors/intdef_mappings/test/android/processor/IntDefProcessorTest.kt
new file mode 100644
index 0000000..c0c159c
--- /dev/null
+++ b/tools/processors/intdef_mappings/test/android/processor/IntDefProcessorTest.kt
@@ -0,0 +1,162 @@
+/*
+ * 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.processor
+
+import android.processor.IntDefProcessor.IntDefMapping
+import com.google.common.collect.ObjectArrays.concat
+import com.google.testing.compile.CompilationSubject.assertThat
+import com.google.testing.compile.Compiler.javac
+import com.google.testing.compile.JavaFileObjects
+import junit.framework.Assert.assertEquals
+import org.junit.Test
+import java.io.StringWriter
+import javax.tools.JavaFileObject
+import javax.tools.StandardLocation.CLASS_OUTPUT
+
+/**
+ * Tests for [IntDefProcessor]
+ */
+class IntDefProcessorTest {
+    private val mAnnotations = arrayOf<JavaFileObject>(
+            JavaFileObjects.forSourceLines("android.annotation.IntDef",
+                    "package android.annotation;",
+                    "import java.lang.annotation.Retention;",
+                    "import java.lang.annotation.Target;",
+                    "import static java.lang.annotation.ElementType.ANNOTATION_TYPE;",
+                    "import static java.lang.annotation.RetentionPolicy.SOURCE;",
+                    "@Retention(SOURCE)",
+                    "@Target({ANNOTATION_TYPE})",
+                    "public @interface IntDef {",
+                    "    String[] prefix() default {};",
+                    "    String[] suffix() default {};",
+                    "    int[] value() default {};",
+                    "    boolean flag() default false;",
+                    "}")
+    )
+
+    @Test
+    public fun annotationProcessorGeneratesMapping() {
+        val sources: Array<JavaFileObject> = arrayOf(
+                JavaFileObjects.forSourceLines(
+                        "com.android.server.accessibility.magnification.MagnificationGestureMatcher",
+                        "package com.android.server.accessibility.magnification;",
+                        "import android.annotation.IntDef;",
+                        "import java.lang.annotation.Retention;",
+                        "import java.lang.annotation.RetentionPolicy;",
+                        "class MagnificationGestureMatcher {",
+                        "    private static final int GESTURE_BASE = 100;",
+                        "    public static final int GESTURE_TWO_FINGER_DOWN = GESTURE_BASE + 1;",
+                        "    public static final int GESTURE_SWIPE = GESTURE_BASE + 2;",
+                        "    @IntDef(prefix = {\"GESTURE_MAGNIFICATION_\"}, value = {",
+                        "            GESTURE_TWO_FINGER_DOWN,",
+                        "            GESTURE_SWIPE",
+                        "    })",
+                        "    @Retention(RetentionPolicy.SOURCE)",
+                        "    @interface GestureId {}",
+                        "}"
+                ),
+                JavaFileObjects.forSourceLines(
+                        "android.service.storage.ExternalStorageService",
+                        "package android.service.storage;",
+                        "import android.annotation.IntDef;",
+                        "import java.lang.annotation.Retention;",
+                        "import java.lang.annotation.RetentionPolicy;",
+                        "class MagnificationGestureMatcher {",
+                        "    public static final int FLAG_SESSION_TYPE_FUSE = 1 << 0;",
+                        "    public static final int FLAG_SESSION_ATTRIBUTE_INDEXABLE = 1 << 1;",
+                        "    @IntDef(flag = true, prefix = {\"FLAG_SESSION_\"},",
+                        "        value = {FLAG_SESSION_TYPE_FUSE, FLAG_SESSION_ATTRIBUTE_INDEXABLE})",
+                        "    @Retention(RetentionPolicy.SOURCE)",
+                        "    public @interface SessionFlag {}",
+                        "}"
+                )
+        )
+
+        val expectedFile = """
+            {
+              "com.android.server.accessibility.magnification.MagnificationGestureMatcher.GestureId": {
+                "flag": false,
+                "values": {
+                  "101": "GESTURE_TWO_FINGER_DOWN",
+                  "102": "GESTURE_SWIPE"
+                }
+              },
+              "android.service.storage.MagnificationGestureMatcher.SessionFlag": {
+                "flag": true,
+                "values": {
+                  "1": "FLAG_SESSION_TYPE_FUSE",
+                  "2": "FLAG_SESSION_ATTRIBUTE_INDEXABLE"
+                }
+              }
+            }
+
+        """.trimIndent()
+
+        val filesToCompile = concat(mAnnotations, sources, JavaFileObject::class.java)
+
+        val compilation = javac()
+                .withProcessors(IntDefProcessor())
+                .compile(filesToCompile.toMutableList())
+
+        assertThat(compilation).succeeded()
+        assertThat(compilation).generatedFile(CLASS_OUTPUT, "com.android.winscope",
+                "intDefMapping.json").contentsAsUtf8String().isEqualTo(expectedFile)
+    }
+
+    @Test
+    public fun serializesMappingCorrectly() {
+        val map = linkedMapOf(
+            "SimpleIntDef" to IntDefMapping(linkedMapOf(
+                0x0001 to "VAL_1",
+                0x0002 to "VAL_2",
+                0x0003 to "VAL_3"
+            ), flag = false),
+            "Flags" to IntDefMapping(linkedMapOf(
+                0b0001 to "PRIVATE_FLAG_1",
+                0b0010 to "PRIVATE_FLAG_2",
+                0b0100 to "PRIVATE_FLAG_3"
+            ), flag = true)
+        )
+
+        val writer = StringWriter()
+        IntDefProcessor.serializeTo(map, writer)
+
+        val actualOutput = writer.toString()
+        val expectedOutput = """
+            {
+              "SimpleIntDef": {
+                "flag": false,
+                "values": {
+                  "1": "VAL_1",
+                  "2": "VAL_2",
+                  "3": "VAL_3"
+                }
+              },
+              "Flags": {
+                "flag": true,
+                "values": {
+                  "1": "PRIVATE_FLAG_1",
+                  "2": "PRIVATE_FLAG_2",
+                  "4": "PRIVATE_FLAG_3"
+                }
+              }
+            }
+            
+        """.trimIndent()
+
+        assertEquals(actualOutput, expectedOutput)
+    }
+}
\ No newline at end of file