Add ART module to extension SDKs

This is the only S module at the moment. Add a unit test to
derive_sdk_test to verify the multi-dessert logic works correctly.

Update the README with up-to-date instructions for adding new SDK
extensions.

Bug: 173188089
Test: atest derive_sdk_test
Change-Id: Id4fbbe13746d99d257342ff5d0dd17e6462d5336
diff --git a/README.md b/README.md
index 7f3831c..bf5191c 100644
--- a/README.md
+++ b/README.md
@@ -35,11 +35,14 @@
 ### Adding a new extension version
 For every new Android SDK level a new extension version should be defined. These
 are the steps necessary to do that:
-- Make derive_sdk correctly set the relevant system property for the new
-  extensions.
+- Add the new modules in this extension version to the SdkModule enum in
+  sdk.proto.
+- Update `derive_sdk.cpp` by:
+ * mapping the modules' package names to the new enum values
+ * creating a new set with the new enum values
+ * set a new sysprop to the value of `GetSdkLevel` with the new enum set
+ * add a unit test to `derive_sdk_test.cpp` verifying the new extensions works
 - Make the `SdkExtensions.getExtensionVersion` API support the new extensions.
 - Extend the CTS test to verify the above two behaviors.
 - Update `RollbackManagerServiceImpl#getExtensionVersions` to account for the
   new extension version.
-
-TODO(b/173188089): expand this section when derive_sdk is reimplemented
diff --git a/derive_sdk/derive_sdk.cpp b/derive_sdk/derive_sdk.cpp
index 98b84a4..d87dfee 100644
--- a/derive_sdk/derive_sdk.cpp
+++ b/derive_sdk/derive_sdk.cpp
@@ -35,6 +35,7 @@
 namespace derivesdk {
 
 static const std::unordered_map<std::string, SdkModule> kApexNameToModule = {
+    {"com.android.art", SdkModule::ART},
     {"com.android.ipsec", SdkModule::IPSEC},
     {"com.android.media", SdkModule::MEDIA},
     {"com.android.mediaprovider", SdkModule::MEDIA_PROVIDER},
@@ -51,7 +52,7 @@
     SdkModule::TETHERING,
 };
 
-static const std::unordered_set<SdkModule> kSModules = {};
+static const std::unordered_set<SdkModule> kSModules = {SdkModule::ART};
 
 bool ReadDatabase(const std::string& db_path, ExtensionDatabase& db) {
   std::string contents;
diff --git a/derive_sdk/derive_sdk_test.cpp b/derive_sdk/derive_sdk_test.cpp
index d4bae6d..8dd7265 100644
--- a/derive_sdk/derive_sdk_test.cpp
+++ b/derive_sdk/derive_sdk_test.cpp
@@ -147,6 +147,38 @@
   EXPECT_R(3);
 }
 
+TEST_F(DeriveSdkTest, TwoDesserts_ManyVersions) {
+  AddExtensionVersion(1, {
+                             {SdkModule::TETHERING, 1},
+                         });
+  AddExtensionVersion(2, {
+                             {SdkModule::ART, 2},
+                             {SdkModule::TETHERING, 1},
+                         });
+  AddExtensionVersion(3, {
+                             {SdkModule::ART, 3},
+                             {SdkModule::MEDIA, 3},
+                             {SdkModule::TETHERING, 1},
+                         });
+  EXPECT_R(0);
+  EXPECT_S(1);
+
+  SetApexVersion("com.android.tethering", 1);
+  EXPECT_R(2);
+  EXPECT_S(1);
+
+  SetApexVersion("com.android.art", 2);
+  EXPECT_R(2);
+  EXPECT_S(2);
+
+  SetApexVersion("com.android.media", 3);
+  EXPECT_R(3);
+  EXPECT_S(2);
+  SetApexVersion("com.android.art", 3);
+  EXPECT_R(3);
+  EXPECT_S(3);
+}
+
 int main(int argc, char** argv) {
   ::testing::InitGoogleTest(&argc, argv);
   return RUN_ALL_TESTS();
diff --git a/proto/sdk.proto b/proto/sdk.proto
index 7b4cae2..1e37dbc 100644
--- a/proto/sdk.proto
+++ b/proto/sdk.proto
@@ -33,6 +33,9 @@
   SDK_EXTENSIONS = 5;
   STATSD = 6;
   TETHERING = 7;
+
+  // S modules
+  ART = 8;
 }
 
 // A single extension version.