Add default cloud device configuration.

Change-Id: I70611875e6c0c2cdf49cfa0dbb0acdca99158a17
diff --git a/google-cloud-testing.iml b/google-cloud-testing.iml
index f765ecb..03b96e1 100644
--- a/google-cloud-testing.iml
+++ b/google-cloud-testing.iml
@@ -54,7 +54,7 @@
     <orderEntry type="module-library">
       <library>
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/lib/google-api-services-testing-v1-rev20150218-1.19.1.jar!/" />
+          <root url="jar://$MODULE_DIR$/lib/google-api-services-testing-v1-rev20150323-1.20.0.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES />
diff --git a/lib/google-api-services-testing-v1-rev20150218-1.19.1.jar b/lib/google-api-services-testing-v1-rev20150218-1.19.1.jar
deleted file mode 100644
index 76d7d5e..0000000
--- a/lib/google-api-services-testing-v1-rev20150218-1.19.1.jar
+++ /dev/null
Binary files differ
diff --git a/lib/google-api-services-testing-v1-rev20150323-1.20.0.jar b/lib/google-api-services-testing-v1-rev20150323-1.20.0.jar
new file mode 100644
index 0000000..26f6c92
--- /dev/null
+++ b/lib/google-api-services-testing-v1-rev20150323-1.20.0.jar
Binary files differ
diff --git a/src/com/google/gct/testing/CloudConfigurationImpl.java b/src/com/google/gct/testing/CloudConfigurationImpl.java
index 0d46a1e..eaa89ea 100644
--- a/src/com/google/gct/testing/CloudConfigurationImpl.java
+++ b/src/com/google/gct/testing/CloudConfigurationImpl.java
@@ -32,7 +32,8 @@
 
 public class CloudConfigurationImpl extends CloudConfiguration {
 
-  public static final int ALL_ID = Integer.MAX_VALUE;
+  public static final int ALL_CONFIGURATION_ID = Integer.MAX_VALUE;
+  public static final int DEFAULT_DEVICE_CONFIGURATION_ID = Integer.MAX_VALUE - 1;
 
   private static int nextAvailableID = 1;
 
@@ -52,7 +53,7 @@
   OrientationDimension orientationDimension;
 
   public CloudConfigurationImpl(int id, String name, Kind kind, Icon icon, AndroidFacet facet) {
-    if (id != ALL_ID && id >= nextAvailableID) {
+    if (!isPredefinedId(id) && id >= nextAvailableID) {
       nextAvailableID = id + 1;
     }
     this.id = id;
@@ -64,6 +65,10 @@
     createDimensions();
   }
 
+  private boolean isPredefinedId(int id) {
+    return id == ALL_CONFIGURATION_ID || id == DEFAULT_DEVICE_CONFIGURATION_ID;
+  }
+
   public CloudConfigurationImpl(String name, Kind kind, Icon icon, AndroidFacet facet) {
     this(nextAvailableID++, name, kind, icon, facet);
   }
diff --git a/src/com/google/gct/testing/CloudConfigurationProviderImpl.java b/src/com/google/gct/testing/CloudConfigurationProviderImpl.java
index 2a07984..e71b84e 100644
--- a/src/com/google/gct/testing/CloudConfigurationProviderImpl.java
+++ b/src/com/google/gct/testing/CloudConfigurationProviderImpl.java
@@ -115,11 +115,19 @@
   }
 
   private List<? extends CloudConfiguration> getDefaultConfigurations(AndroidFacet facet, Kind kind) {
-    if (kind == SINGLE_DEVICE) { // No default single device configurations.
-      return Lists.newArrayList();
+    if (kind == SINGLE_DEVICE) {
+      CloudConfigurationImpl defaultConfiguration = new CloudConfigurationImpl(
+        CloudConfigurationImpl.DEFAULT_DEVICE_CONFIGURATION_ID, "Default Device", SINGLE_DEVICE, AndroidIcons.Display, facet);
+      defaultConfiguration.deviceDimension.enable(DeviceDimension.getDefaultDevice());
+      defaultConfiguration.apiDimension.enable(ApiDimension.getDefaultApi());
+      defaultConfiguration.languageDimension.enable(LanguageDimension.getDefaultLanguage());
+      defaultConfiguration.orientationDimension.enable(OrientationDimension.getDefaultOrientation());
+      defaultConfiguration.setNonEditable();
+      return ImmutableList.of(defaultConfiguration);
     }
+
     CloudConfigurationImpl allConfiguration =
-      new CloudConfigurationImpl(CloudConfigurationImpl.ALL_ID, "All Compatible", MATRIX, AndroidIcons.Display, facet);
+      new CloudConfigurationImpl(CloudConfigurationImpl.ALL_CONFIGURATION_ID, "All Compatible", MATRIX, AndroidIcons.Display, facet);
     allConfiguration.deviceDimension.enableAll();
     allConfiguration.apiDimension.enableAll();
     allConfiguration.languageDimension.enableAll();
@@ -137,7 +145,8 @@
     List<CloudPersistentConfiguration> cloudPersistentConfigurations =
       CloudCustomPersistentConfigurations.getInstance(facet.getModule()).getState().myCloudPersistentConfigurations;
     return Lists.newArrayList(Iterables.concat(deserializeConfigurations(cloudPersistentConfigurations, true, facet),
-                                               getDefaultConfigurations(facet, MATRIX)));
+                                               getDefaultConfigurations(facet, MATRIX),
+                                               getDefaultConfigurations(facet, SINGLE_DEVICE)));
   }
 
   @Nullable
diff --git a/src/com/google/gct/testing/dimension/ApiDimension.java b/src/com/google/gct/testing/dimension/ApiDimension.java
index 13191b6..f4f0d18 100644
--- a/src/com/google/gct/testing/dimension/ApiDimension.java
+++ b/src/com/google/gct/testing/dimension/ApiDimension.java
@@ -60,9 +60,10 @@
   //  ImmutableSet.of(KITKAT_19, JELLY_BEAN_18, JELLY_BEAN_17, JELLY_BEAN_16, ICE_CREAM_SANDWICH_15, ICE_CREAM_SANDWICH_14);
 
   private static ImmutableList<ApiLevel> FULL_DOMAIN;
-
+  private static ApiLevel defaultApi;
   private final int minSdkVersion;
 
+
   public ApiDimension(CloudConfigurationImpl googleCloudTestingConfiguration, AndroidFacet facet) {
     super(googleCloudTestingConfiguration);
     minSdkVersion = facet.getAndroidModuleInfo().getMinSdkVersion().getApiLevel();
@@ -109,7 +110,13 @@
           details.put("Release date", version.getReleaseDate());
           Distribution distribution = version.getDistribution();
           details.put("Market share", distribution == null ? "???" : distribution.getMarketShare() + "%");
-          apiLevels.add(new ApiLevel(version.getId(), version.getCodeName(), version.getVersionString(), version.getApiLevel(), details));
+          ApiLevel apiLevel =
+            new ApiLevel(version.getId(), version.getCodeName(), version.getVersionString(), version.getApiLevel(), details);
+          apiLevels.add(apiLevel);
+          List<String> tags = version.getTags();
+          if (tags != null && tags.contains("default")) {
+            defaultApi = apiLevel;
+          }
         }
       }
       // Sort them in descending order of api version.
@@ -119,6 +126,13 @@
     return FULL_DOMAIN;
   }
 
+  public static ApiLevel getDefaultApi() {
+    if (defaultApi == null) {
+      getFullDomain();
+    }
+    return defaultApi;
+  }
+
   @Override
   public String getDisplayName() {
     return DISPLAY_NAME;
diff --git a/src/com/google/gct/testing/dimension/DeviceDimension.java b/src/com/google/gct/testing/dimension/DeviceDimension.java
index aef09c2..a5913ec 100644
--- a/src/com/google/gct/testing/dimension/DeviceDimension.java
+++ b/src/com/google/gct/testing/dimension/DeviceDimension.java
@@ -40,7 +40,7 @@
   //  new Device("GalaxyS5", "Samsung", "Galaxy S5", ImmutableMap.of("RAM", "2GB", "Disk", "16-32GB", "Display", "1080x1920", "Min API Level", "19"));
 
   private static ImmutableList<Device> FULL_DOMAIN;
-
+  private static Device defaultDevice;
 
   public DeviceDimension(CloudConfigurationImpl googleCloudTestingConfiguration) {
     super(googleCloudTestingConfiguration);
@@ -59,7 +59,12 @@
         for (AndroidModel model : androidDeviceCatalog.getModels()) {
           Map<String, String> details = new HashMap<String, String>();
           details.put("Display", model.getScreenX() + "x" + model.getScreenY());
-          fullDomainBuilder.add(new Device(model.getId(), model.getName(), model.getManufacturer(), model.getForm(), details));
+          Device device = new Device(model.getId(), model.getName(), model.getManufacturer(), model.getForm(), details);
+          fullDomainBuilder.add(device);
+          List<String> tags = model.getTags();
+          if (tags != null && tags.contains("default")) {
+            defaultDevice = device;
+          }
         }
       }
       FULL_DOMAIN = fullDomainBuilder.build();
@@ -68,6 +73,13 @@
     return FULL_DOMAIN;
   }
 
+  public static Device getDefaultDevice() {
+    if (defaultDevice == null) {
+      getFullDomain();
+    }
+    return defaultDevice;
+  }
+
   @Override
   public String getDisplayName() {
     return DISPLAY_NAME;
diff --git a/src/com/google/gct/testing/dimension/LanguageDimension.java b/src/com/google/gct/testing/dimension/LanguageDimension.java
index 21917ff..0aef5e7 100644
--- a/src/com/google/gct/testing/dimension/LanguageDimension.java
+++ b/src/com/google/gct/testing/dimension/LanguageDimension.java
@@ -41,14 +41,16 @@
 
   private static ImmutableList<Language> FULL_DOMAIN;
 
-  private static final Language defaultLanguage;
+  private static final Language localDefaultLanguage;
 
   static {
     //TODO: Make sure we do not "guess" incorrectly the user's language.
     Language userLanguage = getLanguage(System.getProperty("user.language"));
-    defaultLanguage = userLanguage != null ? new Language(userLanguage, true) : null;
+    localDefaultLanguage = userLanguage != null ? new Language(userLanguage, true) : null;
   }
 
+  private static Language defaultLanguage;
+
   private final List<Language> supportedLanguages;
 
 
@@ -67,9 +69,13 @@
         return lang1.getResultsViewerDisplayName().compareTo(lang2.getResultsViewerDisplayName());
       }
     });
-    if (defaultLanguage != null) {
-      supportedLanguages.remove(defaultLanguage);
-      supportedLanguages.add(0, defaultLanguage);
+    addLocalDefaultLocale();
+  }
+
+  private void addLocalDefaultLocale() {
+    if (localDefaultLanguage != null) {
+      supportedLanguages.remove(localDefaultLanguage);
+      supportedLanguages.add(0, localDefaultLanguage);
     }
   }
 
@@ -82,10 +88,7 @@
         return locales.contains(input.getId());
       }
     }));
-    if (defaultLanguage != null) {
-      supportedLanguages.remove(defaultLanguage);
-      supportedLanguages.add(0, defaultLanguage);
-    }
+    addLocalDefaultLocale();
   }
 
   private List<String> getLocales(AndroidFacet facet) {
@@ -128,7 +131,12 @@
       AndroidDeviceCatalog androidDeviceCatalog = getAndroidDeviceCatalog();
       if (androidDeviceCatalog != null) {
         for (Locale locale : androidDeviceCatalog.getRuntimeConfiguration().getLocales()) {
-          fullDomainBuilder.add(new Language(locale.getId(), locale.getName(), locale.getRegion(), false));
+          Language language = new Language(locale.getId(), locale.getName(), locale.getRegion(), false);
+          fullDomainBuilder.add(language);
+          List<String> tags = locale.getTags();
+          if (tags != null && tags.contains("default")) {
+            defaultLanguage = language;
+          }
         }
       }
       FULL_DOMAIN = fullDomainBuilder.build();
@@ -137,6 +145,13 @@
     return FULL_DOMAIN;
   }
 
+  public static Language getDefaultLanguage() {
+    if (defaultLanguage == null) {
+      getFullDomain();
+    }
+    return defaultLanguage;
+  }
+
   public static Language getLanguage(final String locale) {
     try {
       return Iterables.find(getFullDomain(), new Predicate<Language>() {
@@ -170,22 +185,22 @@
     private final String id;
     private final String name;
     private final String region;
-    private final boolean isDefault;
+    private final boolean isLocalDefault;
 
-    public Language(Language language, boolean isDefault) {
-      this(language.id, language.name, language.region, isDefault);
+    public Language(Language language, boolean isLocalDefault) {
+      this(language.id, language.name, language.region, isLocalDefault);
     }
 
     //public Language(String id, String name, String region) {
     //  this(id, name, region, false);
     //}
 
-    public Language(String id, String name, String region, boolean isDefault) {
+    public Language(String id, String name, String region, boolean isLocalDefault) {
       this.id = id;
       this.name = name;
       this.region = region;
       this.details = ImmutableMap.of();
-      this.isDefault = isDefault;
+      this.isLocalDefault = isLocalDefault;
     }
 
     @Override
@@ -196,7 +211,7 @@
 
     @Override
     public String getConfigurationDialogDisplayName() {
-      return getResultsViewerDisplayName() + (isDefault ? " - default" : "");
+      return getResultsViewerDisplayName() + (isLocalDefault ? " - default" : "");
     }
 
     @Override
diff --git a/src/com/google/gct/testing/dimension/OrientationDimension.java b/src/com/google/gct/testing/dimension/OrientationDimension.java
index 4d7ec04..47de3e8 100644
--- a/src/com/google/gct/testing/dimension/OrientationDimension.java
+++ b/src/com/google/gct/testing/dimension/OrientationDimension.java
@@ -34,6 +34,7 @@
   //public static final Orientation LANDSCAPE = new Orientation("landscape", "Landscape");
 
   private static ImmutableList<Orientation> FULL_DOMAIN;
+  private static Orientation defaultOrientation;
 
   public OrientationDimension(CloudConfigurationImpl googleCloudTestingConfiguration) {
     super(googleCloudTestingConfiguration);
@@ -49,10 +50,15 @@
       ImmutableList.Builder<Orientation> fullDomainBuilder = new ImmutableList.Builder<Orientation>();
       AndroidDeviceCatalog androidDeviceCatalog = getAndroidDeviceCatalog();
       if (androidDeviceCatalog != null) {
-        List<com.google.api.services.testing.model.Orientation> orientations =
+        List<com.google.api.services.testing.model.Orientation> modelOrientations =
           androidDeviceCatalog.getRuntimeConfiguration().getOrientations();
-        for (com.google.api.services.testing.model.Orientation orientation : orientations) {
-          fullDomainBuilder.add(new Orientation(orientation.getId(), orientation.getName()));
+        for (com.google.api.services.testing.model.Orientation modelOrientation : modelOrientations) {
+          Orientation orientation = new Orientation(modelOrientation.getId(), modelOrientation.getName());
+          fullDomainBuilder.add(orientation);
+          List<String> tags = modelOrientation.getTags();
+          if (tags != null && tags.contains("default")) {
+            defaultOrientation = orientation;
+          }
         }
       }
       FULL_DOMAIN = fullDomainBuilder.build();
@@ -61,6 +67,13 @@
     return FULL_DOMAIN;
   }
 
+  public static Orientation getDefaultOrientation() {
+    if (defaultOrientation == null) {
+      getFullDomain();
+    }
+    return defaultOrientation;
+  }
+
   @Override
   public String getDisplayName() {
     return DISPLAY_NAME;