Merge "acloud: Define new common_hw_property_map in internal config."
diff --git a/internal/proto/internal_config.proto b/internal/proto/internal_config.proto
index dbe6499..cfb72a4 100755
--- a/internal/proto/internal_config.proto
+++ b/internal/proto/internal_config.proto
@@ -95,4 +95,7 @@
   // [GOLDFISH only] The emulator build target: "sdk_tools_linux".
   // It's very unlikely that this will ever change.
   optional string emulator_build_target = 17;
+
+  // Common hw property
+  map <string, string>  common_hw_property_map = 18;
 }
diff --git a/internal/proto/user_config.proto b/internal/proto/user_config.proto
index 06b5af8..1d765e1 100755
--- a/internal/proto/user_config.proto
+++ b/internal/proto/user_config.proto
@@ -76,4 +76,7 @@
   // Account information for accessing Cloud API
   // This is the new way to provide service account auth.
   optional string service_account_json_private_key_path = 20;
+
+  // Desired hw_property
+  optional string hw_property = 21;
 }
diff --git a/public/config.py b/public/config.py
index 2249ed0..95b3369 100755
--- a/public/config.py
+++ b/public/config.py
@@ -51,6 +51,7 @@
 # pylint: disable=no-name-in-module,import-error
 from acloud.internal.proto import internal_config_pb2
 from acloud.internal.proto import user_config_pb2
+from acloud.create import create_args
 from acloud.public import errors
 
 _CONFIG_DATA_PATH = os.path.join(
@@ -168,6 +169,9 @@
             usr_cfg.stable_goldfish_host_image_project or
             internal_cfg.default_usr_cfg.stable_goldfish_host_image_project)
 
+        self.common_hw_property_map = internal_cfg.common_hw_property_map
+        self.hw_property = usr_cfg.hw_property
+
         # Verify validity of configurations.
         self.Verify()
 
@@ -177,7 +181,7 @@
         Args:
             parsed_args: Args parsed from command line.
         """
-        if parsed_args.which == "create" and parsed_args.spec:
+        if parsed_args.which == create_args.CMD_CREATE and parsed_args.spec:
             if not self.resolution:
                 self.resolution = self.device_resolution_map.get(
                     parsed_args.spec, "")
@@ -191,6 +195,9 @@
                 parsed_args.service_account_json_private_key_path)
         if parsed_args.which == "create_gf" and parsed_args.base_image:
             self.stable_goldfish_host_image_name = parsed_args.base_image
+        if parsed_args.which == create_args.CMD_CREATE and not self.hw_property:
+            self.hw_property = self.common_hw_property_map.get(
+                parsed_args.flavor, "")
 
     def Verify(self):
         """Verify configuration fields."""
diff --git a/public/config_test.py b/public/config_test.py
index 781244b..865ed1a 100644
--- a/public/config_test.py
+++ b/public/config_test.py
@@ -48,6 +48,7 @@
     key: "metadata_1"
     value: "metadata_value_1"
 }
+hw_property: "cpu:3,resolution:1080x1920,dpi=480,memory=4g,disk=10g"
 """
 
     INTERNAL_CONFIG = """
@@ -94,6 +95,11 @@
     key: "aosp-master"
     value: 0
 }
+
+common_hw_property_map {
+  key: "phone"
+  value: "cpu:2,resolution:1080x1920,dpi=420,memory=4g,disk=8g"
+}
 """
 
     def setUp(self):
@@ -124,6 +130,8 @@
         self.assertEqual(
             {key: val for key, val in cfg.metadata_variable.iteritems()},
             {"metadata_1": "metadata_value_1"})
+        self.assertEqual(cfg.hw_property,
+                         "cpu:3,resolution:1080x1920,dpi=480,memory=4g,disk=10g")
 
     # pylint: disable=protected-access
     @mock.patch("os.path.exists")
@@ -220,6 +228,11 @@
                          "fake_stable_goldfish_host_image_project")
         self.assertEqual(cfg.emulator_build_target, "sdk_tools_linux")
 
+        # hw property
+        self.assertEqual(
+            {key: val for key, val in cfg.common_hw_property_map.iteritems()},
+            {"phone": "cpu:2,resolution:1080x1920,dpi=420,memory=4g,disk=8g"})
+
     def testLoadConfigFails(self):
         """Test loading a bad file."""
         self.config_file.read.return_value = "malformed text"
@@ -227,6 +240,34 @@
             config.AcloudConfigManager.LoadConfigFromProtocolBuffer(
                 self.config_file, internal_config_pb2.InternalConfig)
 
+    def testOverrideWithHWProperty(self):
+        """Test override hw property by flavor type."""
+        # initial config with test config.
+        self.config_file.read.return_value = self.INTERNAL_CONFIG
+        internal_cfg = config.AcloudConfigManager.LoadConfigFromProtocolBuffer(
+            self.config_file, internal_config_pb2.InternalConfig)
+        self.config_file.read.return_value = self.USER_CONFIG
+        usr_cfg = config.AcloudConfigManager.LoadConfigFromProtocolBuffer(
+            self.config_file, user_config_pb2.UserConfig)
+        cfg = config.AcloudConfig(usr_cfg, internal_cfg)
+
+        # test override with an exist flavor.
+        cfg.hw_property = None
+        args = mock.MagicMock()
+        args.flavor = "phone"
+        args.which = "create"
+        cfg.OverrideWithArgs(args)
+        self.assertEqual(cfg.hw_property,
+                         "cpu:2,resolution:1080x1920,dpi=420,memory=4g,disk=8g")
+
+        # test override with a nonexistent flavor.
+        cfg.hw_property = None
+        args = mock.MagicMock()
+        args.flavor = "non-exist-flavor"
+        args.which = "create"
+        cfg.OverrideWithArgs(args)
+        self.assertEqual(cfg.hw_property, "")
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/public/data/default.config b/public/data/default.config
index f81c756..581d5b0 100644
--- a/public/data/default.config
+++ b/public/data/default.config
@@ -44,6 +44,34 @@
   }
 }
 
+# Below are common HW properties, the values also could be referred in the
+# AVD manager of android sdk.
+# https://developer.android.com/studio/run/managing-avds
+common_hw_property_map {
+  key: "phone"
+  value: "cpu:2,resolution:1080x1920,dpi=240,memory=4g,disk=4g"
+}
+
+common_hw_property_map {
+  key: "auto"
+  value: "cpu:2,resolution:1280x800,dpi=160,memory=4g,disk=4g"
+}
+
+common_hw_property_map {
+  key: "wear"
+  value: "cpu:2,resolution:320x320,dpi=240,memory=2g,disk=2g"
+}
+
+common_hw_property_map {
+  key: "tablet"
+  value: "cpu:2,resolution:2560x1800,dpi=320,memory=4g,disk=4g"
+}
+
+common_hw_property_map {
+  key: "tv"
+  value: "cpu:2,resolution:1080x1920,dpi=320,memory=4g,disk=4g"
+}
+
 # Device resolution
 device_resolution_map {
   key: "nexus5"