ProtoLog: Cache the result of ProtoLogImpl.isEnabled(ProtoLogGroup)

We introduce a generated class ProtoLog$Cache, which contains a field
for each ProtoLogGroup to cache whether it is enabled or not.

This both makes lookup faster, and reduces code size.

Test: make droid
Change-Id: I581c87849c875918b182eff85996b6d19a6755ec
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 4f4e47a..3067beb 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -21,6 +21,7 @@
     cmd: "$(location protologtool) transform-protolog-calls " +
       "--protolog-class com.android.server.protolog.common.ProtoLog " +
       "--protolog-impl-class com.android.server.protolog.ProtoLogImpl " +
+      "--protolog-cache-class 'com.android.server.protolog.ProtoLog$$Cache' " +
       "--loggroups-class com.android.server.wm.ProtoLogGroup " +
       "--loggroups-jar $(location :services.core.wm.protologgroups) " +
       "--output-srcjar $(out) " +
diff --git a/services/core/java/com/android/server/protolog/ProtoLogImpl.java b/services/core/java/com/android/server/protolog/ProtoLogImpl.java
index 20bab55..bd46c0ae 100644
--- a/services/core/java/com/android/server/protolog/ProtoLogImpl.java
+++ b/services/core/java/com/android/server/protolog/ProtoLogImpl.java
@@ -45,7 +45,6 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.IllegalFormatConversionException;
 import java.util.TreeMap;
 import java.util.stream.Collectors;
@@ -57,8 +56,18 @@
 public class ProtoLogImpl {
     private static final TreeMap<String, IProtoLogGroup> LOG_GROUPS = new TreeMap<>();
 
+    /**
+     * A runnable to update the cached output of {@link #isEnabled}.
+     *
+     * Must be invoked after every action that could change the result of {@link #isEnabled}, eg.
+     * starting / stopping proto log, or enabling / disabling log groups.
+     */
+    static Runnable sCacheUpdater = () -> { };
+
     private static void addLogGroupEnum(IProtoLogGroup[] config) {
-        Arrays.stream(config).forEach(group -> LOG_GROUPS.put(group.name(), group));
+        for (IProtoLogGroup group : config) {
+            LOG_GROUPS.put(group.name(), group);
+        }
     }
 
     static {
@@ -303,6 +312,7 @@
             mProtoLogEnabled = true;
             mProtoLogEnabledLockFree = true;
         }
+        sCacheUpdater.run();
     }
 
     /**
@@ -327,6 +337,7 @@
                 throw new IllegalStateException("logging enabled while waiting for flush.");
             }
         }
+        sCacheUpdater.run();
     }
 
     /**
@@ -351,6 +362,7 @@
                 return -1;
             }
         }
+        sCacheUpdater.run();
         return 0;
     }