Merge "Preload on css resources"
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index eea0cc3..5425774 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -121,6 +121,27 @@
 +
 Default is `ALL`.
 
+[[accounts.defaultDisplayName]]accounts.defaultDisplayName::
++
+If a user account does not have a display name set, which is the normal
+case, then this configuration value chooses the strategy how to choose
+the display name. Note that this strategy is not applied by the backend.
+If the AccountInfo has the display name unset, then the client has to
+apply this strategy.
++
+If `FULL_NAME`, then the (full) name of the user is chosen from
+link:rest-api-accounts.html#account-info[AccountInfo].
++
+If `FIRST_NAME`, then the first word (i.e. everything until first
+whitespace character) of the (full) name of the user is chosen from
+link:rest-api-accounts.html#account-info[AccountInfo].
++
+If `USERNAME`, then the username of the user is chosen from
+link:rest-api-accounts.html#account-info[AccountInfo]. If that is not
+set, then the (full) name will be used.
++
+Default is `FULL_NAME`.
+
 [[addreviewer]]
 === Section addreviewer
 
diff --git a/Documentation/rest-api-config.txt b/Documentation/rest-api-config.txt
index 828674f..2f72340 100644
--- a/Documentation/rest-api-config.txt
+++ b/Documentation/rest-api-config.txt
@@ -1419,10 +1419,13 @@
 
 [options="header",cols="1,6"]
 |=============================
-|Field Name           |Description
-|`visibility`         |
+|Field Name            |Description
+|`visibility`          |
 link:config-gerrit.html#accounts.visibility[Visibility setting for
 accounts].
+|`default_display_name`|The default strategy for choosing the display
+name in the UI, see also
+link:config-gerrit.html#accounts.defaultDisplayName[gerrit.config].
 |=============================
 
 [[auth-info]]
diff --git a/java/com/google/gerrit/extensions/common/AccountDefaultDisplayName.java b/java/com/google/gerrit/extensions/common/AccountDefaultDisplayName.java
new file mode 100644
index 0000000..44d6c00
--- /dev/null
+++ b/java/com/google/gerrit/extensions/common/AccountDefaultDisplayName.java
@@ -0,0 +1,40 @@
+// 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 com.google.gerrit.extensions.common;
+
+/**
+ * Fallback rule for choosing a display name, if it is not explicitly set. This rule will not be
+ * applied by the backend, but should be applied by the user interface.
+ */
+public enum AccountDefaultDisplayName {
+
+  /**
+   * If the display name for an account is not set, then the (full) name will be used as the display
+   * name in the user interface.
+   */
+  FULL_NAME,
+
+  /**
+   * If the display name for an account is not set, then the first name (i.e. full name until first
+   * whitespace character) will be used as the display name in the user interface.
+   */
+  FIRST_NAME,
+
+  /**
+   * If the display name for an account is not set, then the username will be used as the display
+   * name in the user interface. If the username is also not set, then the (full) name will be used.
+   */
+  USERNAME
+}
diff --git a/java/com/google/gerrit/extensions/common/AccountInfo.java b/java/com/google/gerrit/extensions/common/AccountInfo.java
index 803225e..2a3d260 100644
--- a/java/com/google/gerrit/extensions/common/AccountInfo.java
+++ b/java/com/google/gerrit/extensions/common/AccountInfo.java
@@ -35,9 +35,11 @@
 
   /**
    * The display name of the user. This allows users to control how their name is displayed in the
-   * UI. It will likely be unset for most users. Host admins will just choose a default (full name,
-   * user name, first name, ...) for all users, and this account property is just a way to opt out
-   * of the host wide default strategy of choosing the display name.
+   * UI. It will likely be unset for most users. This account property is just a way to opt out of
+   * the host wide default strategy of choosing the display name, see
+   * accounts.accountDefaultDisplayName in the server config. The default strategy is not applied by
+   * the backend. The display name will just be left unset, and the client has to load and apply the
+   * default strategy.
    */
   public String displayName;
 
diff --git a/java/com/google/gerrit/extensions/common/AccountsInfo.java b/java/com/google/gerrit/extensions/common/AccountsInfo.java
index a2a4826..d669578 100644
--- a/java/com/google/gerrit/extensions/common/AccountsInfo.java
+++ b/java/com/google/gerrit/extensions/common/AccountsInfo.java
@@ -22,4 +22,7 @@
 public class AccountsInfo {
   /** The value of the {@code accounts.visibility} parameter in {@code gerrit.config}. */
   public AccountVisibility visibility;
+
+  /** The value of the {@code accounts.visibility} parameter in {@code gerrit.config}. */
+  public AccountDefaultDisplayName defaultDisplayName;
 }
diff --git a/java/com/google/gerrit/server/config/GerritGlobalModule.java b/java/com/google/gerrit/server/config/GerritGlobalModule.java
index 3914205..276d57c 100644
--- a/java/com/google/gerrit/server/config/GerritGlobalModule.java
+++ b/java/com/google/gerrit/server/config/GerritGlobalModule.java
@@ -22,6 +22,7 @@
 import com.google.gerrit.extensions.api.projects.CommentLinkInfo;
 import com.google.gerrit.extensions.auth.oauth.OAuthLoginProvider;
 import com.google.gerrit.extensions.auth.oauth.OAuthTokenEncrypter;
+import com.google.gerrit.extensions.common.AccountDefaultDisplayName;
 import com.google.gerrit.extensions.common.AccountVisibility;
 import com.google.gerrit.extensions.config.CapabilityDefinition;
 import com.google.gerrit.extensions.config.CloneCommand;
@@ -269,6 +270,9 @@
     factory(InboundEmailRejectionSender.Factory.class);
     bind(PermissionCollection.Factory.class);
     bind(AccountVisibility.class).toProvider(AccountVisibilityProvider.class).in(SINGLETON);
+    AccountDefaultDisplayName accountDefaultDisplayName =
+        cfg.getEnum("accounts", null, "defaultDisplayName", AccountDefaultDisplayName.FULL_NAME);
+    bind(AccountDefaultDisplayName.class).toInstance(accountDefaultDisplayName);
     factory(ProjectOwnerGroupsProvider.Factory.class);
     factory(SubmitRuleEvaluator.Factory.class);
 
diff --git a/java/com/google/gerrit/server/restapi/config/GetServerInfo.java b/java/com/google/gerrit/server/restapi/config/GetServerInfo.java
index bbe38a3..0f1369c 100644
--- a/java/com/google/gerrit/server/restapi/config/GetServerInfo.java
+++ b/java/com/google/gerrit/server/restapi/config/GetServerInfo.java
@@ -20,6 +20,7 @@
 import com.google.common.base.Strings;
 import com.google.common.collect.Lists;
 import com.google.gerrit.common.data.ContributorAgreement;
+import com.google.gerrit.extensions.common.AccountDefaultDisplayName;
 import com.google.gerrit.extensions.common.AccountsInfo;
 import com.google.gerrit.extensions.common.AuthInfo;
 import com.google.gerrit.extensions.common.ChangeConfigInfo;
@@ -74,6 +75,7 @@
 public class GetServerInfo implements RestReadView<ConfigResource> {
   private final Config config;
   private final AccountVisibilityProvider accountVisibilityProvider;
+  private final AccountDefaultDisplayName accountDefaultDisplayName;
   private final AuthConfig authConfig;
   private final Realm realm;
   private final PluginMapContext<DownloadScheme> downloadSchemes;
@@ -96,6 +98,7 @@
   public GetServerInfo(
       @GerritServerConfig Config config,
       AccountVisibilityProvider accountVisibilityProvider,
+      AccountDefaultDisplayName accountDefaultDisplayName,
       AuthConfig authConfig,
       Realm realm,
       PluginMapContext<DownloadScheme> downloadSchemes,
@@ -115,6 +118,7 @@
       SitePaths sitePaths) {
     this.config = config;
     this.accountVisibilityProvider = accountVisibilityProvider;
+    this.accountDefaultDisplayName = accountDefaultDisplayName;
     this.authConfig = authConfig;
     this.realm = realm;
     this.downloadSchemes = downloadSchemes;
@@ -156,6 +160,7 @@
   private AccountsInfo getAccountsInfo() {
     AccountsInfo info = new AccountsInfo();
     info.visibility = accountVisibilityProvider.get();
+    info.defaultDisplayName = accountDefaultDisplayName;
     return info;
   }
 
diff --git a/javatests/com/google/gerrit/acceptance/rest/config/ServerInfoIT.java b/javatests/com/google/gerrit/acceptance/rest/config/ServerInfoIT.java
index 14a04cd..802c5b3 100644
--- a/javatests/com/google/gerrit/acceptance/rest/config/ServerInfoIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/config/ServerInfoIT.java
@@ -25,6 +25,7 @@
 import com.google.gerrit.extensions.api.plugins.InstallPluginInput;
 import com.google.gerrit.extensions.client.AccountFieldName;
 import com.google.gerrit.extensions.client.AuthType;
+import com.google.gerrit.extensions.common.AccountDefaultDisplayName;
 import com.google.gerrit.extensions.common.AccountVisibility;
 import com.google.gerrit.extensions.common.ServerInfo;
 import com.google.gerrit.server.config.AllProjectsNameProvider;
@@ -41,6 +42,7 @@
   @Test
   // accounts
   @GerritConfig(name = "accounts.visibility", value = "VISIBLE_GROUP")
+  @GerritConfig(name = "accounts.defaultDisplayName", value = "FIRST_NAME")
 
   // auth
   @GerritConfig(name = "auth.type", value = "HTTP")
@@ -82,6 +84,7 @@
 
     // accounts
     assertThat(i.accounts.visibility).isEqualTo(AccountVisibility.VISIBLE_GROUP);
+    assertThat(i.accounts.defaultDisplayName).isEqualTo(AccountDefaultDisplayName.FIRST_NAME);
 
     // auth
     assertThat(i.auth.authType).isEqualTo(AuthType.HTTP);