Skip to content

Commit

Permalink
Add command to generate sources for sandboxed SDK consumers.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 564394486
Change-Id: I3210682b6bf1d76fef741ed41ef299d37a902981
  • Loading branch information
lucasvtenorio authored and Copybara-Service committed Sep 11, 2023
1 parent 788a8ab commit 7155b29
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 0 deletions.
1 change: 1 addition & 0 deletions defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def rules_android_workspace():
name = "rules_android_maven",
artifacts = [
"androidx.privacysandbox.tools:tools:1.0.0-alpha06",
"androidx.privacysandbox.tools:tools-apigenerator:1.0.0-alpha06",
"androidx.privacysandbox.tools:tools-apipackager:1.0.0-alpha06",
"androidx.test:core:1.6.0-alpha01",
"androidx.test.ext:junit:1.2.0-alpha01",
Expand Down
44 changes: 44 additions & 0 deletions rules/sandboxed_sdk_toolbox.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,51 @@ def _extract_api_descriptors(
progress_message = "Extract SDK API descriptors %s" % output.short_path,
)

def _generate_client_sources(
ctx,
output_kotlin_dir = None,
output_java_dir = None,
sdk_api_descriptors = None,
aidl_compiler = None,
framework_aidl = None,
sandboxed_sdk_toolbox = None,
host_javabase = None):
"""Generate Kotlin and Java sources for SDK communication.
Args:
ctx: The context.
output_kotlin_dir: Directory for Kotlin source tree. It depends on the Java sources.
output_java_dir: Directory for Java source tree. Doesn't depend on Kotlin sources.
sdk_api_descriptors: SDK API descriptor jar.
aidl_compiler: Executable files for the AOSP AIDL compiler.
framework_aidl: Framework.aidl file used to compile AIDL sources.
sandboxed_sdk_toolbox: Toolbox executable files.
host_javabase: Javabase used to run the toolbox.
"""
args = ctx.actions.args()
args.add("generate-client-sources")
args.add("--sdk-api-descriptors", sdk_api_descriptors)
args.add("--aidl-compiler", aidl_compiler)
args.add("--framework-aidl", framework_aidl)
args.add("--output-kotlin-dir", output_kotlin_dir.path)
args.add("--output-java-dir", output_java_dir.path)
_java.run(
ctx = ctx,
host_javabase = host_javabase,
executable = sandboxed_sdk_toolbox,
arguments = [args],
inputs = [
sdk_api_descriptors,
aidl_compiler,
framework_aidl,
],
outputs = [output_kotlin_dir, output_java_dir],
mnemonic = "GenClientSources",
progress_message = "Generate client sources for %s" % output_kotlin_dir.short_path,
)

sandboxed_sdk_toolbox = struct(
extract_api_descriptors = _extract_api_descriptors,
generate_sdk_dependencies_manifest = _generate_sdk_dependencies_manifest,
generate_client_sources = _generate_client_sources,
)
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ java_library(
srcs = glob(["*.java"]),
deps = [
"//src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/apidescriptors",
"//src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/clientsources",
"//src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest",
"@rules_android_maven//:info_picocli_picocli",
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package com.google.devtools.build.android.sandboxedsdktoolbox;

import com.google.devtools.build.android.sandboxedsdktoolbox.apidescriptors.ExtractApiDescriptorsCommand;
import com.google.devtools.build.android.sandboxedsdktoolbox.clientsources.GenerateClientSourcesCommand;
import com.google.devtools.build.android.sandboxedsdktoolbox.sdkdependenciesmanifest.GenerateSdkDependenciesManifestCommand;
import picocli.CommandLine;
import picocli.CommandLine.Command;
Expand All @@ -26,6 +27,7 @@
subcommands = {
ExtractApiDescriptorsCommand.class,
GenerateSdkDependenciesManifestCommand.class,
GenerateClientSourcesCommand.class,
})
public final class SandboxedSdkToolbox {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Command to generate sources for communicating with a sandboxed SDK.

package(
default_applicable_licenses = ["//:license"],
default_visibility = ["//:__subpackages__"],
)

licenses(["notice"])

java_library(
name = "clientsources",
srcs = glob(["*.java"]),
deps = [
"@rules_android_maven//:androidx_privacysandbox_tools_tools_apigenerator",
"@rules_android_maven//:info_picocli_picocli",
],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Copyright 2023 The Bazel Authors. 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 com.google.devtools.build.android.sandboxedsdktoolbox.clientsources;

import static java.nio.file.Files.createTempDirectory;
import static java.util.stream.Collectors.toCollection;

import androidx.privacysandbox.tools.apigenerator.PrivacySandboxApiGenerator;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;

/**
* Command for generating Kotlin and Java sources for communicating with a sandboxed SDK over IPC.
*/
@Command(
name = "generate-client-sources",
description =
"Generate Kotlin and Java sources for communicating with a sandboxed SDK over IPC.")
public final class GenerateClientSourcesCommand implements Runnable {

private final PrivacySandboxApiGenerator generator = new PrivacySandboxApiGenerator();

@Option(names = "--aidl-compiler", required = true)
Path aidlCompilerPath;

@Option(names = "--framework-aidl", required = true)
Path frameworkAidlPath;

@Option(names = "--sdk-api-descriptors", required = true)
Path sdkApiDescriptorsPath;

@Option(
names = "--output-kotlin-dir",
description = "Directory where Kotlin sources will be written.",
required = true)
Path outputKotlinDirPath;

@Option(
names = "--output-java-dir",
description = "Directory where Java sources will be written.",
required = true)
Path outputJavaDirPath;

@Override
public void run() {
try {
Path apiGeneratorOutputDir = createTempDirectory("apigenerator-raw-output");
generator.generate(
sdkApiDescriptorsPath, aidlCompilerPath, frameworkAidlPath, apiGeneratorOutputDir);
splitSources(apiGeneratorOutputDir, outputKotlinDirPath, outputJavaDirPath);
} catch (IOException e) {
throw new UncheckedIOException("Failed to generate sources.", e);
}
}

/** Split Java and Kotlin sources into different root directories. */
private static void splitSources(
Path sourcesDirectory, Path kotlinSourcesDirectory, Path javaSourcesDirectory)
throws IOException {
for (Path path : allFiles(sourcesDirectory)) {
Path targetDir = javaSourcesDirectory;
if (path.toString().endsWith(".kt")) {
targetDir = kotlinSourcesDirectory;
}
Path targetPath = targetDir.resolve(sourcesDirectory.relativize(path));

Files.createDirectories(targetPath.getParent());
Files.move(path, targetPath);
}
}

private static List<Path> allFiles(Path rootDirectory) throws IOException {
try (Stream<Path> pathStream = Files.walk(rootDirectory)) {
return pathStream.filter(Files::isRegularFile).collect(toCollection(ArrayList::new));
}
}

private GenerateClientSourcesCommand() {}
}

0 comments on commit 7155b29

Please sign in to comment.