2021-03-24 20:39:08 +01:00
|
|
|
// Copyright 2021 Google Inc. All rights reserved.
|
|
|
|
//
|
|
|
|
// 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 java
|
|
|
|
|
|
|
|
import (
|
2021-10-04 19:24:00 +02:00
|
|
|
"fmt"
|
2021-03-24 20:28:50 +01:00
|
|
|
"reflect"
|
2021-06-23 22:49:57 +02:00
|
|
|
"regexp"
|
2021-03-24 20:39:08 +01:00
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"android/soong/android"
|
2024-02-22 20:52:46 +01:00
|
|
|
|
|
|
|
"github.com/google/blueprint/proptools"
|
2021-03-24 20:39:08 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestDroidstubs(t *testing.T) {
|
|
|
|
ctx, _ := testJavaWithFS(t, `
|
|
|
|
droiddoc_exported_dir {
|
|
|
|
name: "droiddoc-templates-sdk",
|
|
|
|
path: ".",
|
|
|
|
}
|
|
|
|
|
|
|
|
droidstubs {
|
|
|
|
name: "bar-stubs",
|
|
|
|
srcs: ["bar-doc/a.java"],
|
|
|
|
api_levels_annotations_dirs: ["droiddoc-templates-sdk"],
|
|
|
|
api_levels_annotations_enabled: true,
|
|
|
|
}
|
|
|
|
|
|
|
|
droidstubs {
|
|
|
|
name: "bar-stubs-other",
|
|
|
|
srcs: ["bar-doc/a.java"],
|
|
|
|
high_mem: true,
|
|
|
|
api_levels_annotations_dirs: ["droiddoc-templates-sdk"],
|
|
|
|
api_levels_annotations_enabled: true,
|
|
|
|
api_levels_jar_filename: "android.other.jar",
|
|
|
|
}
|
2022-05-09 11:30:26 +02:00
|
|
|
|
|
|
|
droidstubs {
|
|
|
|
name: "stubs-applying-api-versions",
|
|
|
|
srcs: ["bar-doc/a.java"],
|
|
|
|
api_levels_module: "bar-stubs-other",
|
|
|
|
}
|
2021-03-24 20:39:08 +01:00
|
|
|
`,
|
|
|
|
map[string][]byte{
|
|
|
|
"bar-doc/a.java": nil,
|
|
|
|
})
|
|
|
|
testcases := []struct {
|
|
|
|
moduleName string
|
|
|
|
expectedJarFilename string
|
2022-05-09 11:30:26 +02:00
|
|
|
generate_xml bool
|
2021-03-24 20:39:08 +01:00
|
|
|
high_mem bool
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
moduleName: "bar-stubs",
|
2022-05-09 11:30:26 +02:00
|
|
|
generate_xml: true,
|
2021-03-24 20:39:08 +01:00
|
|
|
expectedJarFilename: "android.jar",
|
|
|
|
high_mem: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
moduleName: "bar-stubs-other",
|
2022-05-09 11:30:26 +02:00
|
|
|
generate_xml: true,
|
2021-03-24 20:39:08 +01:00
|
|
|
expectedJarFilename: "android.other.jar",
|
|
|
|
high_mem: true,
|
|
|
|
},
|
2022-05-09 11:30:26 +02:00
|
|
|
{
|
|
|
|
moduleName: "stubs-applying-api-versions",
|
|
|
|
generate_xml: false,
|
|
|
|
},
|
2021-03-24 20:39:08 +01:00
|
|
|
}
|
|
|
|
for _, c := range testcases {
|
|
|
|
m := ctx.ModuleForTests(c.moduleName, "android_common")
|
2021-03-31 01:40:48 +02:00
|
|
|
manifest := m.Output("metalava.sbox.textproto")
|
2023-11-03 00:56:39 +01:00
|
|
|
sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx, manifest)
|
2022-05-09 11:30:26 +02:00
|
|
|
cmdline := String(sboxProto.Commands[0].Command)
|
|
|
|
android.AssertStringContainsEquals(t, "api-versions generation flag", cmdline, "--generate-api-levels", c.generate_xml)
|
|
|
|
if c.expectedJarFilename != "" {
|
|
|
|
expected := "--android-jar-pattern ./%/public/" + c.expectedJarFilename
|
|
|
|
if !strings.Contains(cmdline, expected) {
|
|
|
|
t.Errorf("For %q, expected metalava argument %q, but was not found %q", c.moduleName, expected, cmdline)
|
|
|
|
}
|
2021-03-24 20:39:08 +01:00
|
|
|
}
|
|
|
|
|
2021-03-31 01:40:48 +02:00
|
|
|
metalava := m.Rule("metalava")
|
|
|
|
rp := metalava.RuleParams
|
2021-03-24 20:39:08 +01:00
|
|
|
if actual := rp.Pool != nil && strings.Contains(rp.Pool.String(), "highmem"); actual != c.high_mem {
|
|
|
|
t.Errorf("Expected %q high_mem to be %v, was %v", c.moduleName, c.high_mem, actual)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-04 19:24:00 +02:00
|
|
|
// runs a test for droidstubs with a customizable sdkType argument and returns
|
|
|
|
// the list of jar patterns that is passed as `--android-jar-pattern`
|
|
|
|
func getAndroidJarPatternsForDroidstubs(t *testing.T, sdkType string) []string {
|
|
|
|
ctx, _ := testJavaWithFS(t, fmt.Sprintf(`
|
2021-06-23 22:49:57 +02:00
|
|
|
droiddoc_exported_dir {
|
|
|
|
name: "some-exported-dir",
|
|
|
|
path: "somedir",
|
|
|
|
}
|
|
|
|
|
|
|
|
droiddoc_exported_dir {
|
|
|
|
name: "some-other-exported-dir",
|
|
|
|
path: "someotherdir",
|
|
|
|
}
|
|
|
|
|
|
|
|
droidstubs {
|
|
|
|
name: "foo-stubs",
|
|
|
|
srcs: ["foo-doc/a.java"],
|
|
|
|
api_levels_annotations_dirs: [
|
|
|
|
"some-exported-dir",
|
|
|
|
"some-other-exported-dir",
|
|
|
|
],
|
|
|
|
api_levels_annotations_enabled: true,
|
2022-10-05 21:45:42 +02:00
|
|
|
api_levels_sdk_type: "%s",
|
2021-06-23 22:49:57 +02:00
|
|
|
}
|
2021-10-04 19:24:00 +02:00
|
|
|
`, sdkType),
|
2021-06-23 22:49:57 +02:00
|
|
|
map[string][]byte{
|
|
|
|
"foo-doc/a.java": nil,
|
|
|
|
})
|
|
|
|
|
|
|
|
m := ctx.ModuleForTests("foo-stubs", "android_common")
|
|
|
|
manifest := m.Output("metalava.sbox.textproto")
|
2023-11-03 00:56:39 +01:00
|
|
|
cmd := String(android.RuleBuilderSboxProtoForTests(t, ctx, manifest).Commands[0].Command)
|
2021-06-23 22:49:57 +02:00
|
|
|
r := regexp.MustCompile(`--android-jar-pattern [^ ]+/android.jar`)
|
2021-10-04 19:24:00 +02:00
|
|
|
return r.FindAllString(cmd, -1)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPublicDroidstubs(t *testing.T) {
|
|
|
|
patterns := getAndroidJarPatternsForDroidstubs(t, "public")
|
|
|
|
|
|
|
|
android.AssertArrayString(t, "order of patterns", []string{
|
|
|
|
"--android-jar-pattern somedir/%/public/android.jar",
|
|
|
|
"--android-jar-pattern someotherdir/%/public/android.jar",
|
|
|
|
}, patterns)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSystemDroidstubs(t *testing.T) {
|
|
|
|
patterns := getAndroidJarPatternsForDroidstubs(t, "system")
|
|
|
|
|
|
|
|
android.AssertArrayString(t, "order of patterns", []string{
|
|
|
|
"--android-jar-pattern somedir/%/system/android.jar",
|
|
|
|
"--android-jar-pattern someotherdir/%/system/android.jar",
|
|
|
|
"--android-jar-pattern somedir/%/public/android.jar",
|
|
|
|
"--android-jar-pattern someotherdir/%/public/android.jar",
|
|
|
|
}, patterns)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestModuleLibDroidstubs(t *testing.T) {
|
|
|
|
patterns := getAndroidJarPatternsForDroidstubs(t, "module-lib")
|
|
|
|
|
2021-06-23 22:49:57 +02:00
|
|
|
android.AssertArrayString(t, "order of patterns", []string{
|
2021-10-04 19:24:00 +02:00
|
|
|
"--android-jar-pattern somedir/%/module-lib/android.jar",
|
|
|
|
"--android-jar-pattern someotherdir/%/module-lib/android.jar",
|
2021-06-23 22:49:57 +02:00
|
|
|
"--android-jar-pattern somedir/%/system/android.jar",
|
|
|
|
"--android-jar-pattern someotherdir/%/system/android.jar",
|
|
|
|
"--android-jar-pattern somedir/%/public/android.jar",
|
|
|
|
"--android-jar-pattern someotherdir/%/public/android.jar",
|
2021-10-04 19:24:00 +02:00
|
|
|
}, patterns)
|
2021-06-23 22:49:57 +02:00
|
|
|
}
|
|
|
|
|
2022-10-05 21:45:42 +02:00
|
|
|
func TestSystemServerDroidstubs(t *testing.T) {
|
|
|
|
patterns := getAndroidJarPatternsForDroidstubs(t, "system-server")
|
|
|
|
|
|
|
|
android.AssertArrayString(t, "order of patterns", []string{
|
|
|
|
"--android-jar-pattern somedir/%/system-server/android.jar",
|
|
|
|
"--android-jar-pattern someotherdir/%/system-server/android.jar",
|
|
|
|
"--android-jar-pattern somedir/%/module-lib/android.jar",
|
|
|
|
"--android-jar-pattern someotherdir/%/module-lib/android.jar",
|
|
|
|
"--android-jar-pattern somedir/%/system/android.jar",
|
|
|
|
"--android-jar-pattern someotherdir/%/system/android.jar",
|
|
|
|
"--android-jar-pattern somedir/%/public/android.jar",
|
|
|
|
"--android-jar-pattern someotherdir/%/public/android.jar",
|
|
|
|
}, patterns)
|
|
|
|
}
|
|
|
|
|
2021-03-24 20:28:50 +01:00
|
|
|
func TestDroidstubsSandbox(t *testing.T) {
|
|
|
|
ctx, _ := testJavaWithFS(t, `
|
2021-03-26 02:33:16 +01:00
|
|
|
genrule {
|
|
|
|
name: "foo",
|
|
|
|
out: ["foo.txt"],
|
|
|
|
cmd: "touch $(out)",
|
|
|
|
}
|
|
|
|
|
2021-03-24 20:28:50 +01:00
|
|
|
droidstubs {
|
|
|
|
name: "bar-stubs",
|
|
|
|
srcs: ["bar-doc/a.java"],
|
2021-03-26 02:33:16 +01:00
|
|
|
|
|
|
|
args: "--reference $(location :foo)",
|
|
|
|
arg_files: [":foo"],
|
2021-03-24 20:28:50 +01:00
|
|
|
}
|
|
|
|
`,
|
|
|
|
map[string][]byte{
|
|
|
|
"bar-doc/a.java": nil,
|
|
|
|
})
|
|
|
|
|
|
|
|
m := ctx.ModuleForTests("bar-stubs", "android_common")
|
|
|
|
metalava := m.Rule("metalava")
|
|
|
|
if g, w := metalava.Inputs.Strings(), []string{"bar-doc/a.java"}; !reflect.DeepEqual(w, g) {
|
|
|
|
t.Errorf("Expected inputs %q, got %q", w, g)
|
|
|
|
}
|
2021-03-26 02:33:16 +01:00
|
|
|
|
2023-11-03 00:56:39 +01:00
|
|
|
manifest := android.RuleBuilderSboxProtoForTests(t, ctx, m.Output("metalava.sbox.textproto"))
|
2023-12-01 02:26:37 +01:00
|
|
|
if g, w := manifest.Commands[0].GetCommand(), "reference __SBOX_SANDBOX_DIR__/out/soong/.intermediates/foo/gen/foo.txt"; !strings.Contains(g, w) {
|
2021-03-26 02:33:16 +01:00
|
|
|
t.Errorf("Expected command to contain %q, got %q", w, g)
|
|
|
|
}
|
2021-03-24 20:28:50 +01:00
|
|
|
}
|
|
|
|
|
2021-03-24 20:39:08 +01:00
|
|
|
func TestDroidstubsWithSystemModules(t *testing.T) {
|
|
|
|
ctx, _ := testJava(t, `
|
|
|
|
droidstubs {
|
|
|
|
name: "stubs-source-system-modules",
|
|
|
|
srcs: [
|
|
|
|
"bar-doc/a.java",
|
|
|
|
],
|
|
|
|
sdk_version: "none",
|
|
|
|
system_modules: "source-system-modules",
|
|
|
|
}
|
|
|
|
|
|
|
|
java_library {
|
|
|
|
name: "source-jar",
|
|
|
|
srcs: [
|
|
|
|
"a.java",
|
|
|
|
],
|
|
|
|
}
|
|
|
|
|
|
|
|
java_system_modules {
|
|
|
|
name: "source-system-modules",
|
|
|
|
libs: ["source-jar"],
|
|
|
|
}
|
|
|
|
|
|
|
|
droidstubs {
|
|
|
|
name: "stubs-prebuilt-system-modules",
|
|
|
|
srcs: [
|
|
|
|
"bar-doc/a.java",
|
|
|
|
],
|
|
|
|
sdk_version: "none",
|
|
|
|
system_modules: "prebuilt-system-modules",
|
|
|
|
}
|
|
|
|
|
|
|
|
java_import {
|
|
|
|
name: "prebuilt-jar",
|
|
|
|
jars: ["a.jar"],
|
|
|
|
}
|
|
|
|
|
|
|
|
java_system_modules_import {
|
|
|
|
name: "prebuilt-system-modules",
|
|
|
|
libs: ["prebuilt-jar"],
|
|
|
|
}
|
|
|
|
`)
|
|
|
|
|
|
|
|
checkSystemModulesUseByDroidstubs(t, ctx, "stubs-source-system-modules", "source-jar.jar")
|
|
|
|
|
|
|
|
checkSystemModulesUseByDroidstubs(t, ctx, "stubs-prebuilt-system-modules", "prebuilt-jar.jar")
|
|
|
|
}
|
|
|
|
|
|
|
|
func checkSystemModulesUseByDroidstubs(t *testing.T, ctx *android.TestContext, moduleName string, systemJar string) {
|
|
|
|
metalavaRule := ctx.ModuleForTests(moduleName, "android_common").Rule("metalava")
|
|
|
|
var systemJars []string
|
|
|
|
for _, i := range metalavaRule.Implicits {
|
|
|
|
systemJars = append(systemJars, i.Base())
|
|
|
|
}
|
|
|
|
if len(systemJars) < 1 || systemJars[0] != systemJar {
|
|
|
|
t.Errorf("inputs of %q must be []string{%q}, but was %#v.", moduleName, systemJar, systemJars)
|
|
|
|
}
|
|
|
|
}
|
2022-07-27 13:47:32 +02:00
|
|
|
|
|
|
|
func TestDroidstubsWithSdkExtensions(t *testing.T) {
|
|
|
|
ctx, _ := testJavaWithFS(t, `
|
|
|
|
droiddoc_exported_dir {
|
|
|
|
name: "sdk-dir",
|
|
|
|
path: "sdk",
|
|
|
|
}
|
|
|
|
|
|
|
|
droidstubs {
|
|
|
|
name: "baz-stubs",
|
|
|
|
api_levels_annotations_dirs: ["sdk-dir"],
|
|
|
|
api_levels_annotations_enabled: true,
|
|
|
|
extensions_info_file: ":info-file",
|
|
|
|
}
|
|
|
|
|
|
|
|
filegroup {
|
|
|
|
name: "info-file",
|
|
|
|
srcs: ["sdk/extensions/info.txt"],
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
map[string][]byte{
|
|
|
|
"sdk/extensions/1/public/some-mainline-module-stubs.jar": nil,
|
|
|
|
"sdk/extensions/info.txt": nil,
|
|
|
|
})
|
|
|
|
m := ctx.ModuleForTests("baz-stubs", "android_common")
|
|
|
|
manifest := m.Output("metalava.sbox.textproto")
|
2023-11-03 00:56:39 +01:00
|
|
|
cmdline := String(android.RuleBuilderSboxProtoForTests(t, ctx, manifest).Commands[0].Command)
|
2022-07-27 13:47:32 +02:00
|
|
|
android.AssertStringDoesContain(t, "sdk-extensions-root present", cmdline, "--sdk-extensions-root sdk/extensions")
|
|
|
|
android.AssertStringDoesContain(t, "sdk-extensions-info present", cmdline, "--sdk-extensions-info sdk/extensions/info.txt")
|
|
|
|
}
|
2022-11-28 19:48:51 +01:00
|
|
|
|
2023-01-26 09:08:52 +01:00
|
|
|
func TestDroidStubsApiContributionGeneration(t *testing.T) {
|
|
|
|
ctx, _ := testJavaWithFS(t, `
|
|
|
|
droidstubs {
|
|
|
|
name: "foo",
|
|
|
|
srcs: ["A/a.java"],
|
|
|
|
api_surface: "public",
|
|
|
|
check_api: {
|
|
|
|
current: {
|
|
|
|
api_file: "A/current.txt",
|
|
|
|
removed_api_file: "A/removed.txt",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
map[string][]byte{
|
|
|
|
"A/a.java": nil,
|
|
|
|
"A/current.txt": nil,
|
|
|
|
"A/removed.txt": nil,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
ctx.ModuleForTests("foo.api.contribution", "")
|
|
|
|
}
|
2023-02-03 23:56:13 +01:00
|
|
|
|
|
|
|
func TestGeneratedApiContributionVisibilityTest(t *testing.T) {
|
|
|
|
library_bp := `
|
|
|
|
java_api_library {
|
|
|
|
name: "bar",
|
|
|
|
api_surface: "public",
|
|
|
|
api_contributions: ["foo.api.contribution"],
|
2024-02-15 22:53:49 +01:00
|
|
|
stubs_type: "everything",
|
2023-02-03 23:56:13 +01:00
|
|
|
}
|
|
|
|
`
|
|
|
|
ctx, _ := testJavaWithFS(t, `
|
|
|
|
droidstubs {
|
|
|
|
name: "foo",
|
|
|
|
srcs: ["A/a.java"],
|
|
|
|
api_surface: "public",
|
|
|
|
check_api: {
|
|
|
|
current: {
|
|
|
|
api_file: "A/current.txt",
|
|
|
|
removed_api_file: "A/removed.txt",
|
|
|
|
}
|
|
|
|
},
|
2023-06-28 03:16:23 +02:00
|
|
|
visibility: ["//a", "//b"],
|
2023-02-03 23:56:13 +01:00
|
|
|
}
|
|
|
|
`,
|
|
|
|
map[string][]byte{
|
|
|
|
"a/a.java": nil,
|
|
|
|
"a/current.txt": nil,
|
|
|
|
"a/removed.txt": nil,
|
|
|
|
"b/Android.bp": []byte(library_bp),
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
ctx.ModuleForTests("bar", "android_common")
|
|
|
|
}
|
2023-09-20 02:54:47 +02:00
|
|
|
|
2023-12-19 02:13:16 +01:00
|
|
|
func TestAconfigDeclarations(t *testing.T) {
|
|
|
|
result := android.GroupFixturePreparers(
|
|
|
|
prepareForJavaTest,
|
|
|
|
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
|
|
|
|
}),
|
|
|
|
android.FixtureMergeMockFs(map[string][]byte{
|
|
|
|
"a/A.java": nil,
|
|
|
|
"a/current.txt": nil,
|
|
|
|
"a/removed.txt": nil,
|
|
|
|
}),
|
|
|
|
).RunTestWithBp(t, `
|
|
|
|
aconfig_declarations {
|
|
|
|
name: "bar",
|
|
|
|
package: "com.example.package",
|
|
|
|
srcs: [
|
|
|
|
"bar.aconfig",
|
|
|
|
],
|
|
|
|
}
|
|
|
|
droidstubs {
|
|
|
|
name: "foo",
|
|
|
|
srcs: ["a/A.java"],
|
|
|
|
api_surface: "public",
|
|
|
|
check_api: {
|
|
|
|
current: {
|
|
|
|
api_file: "a/current.txt",
|
|
|
|
removed_api_file: "a/removed.txt",
|
|
|
|
}
|
|
|
|
},
|
|
|
|
aconfig_declarations: [
|
|
|
|
"bar",
|
|
|
|
],
|
|
|
|
}
|
|
|
|
`)
|
|
|
|
|
|
|
|
// Check that droidstubs depend on aconfig_declarations
|
|
|
|
android.AssertBoolEquals(t, "foo expected to depend on bar",
|
|
|
|
CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "bar"), true)
|
|
|
|
|
2024-03-05 17:12:20 +01:00
|
|
|
m := result.ModuleForTests("foo", "android_common")
|
2023-12-19 02:13:16 +01:00
|
|
|
android.AssertStringDoesContain(t, "foo generates revert annotations file",
|
2024-03-05 17:12:20 +01:00
|
|
|
strings.Join(m.AllOutputs(), ""), "revert-annotations-exportable.txt")
|
Generate "exportable" stubs in droidstubs
This change generates rules for "exportable" stubs in the droidstubs
module.
Given that there are a lot of overlap between the currently existing
"everything" stubs rule and the newly introducing "exportable" stubs
rule, the currently existing metalava rule commands are modularized to
be utilized in the "exportable" stubs rule commands.
The currently existing build actions are modularized in the followings:
- commonMetalavaStubCmd(...): metalava commands that are required for
generation of both "everything", "exportable", and potentially
"runtime" stubs
- everythingOptionalCmd(...): metalava commands that are dependent on
"everything" stubs and not dependent on flagged apis annotations, such
as api lint, released api check
Based on this modularization, the "everything" stubs are now generated
in everythingStubCmd(...), which calls commonMetalavaStubCmd(...) and
everythingOptionalCmd(...).
Similarly, the "exportable" stubs are generated in
optionalStubCmd(stubsType=Exportable, ...), which calls
commonMetalavaStubCmd(...) and appends additional flags. Runtime stubs
can be generated similarly in the future with
optionalStubCmd(stubsType=Runtime, ...).
"everything"-related artifacts will now be created in
`everything/` subdirectory, and "exportable"-related artifacts will be
created in `exportable/` subdirectory. For example, the outdir of a
droidstubs module "foo" would look like below:
```
foo
|-- everything
| |-- foo_api.txt
| |-- foo-stubs.srcjar
|
|-- exportable
|-- foo_api.txt
|-- foo-stubs.srcjar
```
The module generates the build rules for the "exportable" stubs
regardless of whether the module defines the `aconfig_declarations`
property or not. All APIs marked with `@FlaggedApis` annotations are
stripped out for the "exportable" stubs when the `aconfig_declarations`
property is not defined. On the other hand, only the `@FlaggedApis` that
are specified in the aconfig_declarations module and are enabled will be
included (and all others are stripped) when the `aconfig_declarations`
propety is defined.
Test: go test ./java && BUILD_FROM_SOURCE_STUBS=true m
Bug: 315490657
Change-Id: I300273cd2a62fa978b046c0268e3a67c35e22b08
2023-12-19 03:40:22 +01:00
|
|
|
|
|
|
|
// revert-annotations.txt passed to exportable stubs generation metalava command
|
2024-03-05 17:12:20 +01:00
|
|
|
manifest := m.Output("metalava_exportable.sbox.textproto")
|
|
|
|
cmdline := String(android.RuleBuilderSboxProtoForTests(t, result.TestContext, manifest).Commands[0].Command)
|
|
|
|
android.AssertStringDoesContain(t, "flagged api hide command not included", cmdline, "revert-annotations-exportable.txt")
|
Generate "exportable" stubs in droidstubs
This change generates rules for "exportable" stubs in the droidstubs
module.
Given that there are a lot of overlap between the currently existing
"everything" stubs rule and the newly introducing "exportable" stubs
rule, the currently existing metalava rule commands are modularized to
be utilized in the "exportable" stubs rule commands.
The currently existing build actions are modularized in the followings:
- commonMetalavaStubCmd(...): metalava commands that are required for
generation of both "everything", "exportable", and potentially
"runtime" stubs
- everythingOptionalCmd(...): metalava commands that are dependent on
"everything" stubs and not dependent on flagged apis annotations, such
as api lint, released api check
Based on this modularization, the "everything" stubs are now generated
in everythingStubCmd(...), which calls commonMetalavaStubCmd(...) and
everythingOptionalCmd(...).
Similarly, the "exportable" stubs are generated in
optionalStubCmd(stubsType=Exportable, ...), which calls
commonMetalavaStubCmd(...) and appends additional flags. Runtime stubs
can be generated similarly in the future with
optionalStubCmd(stubsType=Runtime, ...).
"everything"-related artifacts will now be created in
`everything/` subdirectory, and "exportable"-related artifacts will be
created in `exportable/` subdirectory. For example, the outdir of a
droidstubs module "foo" would look like below:
```
foo
|-- everything
| |-- foo_api.txt
| |-- foo-stubs.srcjar
|
|-- exportable
|-- foo_api.txt
|-- foo-stubs.srcjar
```
The module generates the build rules for the "exportable" stubs
regardless of whether the module defines the `aconfig_declarations`
property or not. All APIs marked with `@FlaggedApis` annotations are
stripped out for the "exportable" stubs when the `aconfig_declarations`
property is not defined. On the other hand, only the `@FlaggedApis` that
are specified in the aconfig_declarations module and are enabled will be
included (and all others are stripped) when the `aconfig_declarations`
propety is defined.
Test: go test ./java && BUILD_FROM_SOURCE_STUBS=true m
Bug: 315490657
Change-Id: I300273cd2a62fa978b046c0268e3a67c35e22b08
2023-12-19 03:40:22 +01:00
|
|
|
|
|
|
|
android.AssertStringDoesContain(t, "foo generates exportable stubs jar",
|
2024-03-05 17:12:20 +01:00
|
|
|
strings.Join(m.AllOutputs(), ""), "exportable/foo-stubs.srcjar")
|
2023-12-19 02:13:16 +01:00
|
|
|
}
|
Enable exportable stubs to include READ_WRITE aconfig flagged apis
Currently in SDK build, "exportable" stubs are used to generate the
android.jar and the corresponding build artifacts, as well as the
hiddenapi flags. "exportable" stubs only include the flagged apis that
are "enabled" and "read only", and exclude all other flagged apis. This
will be replaced with "runtime" stubs in the long run, which include
"read_write" flagged apis on top of the "enabled" and "read only" flags.
Prior to Trunk Stable, the SDK build did not distinguish the target
audience of the SDK. That is, the identical build target was used to
generate the SDK targeted toward the Google3 developers (i.e. Google3
SDK drop) and the SDK targeted toward the public (i.e. Developer
Preview). However, given that we now have "experimental" apis with Trunk
Stable, there are demands to differentiate the SDK based on the target
audience, so that the "experimental" APIs are included in the SDK
targeted toward Google3 while they are excluded in the public facing
SDK.
The long term solution to achieve this is to generate the hiddenapi
flags and (conditionally) the SDKs using the runtime stubs. However, as
this is high priority, this change resolves the problem by modifying the
filter condition of the "exportable" stubs to include the "read_write"
flagged apis on top of the "enabled" and "read only" flagged apis when
the value of the default-false build flag "RELEASE_EXPORT_RUNTIME_APIS"
is set to true.
Note that this is a temporary solution; However, we might need to keep
the "RELEASE_EXPORT_RUNTIME_APIS" build flag even in the long run to
determine what set of apis are included in the generated SDK, based on
the target audience of the SDK.
Test: m nothing --no-skip-soong-tests
Bug: 323188988
Change-Id: If0d5fa74b3ba6f4a57c86aade8d340f149a657a2
2024-02-06 23:43:18 +01:00
|
|
|
|
|
|
|
func TestReleaseExportRuntimeApis(t *testing.T) {
|
|
|
|
result := android.GroupFixturePreparers(
|
|
|
|
prepareForJavaTest,
|
|
|
|
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
|
|
|
|
variables.BuildFlags = map[string]string{
|
|
|
|
"RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true",
|
|
|
|
}
|
2024-02-22 20:52:46 +01:00
|
|
|
variables.ExportRuntimeApis = proptools.BoolPtr(true)
|
Enable exportable stubs to include READ_WRITE aconfig flagged apis
Currently in SDK build, "exportable" stubs are used to generate the
android.jar and the corresponding build artifacts, as well as the
hiddenapi flags. "exportable" stubs only include the flagged apis that
are "enabled" and "read only", and exclude all other flagged apis. This
will be replaced with "runtime" stubs in the long run, which include
"read_write" flagged apis on top of the "enabled" and "read only" flags.
Prior to Trunk Stable, the SDK build did not distinguish the target
audience of the SDK. That is, the identical build target was used to
generate the SDK targeted toward the Google3 developers (i.e. Google3
SDK drop) and the SDK targeted toward the public (i.e. Developer
Preview). However, given that we now have "experimental" apis with Trunk
Stable, there are demands to differentiate the SDK based on the target
audience, so that the "experimental" APIs are included in the SDK
targeted toward Google3 while they are excluded in the public facing
SDK.
The long term solution to achieve this is to generate the hiddenapi
flags and (conditionally) the SDKs using the runtime stubs. However, as
this is high priority, this change resolves the problem by modifying the
filter condition of the "exportable" stubs to include the "read_write"
flagged apis on top of the "enabled" and "read only" flagged apis when
the value of the default-false build flag "RELEASE_EXPORT_RUNTIME_APIS"
is set to true.
Note that this is a temporary solution; However, we might need to keep
the "RELEASE_EXPORT_RUNTIME_APIS" build flag even in the long run to
determine what set of apis are included in the generated SDK, based on
the target audience of the SDK.
Test: m nothing --no-skip-soong-tests
Bug: 323188988
Change-Id: If0d5fa74b3ba6f4a57c86aade8d340f149a657a2
2024-02-06 23:43:18 +01:00
|
|
|
}),
|
|
|
|
android.FixtureMergeMockFs(map[string][]byte{
|
|
|
|
"a/A.java": nil,
|
|
|
|
"a/current.txt": nil,
|
|
|
|
"a/removed.txt": nil,
|
|
|
|
}),
|
|
|
|
).RunTestWithBp(t, `
|
|
|
|
aconfig_declarations {
|
|
|
|
name: "bar",
|
|
|
|
package: "com.example.package",
|
|
|
|
srcs: [
|
|
|
|
"bar.aconfig",
|
|
|
|
],
|
|
|
|
}
|
|
|
|
droidstubs {
|
|
|
|
name: "foo",
|
|
|
|
srcs: ["a/A.java"],
|
|
|
|
api_surface: "public",
|
|
|
|
check_api: {
|
|
|
|
current: {
|
|
|
|
api_file: "a/current.txt",
|
|
|
|
removed_api_file: "a/removed.txt",
|
|
|
|
}
|
|
|
|
},
|
|
|
|
aconfig_declarations: [
|
|
|
|
"bar",
|
|
|
|
],
|
|
|
|
}
|
|
|
|
`)
|
|
|
|
|
|
|
|
m := result.ModuleForTests("foo", "android_common")
|
|
|
|
|
|
|
|
rule := m.Output("released-flagged-apis-exportable.txt")
|
|
|
|
exposeWritableApisFilter := "--filter='state:ENABLED+permission:READ_ONLY' --filter='permission:READ_WRITE'"
|
|
|
|
android.AssertStringEquals(t, "Filter argument expected to contain READ_WRITE permissions", exposeWritableApisFilter, rule.Args["filter_args"])
|
|
|
|
}
|