Merge "Add rest API endpoints for batch update submit requirements."
diff --git a/java/com/google/gerrit/entities/NotifyConfig.java b/java/com/google/gerrit/entities/NotifyConfig.java
index d3123c4..42baebc 100644
--- a/java/com/google/gerrit/entities/NotifyConfig.java
+++ b/java/com/google/gerrit/entities/NotifyConfig.java
@@ -19,6 +19,7 @@
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableSet;
 import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.gerrit.common.ConvertibleToProto;
 import com.google.gerrit.common.Nullable;
 import java.util.EnumSet;
 import java.util.Set;
@@ -31,6 +32,7 @@
     BCC
   }
 
+  @ConvertibleToProto
   public enum NotifyType {
     // sort by name, except 'ALL' which should stay last
     ABANDONED_CHANGES,
diff --git a/java/com/google/gerrit/server/account/ProjectWatches.java b/java/com/google/gerrit/server/account/ProjectWatches.java
index 86132d3..341b493 100644
--- a/java/com/google/gerrit/server/account/ProjectWatches.java
+++ b/java/com/google/gerrit/server/account/ProjectWatches.java
@@ -29,6 +29,7 @@
 import com.google.common.collect.Multimap;
 import com.google.common.collect.MultimapBuilder;
 import com.google.common.collect.Sets;
+import com.google.gerrit.common.ConvertibleToProto;
 import com.google.gerrit.common.Nullable;
 import com.google.gerrit.entities.Account;
 import com.google.gerrit.entities.NotifyConfig;
@@ -79,6 +80,7 @@
  */
 public class ProjectWatches {
   @AutoValue
+  @ConvertibleToProto
   public abstract static class ProjectWatchKey {
 
     public static ProjectWatchKey create(Project.NameKey project, @Nullable String filter) {
diff --git a/java/com/google/gerrit/server/git/WorkQueue.java b/java/com/google/gerrit/server/git/WorkQueue.java
index 6f904ea..60cbeed 100644
--- a/java/com/google/gerrit/server/git/WorkQueue.java
+++ b/java/com/google/gerrit/server/git/WorkQueue.java
@@ -636,15 +636,16 @@
 
     public void waitUntilReadyToStart(Task<?> task) {
       if (!listeners.isEmpty() && !isReadyToStart(task)) {
-        incrementCorePoolSizeBy(1);
         ParkedTask parkedTask = new ParkedTask(task);
         parked.offer(parkedTask);
         task.runningState.set(Task.State.PARKED);
+        incrementCorePoolSizeBy(1);
         try {
           parkedTask.latch.await();
         } catch (InterruptedException e) {
           logger.atSevere().withCause(e).log("Parked Task(%s) Interrupted", task);
           parked.remove(parkedTask);
+        } finally {
           incrementCorePoolSizeBy(-1);
         }
       }
@@ -702,7 +703,6 @@
       parked.addAll(notReady);
 
       if (ready != null) {
-        incrementCorePoolSizeBy(-1);
         ready.latch.countDown();
       }
     }
diff --git a/java/com/google/gerrit/server/schema/SchemaCreatorImpl.java b/java/com/google/gerrit/server/schema/SchemaCreatorImpl.java
index cf3948a..fcd2264 100644
--- a/java/com/google/gerrit/server/schema/SchemaCreatorImpl.java
+++ b/java/com/google/gerrit/server/schema/SchemaCreatorImpl.java
@@ -54,6 +54,8 @@
 // confusing and could stand to be reworked. Another smell is that this is an interface only for
 // testing purposes.
 public class SchemaCreatorImpl implements SchemaCreator {
+  public static final String BLOCKED_USERS = "Blocked Users";
+
   private final GitRepositoryManager repoManager;
   private final AllProjectsCreator allProjectsCreator;
   private final AllUsersCreator allUsersCreator;
@@ -92,7 +94,7 @@
     try (RefUpdateContext ctx = RefUpdateContext.open(RefUpdateType.INIT_REPO)) {
       GroupReference admins = createGroupReference("Administrators");
       GroupReference serviceUsers = createGroupReference(ServiceUserClassifier.SERVICE_USERS);
-      GroupReference blockedUsers = createGroupReference("Blocked Users");
+      GroupReference blockedUsers = createGroupReference(BLOCKED_USERS);
 
       AllProjectsInput allProjectsInput =
           AllProjectsInput.builder()
diff --git a/javatests/com/google/gerrit/acceptance/git/RefAdvertisementIT.java b/javatests/com/google/gerrit/acceptance/git/RefAdvertisementIT.java
index c18cd55..c9f469e 100644
--- a/javatests/com/google/gerrit/acceptance/git/RefAdvertisementIT.java
+++ b/javatests/com/google/gerrit/acceptance/git/RefAdvertisementIT.java
@@ -57,6 +57,7 @@
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackend.RefFilterOptions;
 import com.google.gerrit.server.query.change.ChangeData;
+import com.google.gerrit.server.schema.SchemaCreatorImpl;
 import com.google.gerrit.testing.ConfigSuite;
 import com.google.inject.Inject;
 import java.util.ArrayList;
@@ -120,7 +121,7 @@
   public void setUp() throws Exception {
     admins = adminGroupUuid();
     serviceUsers = groupUuid(ServiceUserClassifier.SERVICE_USERS);
-    blockedUsers = groupUuid("Blocked Users");
+    blockedUsers = groupUuid(SchemaCreatorImpl.BLOCKED_USERS);
     setUpPermissions();
     setUpChanges();
   }
diff --git a/javatests/com/google/gerrit/acceptance/rest/group/ListGroupsIT.java b/javatests/com/google/gerrit/acceptance/rest/group/ListGroupsIT.java
index e58757b..00d8f4e 100644
--- a/javatests/com/google/gerrit/acceptance/rest/group/ListGroupsIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/group/ListGroupsIT.java
@@ -20,6 +20,7 @@
 import com.google.gerrit.acceptance.RestResponse;
 import com.google.gerrit.extensions.common.GroupInfo;
 import com.google.gerrit.server.account.ServiceUserClassifier;
+import com.google.gerrit.server.schema.SchemaCreatorImpl;
 import com.google.gson.reflect.TypeToken;
 import java.util.Map;
 import org.junit.Test;
@@ -34,6 +35,7 @@
         newGson()
             .fromJson(response.getReader(), new TypeToken<Map<String, GroupInfo>>() {}.getType());
     assertThat(groupMap.keySet())
-        .containsExactly("Administrators", "Blocked Users", ServiceUserClassifier.SERVICE_USERS);
+        .containsExactly(
+            "Administrators", SchemaCreatorImpl.BLOCKED_USERS, ServiceUserClassifier.SERVICE_USERS);
   }
 }
diff --git a/javatests/com/google/gerrit/server/schema/AllProjectsCreatorTest.java b/javatests/com/google/gerrit/server/schema/AllProjectsCreatorTest.java
index 3fae3ad..089ceea 100644
--- a/javatests/com/google/gerrit/server/schema/AllProjectsCreatorTest.java
+++ b/javatests/com/google/gerrit/server/schema/AllProjectsCreatorTest.java
@@ -91,7 +91,7 @@
 
     GroupReference adminsGroup = createGroupReference("Administrators");
     GroupReference serviceUsersGroup = createGroupReference(ServiceUserClassifier.SERVICE_USERS);
-    GroupReference blockedUsersGroup = createGroupReference("Blocked Users");
+    GroupReference blockedUsersGroup = createGroupReference(SchemaCreatorImpl.BLOCKED_USERS);
     AllProjectsInput allProjectsInput =
         AllProjectsInput.builder()
             .administratorsGroup(adminsGroup)
@@ -165,7 +165,7 @@
   public void createAllProjectsWithoutInitializingDefaultSubmitRequirements() throws Exception {
     GroupReference adminsGroup = createGroupReference("Administrators");
     GroupReference serviceUsersGroup = createGroupReference(ServiceUserClassifier.SERVICE_USERS);
-    GroupReference blockedUsersGroup = createGroupReference("Blocked Users");
+    GroupReference blockedUsersGroup = createGroupReference(SchemaCreatorImpl.BLOCKED_USERS);
     AllProjectsInput allProjectsInput =
         AllProjectsInput.builder()
             .administratorsGroup(adminsGroup)
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts
index 68ab132..6f7e151 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts
@@ -945,6 +945,7 @@
   }
 
   private reportHintInteractionSaved() {
+    if (this.autocompleteAcceptedHints.length === 0) return;
     const content = this.messageText.trimEnd();
     const acceptedHintsConcatenated = this.autocompleteAcceptedHints.join('');
     const numExtraCharacters =
@@ -1444,7 +1445,7 @@
     );
     this.reportHintInteraction(
       Interaction.COMMENT_COMPLETION_SUGGESTION_FETCHED,
-      context
+      {...context, hasDraftChanged: this.messageText !== commentText}
     );
     if (!response?.completion) return;
     // Note that we are setting the cache value for `commentText` and getting the value
diff --git a/polygerrit-ui/app/utils/autocomplete-cache.ts b/polygerrit-ui/app/utils/autocomplete-cache.ts
index c8077ab..b1dba44 100644
--- a/polygerrit-ui/app/utils/autocomplete-cache.ts
+++ b/polygerrit-ui/app/utils/autocomplete-cache.ts
@@ -24,6 +24,8 @@
   acceptedSuggestionsCount?: number;
   totalAcceptedCharacters?: number;
   savedDraftLength?: number;
+
+  hasDraftChanged?: boolean;
 }
 
 /**