APEXes can be signed with devkeys

When PRODUCT_DEFAULT_DEV_CERTIFICATE is set to /vendor/foo/devkeys/test,
then the public/private key pairs for an apex_key is searched at
/vendor/foo/devkeys directory.

To be specific,

/system/timezone/Android.bp:
apex_key {
    name: "timezone.key",
    public_key: "com.android.tzdata.avbpubkey",
    private_key: "com.android.tzdata.pem",
}

When PRODUCT_DEFAULT_DEV_CERTIFICATE isn't set, the keys are searched at
/system/timezone, which is the path where Android.bp is located.

With PRODUCT_DEFAULT_DEV_CERTIFICATE set to /vendor/foo/devkeys/test,
the keys are searched at /vendor/foo/devkeys.

Bug: 121224311
Test: m (apex_test updated)
Test: m with crosshatch (PRODUCT_DEFAULT_DEV_CERTIFICATE is set to
/vendor/google/...)
Test: m with cheets (PRODUCT_DEFAULT_DEV_CERTIFICATE is set, but there
is no apex key there. The product is with TARGET_FLATTEN_APEX := true)

Change-Id: I213bbb96c433d851f9cc982871459fd7fb4fe47d
diff --git a/apex/apex_test.go b/apex/apex_test.go
index d4f0f7e..dbc85d9 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -124,13 +124,15 @@
 
 	ctx.MockFileSystem(map[string][]byte{
 		"Android.bp":                                []byte(bp),
-		"testkey.avbpubkey":                         nil,
-		"testkey.pem":                               nil,
 		"build/target/product/security":             nil,
 		"apex_manifest.json":                        nil,
 		"system/sepolicy/apex/myapex-file_contexts": nil,
 		"mylib.cpp":                                 nil,
 		"myprebuilt":                                nil,
+		"vendor/foo/devkeys/test.x509.pem":          nil,
+		"vendor/foo/devkeys/test.pk8":               nil,
+		"vendor/foo/devkeys/testkey.avbpubkey":      nil,
+		"vendor/foo/devkeys/testkey.pem":            nil,
 	})
 	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
 	android.FailIfErrored(t, errs)
@@ -148,6 +150,7 @@
 
 	config = android.TestArchConfig(buildDir, nil)
 	config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current")
+	config.TestProductVariables.DefaultAppCertificate = proptools.StringPtr("vendor/foo/devkeys/test")
 	return
 }
 
@@ -683,3 +686,46 @@
 	// Ensure that not_in_apex is linking with the static variant of mylib
 	ensureContains(t, ldFlags, "mylib/android_arm64_armv8-a_core_static/mylib.a")
 }
+
+func TestKeys(t *testing.T) {
+	ctx := testApex(t, `
+		apex {
+			name: "myapex",
+			key: "myapex.key",
+			native_shared_libs: ["mylib"],
+		}
+
+		cc_library {
+			name: "mylib",
+			srcs: ["mylib.cpp"],
+			system_shared_libs: [],
+			stl: "none",
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+	`)
+
+	// check the APEX keys
+	keys := ctx.ModuleForTests("myapex.key", "").Module().(*apexKey)
+
+	if keys.public_key_file.String() != "vendor/foo/devkeys/testkey.avbpubkey" {
+		t.Errorf("public key %q is not %q", keys.public_key_file.String(),
+			"vendor/foo/devkeys/testkey.avbpubkey")
+	}
+	if keys.private_key_file.String() != "vendor/foo/devkeys/testkey.pem" {
+		t.Errorf("private key %q is not %q", keys.private_key_file.String(),
+			"vendor/foo/devkeys/testkey.pem")
+	}
+
+	// check the APK certs
+	certs := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("signapk").Args["certificates"]
+	if certs != "vendor/foo/devkeys/test.x509.pem vendor/foo/devkeys/test.pk8" {
+		t.Errorf("cert and private key %q are not %q", certs,
+			"vendor/foo/devkeys/test.x509.pem vendor/foo/devkeys/test.pk8")
+	}
+}