Merge "Revert "Enable dex container (DEX v41) for the whole system"" into main
diff --git a/android/androidmk.go b/android/androidmk.go
index 62f82f2..f6e8799 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -486,17 +486,6 @@
return generateDistContributionsForMake(distContributions)
}
-// Write the license variables to Make for AndroidMkData.Custom(..) methods that do not call WriteAndroidMkData(..)
-// It's required to propagate the license metadata even for module types that have non-standard interfaces to Make.
-func (a *AndroidMkEntries) WriteLicenseVariables(w io.Writer) {
- AndroidMkEmitAssignList(w, "LOCAL_LICENSE_KINDS", a.EntryMap["LOCAL_LICENSE_KINDS"])
- AndroidMkEmitAssignList(w, "LOCAL_LICENSE_CONDITIONS", a.EntryMap["LOCAL_LICENSE_CONDITIONS"])
- AndroidMkEmitAssignList(w, "LOCAL_NOTICE_FILE", a.EntryMap["LOCAL_NOTICE_FILE"])
- if pn, ok := a.EntryMap["LOCAL_LICENSE_PACKAGE_NAME"]; ok {
- AndroidMkEmitAssignList(w, "LOCAL_LICENSE_PACKAGE_NAME", pn)
- }
-}
-
// fillInEntries goes through the common variable processing and calls the extra data funcs to
// generate and fill in AndroidMkEntries's in-struct data, ready to be flushed to a file.
type fillInEntriesContext interface {
@@ -534,15 +523,6 @@
// Collect make variable assignment entries.
a.SetString("LOCAL_PATH", ctx.ModuleDir(mod))
a.SetString("LOCAL_MODULE", name+a.SubName)
- a.AddStrings("LOCAL_LICENSE_KINDS", base.commonProperties.Effective_license_kinds...)
- a.AddStrings("LOCAL_LICENSE_CONDITIONS", base.commonProperties.Effective_license_conditions...)
- a.AddStrings("LOCAL_NOTICE_FILE", base.commonProperties.Effective_license_text.Strings()...)
- // TODO(b/151177513): Does this code need to set LOCAL_MODULE_IS_CONTAINER ?
- if base.commonProperties.Effective_package_name != nil {
- a.SetString("LOCAL_LICENSE_PACKAGE_NAME", *base.commonProperties.Effective_package_name)
- } else if len(base.commonProperties.Effective_licenses) > 0 {
- a.SetString("LOCAL_LICENSE_PACKAGE_NAME", strings.Join(base.commonProperties.Effective_licenses, " "))
- }
a.SetString("LOCAL_MODULE_CLASS", a.Class)
a.SetString("LOCAL_PREBUILT_MODULE_FILE", a.OutputFile.String())
a.AddStrings("LOCAL_REQUIRED_MODULES", a.Required...)
diff --git a/apex/androidmk.go b/apex/androidmk.go
index 6136cbd..4e968ea 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -245,7 +245,6 @@
fmt.Fprintln(w, "\ninclude $(CLEAR_VARS) # apex.apexBundle")
fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
fmt.Fprintln(w, "LOCAL_MODULE :=", name)
- data.Entries.WriteLicenseVariables(w)
fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC") // do we need a new class?
fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", a.outputFile.String())
fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", a.installDir.String())
diff --git a/bpf/bpf.go b/bpf/bpf.go
index ba825cf..58213aa 100644
--- a/bpf/bpf.go
+++ b/bpf/bpf.go
@@ -229,7 +229,6 @@
names = append(names, objName)
fmt.Fprintln(w, "include $(CLEAR_VARS)", " # bpf.bpf.obj")
fmt.Fprintln(w, "LOCAL_MODULE := ", objName)
- data.Entries.WriteLicenseVariables(w)
fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", obj.String())
fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", obj.Base())
fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC")
@@ -239,7 +238,6 @@
}
fmt.Fprintln(w, "include $(CLEAR_VARS)", " # bpf.bpf")
fmt.Fprintln(w, "LOCAL_MODULE := ", name)
- data.Entries.WriteLicenseVariables(w)
android.AndroidMkEmitAssignList(w, "LOCAL_REQUIRED_MODULES", names)
fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
},
diff --git a/cc/Android.bp b/cc/Android.bp
index 77e96db..9496bac 100644
--- a/cc/Android.bp
+++ b/cc/Android.bp
@@ -40,7 +40,6 @@
"lto.go",
"makevars.go",
"orderfile.go",
- "pgo.go",
"prebuilt.go",
"proto.go",
"rs.go",
diff --git a/cc/cc.go b/cc/cc.go
index e215438..74a8d35 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -141,6 +141,8 @@
// List of libs that need to be excluded for APEX variant
ExcludeLibsForApex []string
+ // List of libs that need to be excluded for non-APEX variant
+ ExcludeLibsForNonApex []string
}
// PathDeps is a struct containing file paths to dependencies of a module.
@@ -529,7 +531,6 @@
baseModuleName() string
getVndkExtendsModuleName() string
isAfdoCompile() bool
- isPgoCompile() bool
isOrderfileCompile() bool
isCfi() bool
isFuzzer() bool
@@ -728,6 +729,8 @@
// Whether or not this dependency has to be followed for the apex variants
excludeInApex bool
+ // Whether or not this dependency has to be followed for the non-apex variants
+ excludeInNonApex bool
// If true, don't automatically export symbols from the static library into a shared library.
unexportedSymbols bool
@@ -891,7 +894,6 @@
vndkdep *vndkdep
lto *lto
afdo *afdo
- pgo *pgo
orderfile *orderfile
library libraryInterface
@@ -1274,9 +1276,6 @@
if c.afdo != nil {
c.AddProperties(c.afdo.props()...)
}
- if c.pgo != nil {
- c.AddProperties(c.pgo.props()...)
- }
if c.orderfile != nil {
c.AddProperties(c.orderfile.props()...)
}
@@ -1406,13 +1405,6 @@
return false
}
-func (c *Module) isPgoCompile() bool {
- if pgo := c.pgo; pgo != nil {
- return pgo.Properties.PgoCompile
- }
- return false
-}
-
func (c *Module) isOrderfileCompile() bool {
if orderfile := c.orderfile; orderfile != nil {
return orderfile.Properties.OrderfileLoad
@@ -1721,10 +1713,6 @@
return ctx.mod.isAfdoCompile()
}
-func (ctx *moduleContextImpl) isPgoCompile() bool {
- return ctx.mod.isPgoCompile()
-}
-
func (ctx *moduleContextImpl) isOrderfileCompile() bool {
return ctx.mod.isOrderfileCompile()
}
@@ -1837,7 +1825,6 @@
module.vndkdep = &vndkdep{}
module.lto = <o{}
module.afdo = &afdo{}
- module.pgo = &pgo{}
module.orderfile = &orderfile{}
return module
}
@@ -2263,9 +2250,6 @@
if c.afdo != nil {
flags = c.afdo.flags(ctx, flags)
}
- if c.pgo != nil {
- flags = c.pgo.flags(ctx, flags)
- }
if c.orderfile != nil {
flags = c.orderfile.flags(ctx, flags)
}
@@ -2417,9 +2401,6 @@
if c.orderfile != nil {
c.orderfile.begin(ctx)
}
- if c.pgo != nil {
- c.pgo.begin(ctx)
- }
if ctx.useSdk() && c.IsSdkVariant() {
version, err := nativeApiLevelFromUser(ctx, ctx.sdkVersion())
if err != nil {
@@ -2819,6 +2800,9 @@
if inList(lib, deps.ExcludeLibsForApex) {
depTag.excludeInApex = true
}
+ if inList(lib, deps.ExcludeLibsForNonApex) {
+ depTag.excludeInNonApex = true
+ }
name, version := StubsLibNameAndVersion(lib)
if apiLibraryName, ok := apiImportInfo.SharedLibs[name]; ok && !ctx.OtherModuleExists(name) {
@@ -3335,6 +3319,9 @@
if !apexInfo.IsForPlatform() && libDepTag.excludeInApex {
return
}
+ if apexInfo.IsForPlatform() && libDepTag.excludeInNonApex {
+ return
+ }
depExporterInfo := ctx.OtherModuleProvider(dep, FlagExporterInfoProvider).(FlagExporterInfo)
@@ -4323,7 +4310,6 @@
&VndkProperties{},
<OProperties{},
&AfdoProperties{},
- &PgoProperties{},
&OrderfileProperties{},
&android.ProtoProperties{},
// RustBindgenProperties is included here so that cc_defaults can be used for rust_bindgen modules.
diff --git a/cc/linker.go b/cc/linker.go
index 257fe86..357d1ce 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -214,6 +214,11 @@
// variant of the C/C++ module.
Exclude_static_libs []string
}
+ Non_apex struct {
+ // list of shared libs that should not be used to build the non-apex
+ // variant of the C/C++ module.
+ Exclude_shared_libs []string
+ }
} `android:"arch_variant"`
// make android::build:GetBuildNumber() available containing the build ID.
@@ -300,6 +305,10 @@
// variants.
deps.ExcludeLibsForApex = append(deps.ExcludeLibsForApex, linker.Properties.Target.Apex.Exclude_shared_libs...)
deps.ExcludeLibsForApex = append(deps.ExcludeLibsForApex, linker.Properties.Target.Apex.Exclude_static_libs...)
+ // Record the libraries that need to be excluded when building for non-APEX variants
+ // for the same reason above. This is used for marking deps and marked deps are
+ // ignored for non-apex variants.
+ deps.ExcludeLibsForNonApex = append(deps.ExcludeLibsForNonApex, linker.Properties.Target.Non_apex.Exclude_shared_libs...)
if Bool(linker.Properties.Use_version_lib) {
deps.WholeStaticLibs = append(deps.WholeStaticLibs, "libbuildversion")
diff --git a/cc/lto.go b/cc/lto.go
index 30d7b757..d2a43d2 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -140,7 +140,7 @@
// Reduce the inlining threshold for a better balance of binary size and
// performance.
if !ctx.Darwin() {
- if ctx.isPgoCompile() || ctx.isAfdoCompile() {
+ if ctx.isAfdoCompile() {
ltoLdFlags = append(ltoLdFlags, "-Wl,-plugin-opt,-import-instr-limit=40")
} else {
ltoLdFlags = append(ltoLdFlags, "-Wl,-plugin-opt,-import-instr-limit=5")
diff --git a/cc/pgo.go b/cc/pgo.go
deleted file mode 100644
index 463e2e6..0000000
--- a/cc/pgo.go
+++ /dev/null
@@ -1,294 +0,0 @@
-// Copyright 2017 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 cc
-
-import (
- "fmt"
- "path/filepath"
- "strings"
-
- "github.com/google/blueprint/proptools"
-
- "android/soong/android"
-)
-
-var (
- // Add flags to ignore warnings that profiles are old or missing for
- // some functions.
- profileUseOtherFlags = []string{
- "-Wno-backend-plugin",
- }
-
- globalPgoProfileProjects = []string{
- "toolchain/pgo-profiles/pgo",
- "vendor/google_data/pgo_profile/pgo",
- }
-)
-
-var pgoProfileProjectsConfigKey = android.NewOnceKey("PgoProfileProjects")
-
-const profileInstrumentFlag = "-fprofile-generate=/data/local/tmp"
-const profileUseInstrumentFormat = "-fprofile-use=%s"
-
-func getPgoProfileProjects(config android.DeviceConfig) []string {
- return config.OnceStringSlice(pgoProfileProjectsConfigKey, func() []string {
- return append(globalPgoProfileProjects, config.PgoAdditionalProfileDirs()...)
- })
-}
-
-func recordMissingProfileFile(ctx BaseModuleContext, missing string) {
- getNamedMapForConfig(ctx.Config(), modulesMissingProfileFileKey).Store(missing, true)
-}
-
-type PgoProperties struct {
- Pgo struct {
- Instrumentation *bool
- Profile_file *string `android:"arch_variant"`
- Benchmarks []string
- Enable_profile_use *bool `android:"arch_variant"`
- // Additional compiler flags to use when building this module
- // for profiling.
- Cflags []string `android:"arch_variant"`
- } `android:"arch_variant"`
-
- PgoPresent bool `blueprint:"mutated"`
- ShouldProfileModule bool `blueprint:"mutated"`
- PgoCompile bool `blueprint:"mutated"`
- PgoInstrLink bool `blueprint:"mutated"`
-}
-
-type pgo struct {
- Properties PgoProperties
-}
-
-func (props *PgoProperties) isInstrumentation() bool {
- return props.Pgo.Instrumentation != nil && *props.Pgo.Instrumentation == true
-}
-
-func (pgo *pgo) props() []interface{} {
- return []interface{}{&pgo.Properties}
-}
-
-func (props *PgoProperties) addInstrumentationProfileGatherFlags(ctx ModuleContext, flags Flags) Flags {
- // Add to C flags iff PGO is explicitly enabled for this module.
- if props.ShouldProfileModule {
- flags.Local.CFlags = append(flags.Local.CFlags, props.Pgo.Cflags...)
- flags.Local.CFlags = append(flags.Local.CFlags, profileInstrumentFlag)
- }
- flags.Local.LdFlags = append(flags.Local.LdFlags, profileInstrumentFlag)
- return flags
-}
-
-func (props *PgoProperties) getPgoProfileFile(ctx BaseModuleContext) android.OptionalPath {
- profileFile := *props.Pgo.Profile_file
-
- // Test if the profile_file is present in any of the PGO profile projects
- for _, profileProject := range getPgoProfileProjects(ctx.DeviceConfig()) {
- // Bug: http://b/74395273 If the profile_file is unavailable,
- // use a versioned file named
- // <profile_file>.<arbitrary-version> when available. This
- // works around an issue where ccache serves stale cache
- // entries when the profile file has changed.
- globPattern := filepath.Join(profileProject, profileFile+".*")
- versionedProfiles, err := ctx.GlobWithDeps(globPattern, nil)
- if err != nil {
- ctx.ModuleErrorf("glob: %s", err.Error())
- }
-
- path := android.ExistentPathForSource(ctx, profileProject, profileFile)
- if path.Valid() {
- if len(versionedProfiles) != 0 {
- ctx.PropertyErrorf("pgo.profile_file", "Profile_file has multiple versions: "+filepath.Join(profileProject, profileFile)+", "+strings.Join(versionedProfiles, ", "))
- }
- return path
- }
-
- if len(versionedProfiles) > 1 {
- ctx.PropertyErrorf("pgo.profile_file", "Profile_file has multiple versions: "+strings.Join(versionedProfiles, ", "))
- } else if len(versionedProfiles) == 1 {
- return android.OptionalPathForPath(android.PathForSource(ctx, versionedProfiles[0]))
- }
- }
-
- // Record that this module's profile file is absent
- missing := *props.Pgo.Profile_file + ":" + ctx.ModuleDir() + "/Android.bp:" + ctx.ModuleName()
- recordMissingProfileFile(ctx, missing)
-
- return android.OptionalPathForPath(nil)
-}
-
-func (props *PgoProperties) profileUseFlags(ctx ModuleContext, file string) []string {
- flags := []string{fmt.Sprintf(profileUseInstrumentFormat, file)}
- flags = append(flags, profileUseOtherFlags...)
- return flags
-}
-
-func (props *PgoProperties) addProfileUseFlags(ctx ModuleContext, flags Flags) Flags {
- // Return if 'pgo' property is not present in this module.
- if !props.PgoPresent {
- return flags
- }
-
- if props.PgoCompile {
- profileFile := props.getPgoProfileFile(ctx)
- profileFilePath := profileFile.Path()
- profileUseFlags := props.profileUseFlags(ctx, profileFilePath.String())
-
- flags.Local.CFlags = append(flags.Local.CFlags, profileUseFlags...)
- flags.Local.LdFlags = append(flags.Local.LdFlags, profileUseFlags...)
-
- // Update CFlagsDeps and LdFlagsDeps so the module is rebuilt
- // if profileFile gets updated
- flags.CFlagsDeps = append(flags.CFlagsDeps, profileFilePath)
- flags.LdFlagsDeps = append(flags.LdFlagsDeps, profileFilePath)
- }
- return flags
-}
-
-func (props *PgoProperties) isPGO(ctx BaseModuleContext) bool {
- isInstrumentation := props.isInstrumentation()
-
- profileKindPresent := isInstrumentation
- filePresent := props.Pgo.Profile_file != nil
- benchmarksPresent := len(props.Pgo.Benchmarks) > 0
-
- // If all three properties are absent, PGO is OFF for this module
- if !profileKindPresent && !filePresent && !benchmarksPresent {
- return false
- }
-
- // profileKindPresent and filePresent are mandatory properties.
- if !profileKindPresent || !filePresent {
- var missing []string
- if !profileKindPresent {
- missing = append(missing, "profile kind")
- }
- if !filePresent {
- missing = append(missing, "profile_file property")
- }
- missingProps := strings.Join(missing, ", ")
- ctx.ModuleErrorf("PGO specification is missing properties: " + missingProps)
- }
-
- // Benchmark property is mandatory for instrumentation PGO.
- if isInstrumentation && !benchmarksPresent {
- ctx.ModuleErrorf("Instrumentation PGO specification is missing benchmark property")
- }
-
- return true
-}
-
-func (pgo *pgo) begin(ctx BaseModuleContext) {
- // TODO Evaluate if we need to support PGO for host modules
- if ctx.Host() {
- return
- }
-
- // Check if PGO is needed for this module
- pgo.Properties.PgoPresent = pgo.Properties.isPGO(ctx)
-
- if !pgo.Properties.PgoPresent {
- return
- }
-
- // This module should be instrumented if ANDROID_PGO_INSTRUMENT is set
- // and includes 'all', 'ALL' or a benchmark listed for this module.
- //
- // TODO Validate that each benchmark instruments at least one module
- pgo.Properties.ShouldProfileModule = false
- pgoBenchmarks := ctx.Config().Getenv("ANDROID_PGO_INSTRUMENT")
- pgoBenchmarksMap := make(map[string]bool)
- for _, b := range strings.Split(pgoBenchmarks, ",") {
- pgoBenchmarksMap[b] = true
- }
-
- if pgoBenchmarksMap["all"] == true || pgoBenchmarksMap["ALL"] == true {
- pgo.Properties.ShouldProfileModule = true
- pgo.Properties.PgoInstrLink = pgo.Properties.isInstrumentation()
- } else {
- for _, b := range pgo.Properties.Pgo.Benchmarks {
- if pgoBenchmarksMap[b] == true {
- pgo.Properties.ShouldProfileModule = true
- pgo.Properties.PgoInstrLink = pgo.Properties.isInstrumentation()
- break
- }
- }
- }
-
- // PGO profile use is not feasible for a Clang coverage build because
- // -fprofile-use and -fprofile-instr-generate are incompatible.
- if ctx.DeviceConfig().ClangCoverageEnabled() {
- return
- }
-
- if !ctx.Config().IsEnvTrue("ANDROID_PGO_NO_PROFILE_USE") &&
- proptools.BoolDefault(pgo.Properties.Pgo.Enable_profile_use, true) {
- if profileFile := pgo.Properties.getPgoProfileFile(ctx); profileFile.Valid() {
- pgo.Properties.PgoCompile = true
- }
- }
-}
-
-func (pgo *pgo) flags(ctx ModuleContext, flags Flags) Flags {
- if ctx.Host() {
- return flags
- }
-
- // Deduce PgoInstrLink property i.e. whether this module needs to be
- // linked with profile-generation flags. Here, we're setting it if any
- // dependency needs PGO instrumentation. It is initially set in
- // begin() if PGO is directly enabled for this module.
- if ctx.static() && !ctx.staticBinary() {
- // For static libraries, check if any whole_static_libs are
- // linked with profile generation
- ctx.VisitDirectDeps(func(m android.Module) {
- if depTag, ok := ctx.OtherModuleDependencyTag(m).(libraryDependencyTag); ok {
- if depTag.static() && depTag.wholeStatic {
- if cc, ok := m.(*Module); ok {
- if cc.pgo.Properties.PgoInstrLink {
- pgo.Properties.PgoInstrLink = true
- }
- }
- }
- }
- })
- } else {
- // For executables and shared libraries, check all static dependencies.
- ctx.VisitDirectDeps(func(m android.Module) {
- if depTag, ok := ctx.OtherModuleDependencyTag(m).(libraryDependencyTag); ok {
- if depTag.static() {
- if cc, ok := m.(*Module); ok {
- if cc.pgo.Properties.PgoInstrLink {
- pgo.Properties.PgoInstrLink = true
- }
- }
- }
- }
- })
- }
-
- props := pgo.Properties
- // Add flags to profile this module based on its profile_kind
- if (props.ShouldProfileModule && props.isInstrumentation()) || props.PgoInstrLink {
- // Instrumentation PGO use and gather flags cannot coexist.
- return props.addInstrumentationProfileGatherFlags(ctx, flags)
- }
-
- if !ctx.Config().IsEnvTrue("ANDROID_PGO_NO_PROFILE_USE") {
- flags = props.addProfileUseFlags(ctx, flags)
- }
-
- return flags
-}
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index c871e85..6163952 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -184,8 +184,6 @@
PreoptBootClassPathDexFiles android.Paths // file paths of boot class path files
PreoptBootClassPathDexLocations []string // virtual locations of boot class path files
- PreoptExtractedApk bool // Overrides OnlyPreoptModules
-
NoCreateAppImage bool
ForceCreateAppImage bool
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index c13e14a..94707ba 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -124,7 +124,7 @@
return true
}
- if global.OnlyPreoptArtBootImage && !module.PreoptExtractedApk {
+ if global.OnlyPreoptArtBootImage {
return true
}
diff --git a/dexpreopt/dexpreopt_test.go b/dexpreopt/dexpreopt_test.go
index 2b19c9d..230fbb4 100644
--- a/dexpreopt/dexpreopt_test.go
+++ b/dexpreopt/dexpreopt_test.go
@@ -87,7 +87,6 @@
DexPreoptImageLocationsOnHost: []string{},
PreoptBootClassPathDexFiles: nil,
PreoptBootClassPathDexLocations: nil,
- PreoptExtractedApk: false,
NoCreateAppImage: false,
ForceCreateAppImage: false,
PresignedPrebuilt: false,
diff --git a/genrule/allowlists.go b/genrule/allowlists.go
index 56b61bf..2405345 100644
--- a/genrule/allowlists.go
+++ b/genrule/allowlists.go
@@ -24,20 +24,10 @@
SandboxingDenyModuleList = []string{
// go/keep-sorted start
"CtsApkVerityTestDebugFiles",
- "ScriptGroupTest-rscript",
"aidl-golden-test-build-hook-gen",
"aidl_camera_build_version",
"camera-its",
- "chre_atoms_log.h",
- "cronet_aml_base_android_runtime_jni_headers",
- "cronet_aml_base_android_runtime_jni_headers__testing",
- "cronet_aml_base_android_runtime_unchecked_jni_headers",
- "cronet_aml_base_android_runtime_unchecked_jni_headers__testing",
- "deqp_spvtools_update_build_version",
- "gen_corrupt_rebootless_apex",
- "gen_key_mismatch_capex",
"libcore-non-cts-tests-txt",
- "seller-frontend-service-stub-lite",
"swiftshader_spvtools_update_build_version",
"vm-tests-tf-lib",
// go/keep-sorted end
@@ -46,7 +36,6 @@
SandboxingDenyPathList = []string{
// go/keep-sorted start
"art/test",
- "external/cronet",
// go/keep-sorted end
}
)
diff --git a/java/Android.bp b/java/Android.bp
index cf96871..9f42771 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -67,7 +67,6 @@
"plugin.go",
"prebuilt_apis.go",
"proto.go",
- "resourceshrinker.go",
"robolectric.go",
"rro.go",
"sdk.go",
@@ -107,7 +106,6 @@
"plugin_test.go",
"prebuilt_apis_test.go",
"proto_test.go",
- "resourceshrinker_test.go",
"rro_test.go",
"sdk_test.go",
"sdk_library_test.go",
diff --git a/java/app.go b/java/app.go
index 6d7411d..6ec6bb2 100755
--- a/java/app.go
+++ b/java/app.go
@@ -544,7 +544,7 @@
return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
}
-func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path {
+func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path) {
a.dexpreopter.installPath = a.installPath(ctx)
a.dexpreopter.isApp = true
if a.dexProperties.Uncompress_dex == nil {
@@ -557,7 +557,15 @@
a.dexpreopter.manifestFile = a.mergedManifestFile
a.dexpreopter.preventInstall = a.appProperties.PreventInstall
+ var packageResources = a.exportPackage
+
if ctx.ModuleName() != "framework-res" {
+ if Bool(a.dexProperties.Optimize.Shrink_resources) {
+ protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk")
+ aapt2Convert(ctx, protoFile, packageResources, "proto")
+ a.dexer.resourcesInput = android.OptionalPathForPath(protoFile)
+ }
+
var extraSrcJars android.Paths
var extraClasspathJars android.Paths
var extraCombinedJars android.Paths
@@ -575,9 +583,14 @@
}
a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars)
+ if Bool(a.dexProperties.Optimize.Shrink_resources) {
+ binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk")
+ aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary")
+ packageResources = binaryResources
+ }
}
- return a.dexJarFile.PathOrNil()
+ return a.dexJarFile.PathOrNil(), packageResources
}
func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath {
@@ -762,7 +775,6 @@
// Process all building blocks, from AAPT to certificates.
a.aaptBuildActions(ctx)
-
// The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
a.usesLibrary.freezeEnforceUsesLibraries()
@@ -788,7 +800,7 @@
a.linter.resources = a.aapt.resourceFiles
a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
- dexJarFile := a.dexBuildActions(ctx)
+ dexJarFile, packageResources := a.dexBuildActions(ctx)
jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis))
jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx)
@@ -812,7 +824,7 @@
}
rotationMinSdkVersion := String(a.overridableAppProperties.RotationMinSdkVersion)
- CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion, Bool(a.dexProperties.Optimize.Shrink_resources))
+ CreateAndSignAppPackage(ctx, packageFile, packageResources, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
a.outputFile = packageFile
if v4SigningRequested {
a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
@@ -841,7 +853,7 @@
if v4SigningRequested {
v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
}
- CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion, false)
+ CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
if v4SigningRequested {
a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
diff --git a/java/app_builder.go b/java/app_builder.go
index d397ff7..943ce31 100644
--- a/java/app_builder.go
+++ b/java/app_builder.go
@@ -52,7 +52,7 @@
})
func CreateAndSignAppPackage(ctx android.ModuleContext, outputFile android.WritablePath,
- packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate, deps android.Paths, v4SignatureFile android.WritablePath, lineageFile android.Path, rotationMinSdkVersion string, shrinkResources bool) {
+ packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate, deps android.Paths, v4SignatureFile android.WritablePath, lineageFile android.Path, rotationMinSdkVersion string) {
unsignedApkName := strings.TrimSuffix(outputFile.Base(), ".apk") + "-unsigned.apk"
unsignedApk := android.PathForModuleOut(ctx, unsignedApkName)
@@ -71,12 +71,6 @@
Output: unsignedApk,
Implicits: deps,
})
-
- if shrinkResources {
- shrunkenApk := android.PathForModuleOut(ctx, "resource-shrunken", unsignedApk.Base())
- ShrinkResources(ctx, unsignedApk, shrunkenApk)
- unsignedApk = shrunkenApk
- }
SignAppPackage(ctx, outputFile, unsignedApk, certificates, v4SignatureFile, lineageFile, rotationMinSdkVersion)
}
diff --git a/java/dex.go b/java/dex.go
index dab0836..4dd020e 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -95,6 +95,8 @@
proguardDictionary android.OptionalPath
proguardConfiguration android.OptionalPath
proguardUsageZip android.OptionalPath
+ resourcesInput android.OptionalPath
+ resourcesOutput android.OptionalPath
providesTransitiveHeaderJars
}
@@ -160,7 +162,7 @@
"$r8Template": &remoteexec.REParams{
Labels: map[string]string{"type": "compile", "compiler": "r8"},
Inputs: []string{"$implicits", "${config.R8Jar}"},
- OutputFiles: []string{"${outUsage}", "${outConfig}", "${outDict}"},
+ OutputFiles: []string{"${outUsage}", "${outConfig}", "${outDict}", "${resourcesOutput}"},
ExecStrategy: "${config.RER8ExecStrategy}",
ToolchainInputs: []string{"${config.JavaCmd}"},
Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
@@ -180,7 +182,7 @@
Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
},
}, []string{"outDir", "outDict", "outConfig", "outUsage", "outUsageZip", "outUsageDir",
- "r8Flags", "zipFlags", "mergeZipsFlags"}, []string{"implicits"})
+ "r8Flags", "zipFlags", "mergeZipsFlags", "resourcesOutput"}, []string{"implicits"})
func (d *dexer) dexCommonFlags(ctx android.ModuleContext,
dexParams *compileDexParams) (flags []string, deps android.Paths) {
@@ -349,6 +351,12 @@
r8Flags = append(r8Flags, "-ignorewarnings")
}
+ if d.resourcesInput.Valid() {
+ r8Flags = append(r8Flags, "--resource-input", d.resourcesInput.Path().String())
+ r8Deps = append(r8Deps, d.resourcesInput.Path())
+ r8Flags = append(r8Flags, "--resource-output", d.resourcesOutput.Path().String())
+ }
+
return r8Flags, r8Deps
}
@@ -390,6 +398,8 @@
android.ModuleNameWithPossibleOverride(ctx), "unused.txt")
proguardUsageZip := android.PathForModuleOut(ctx, "proguard_usage.zip")
d.proguardUsageZip = android.OptionalPathForPath(proguardUsageZip)
+ resourcesOutput := android.PathForModuleOut(ctx, "package-res-shrunken.apk")
+ d.resourcesOutput = android.OptionalPathForPath(resourcesOutput)
r8Flags, r8Deps := d.r8Flags(ctx, dexParams.flags)
r8Deps = append(r8Deps, commonDeps...)
rule := r8
@@ -408,17 +418,22 @@
rule = r8RE
args["implicits"] = strings.Join(r8Deps.Strings(), ",")
}
+ implicitOutputs := android.WritablePaths{
+ proguardDictionary,
+ proguardUsageZip,
+ proguardConfiguration}
+ if d.resourcesInput.Valid() {
+ implicitOutputs = append(implicitOutputs, resourcesOutput)
+ args["resourcesOutput"] = resourcesOutput.String()
+ }
ctx.Build(pctx, android.BuildParams{
- Rule: rule,
- Description: "r8",
- Output: javalibJar,
- ImplicitOutputs: android.WritablePaths{
- proguardDictionary,
- proguardUsageZip,
- proguardConfiguration},
- Input: dexParams.classesJar,
- Implicits: r8Deps,
- Args: args,
+ Rule: rule,
+ Description: "r8",
+ Output: javalibJar,
+ ImplicitOutputs: implicitOutputs,
+ Input: dexParams.classesJar,
+ Implicits: r8Deps,
+ Args: args,
})
} else {
d8Flags, d8Deps := d8Flags(dexParams.flags)
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 998730e..fe8c5fb 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -374,8 +374,6 @@
PreoptBootClassPathDexFiles: dexFiles.Paths(),
PreoptBootClassPathDexLocations: dexLocations,
- PreoptExtractedApk: false,
-
NoCreateAppImage: !BoolDefault(d.dexpreoptProperties.Dex_preopt.App_image, true),
ForceCreateAppImage: BoolDefault(d.dexpreoptProperties.Dex_preopt.App_image, false),
diff --git a/java/droidstubs.go b/java/droidstubs.go
index 180ba92..6b8d21f 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -19,7 +19,6 @@
"path/filepath"
"regexp"
"sort"
- "strconv"
"strings"
"github.com/google/blueprint/proptools"
@@ -500,18 +499,20 @@
if metalavaUseRbe(ctx) {
rule.Remoteable(android.RemoteRuleSupports{RBE: true})
execStrategy := ctx.Config().GetenvWithDefault("RBE_METALAVA_EXEC_STRATEGY", remoteexec.LocalExecStrategy)
- compare, _ := strconv.ParseBool(ctx.Config().GetenvWithDefault("RBE_METALAVA_COMPARE", "false"))
+ compare := ctx.Config().IsEnvTrue("RBE_METALAVA_COMPARE")
+ remoteUpdateCache := !ctx.Config().IsEnvFalse("RBE_METALAVA_REMOTE_UPDATE_CACHE")
labels := map[string]string{"type": "tool", "name": "metalava"}
// TODO: metalava pool rejects these jobs
pool := ctx.Config().GetenvWithDefault("RBE_METALAVA_POOL", "java16")
rule.Rewrapper(&remoteexec.REParams{
- Labels: labels,
- ExecStrategy: execStrategy,
- ToolchainInputs: []string{config.JavaCmd(ctx).String()},
- Platform: map[string]string{remoteexec.PoolKey: pool},
- Compare: compare,
- NumLocalRuns: 1,
- NumRemoteRuns: 1,
+ Labels: labels,
+ ExecStrategy: execStrategy,
+ ToolchainInputs: []string{config.JavaCmd(ctx).String()},
+ Platform: map[string]string{remoteexec.PoolKey: pool},
+ Compare: compare,
+ NumLocalRuns: 1,
+ NumRemoteRuns: 1,
+ NoRemoteUpdateCache: !remoteUpdateCache,
})
}
diff --git a/java/resourceshrinker.go b/java/resourceshrinker.go
deleted file mode 100644
index af13aa3..0000000
--- a/java/resourceshrinker.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2022 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 (
- "android/soong/android"
-
- "github.com/google/blueprint"
-)
-
-var shrinkResources = pctx.AndroidStaticRule("shrinkResources",
- blueprint.RuleParams{
- // Note that we suppress stdout to avoid successful log confirmations.
- Command: `RESOURCESHRINKER_OPTS=-Dcom.android.tools.r8.dexContainerExperiment ` +
- `${config.ResourceShrinkerCmd} --output $out --input $in --raw_resources $raw_resources >/dev/null`,
- CommandDeps: []string{"${config.ResourceShrinkerCmd}"},
- }, "raw_resources")
-
-func ShrinkResources(ctx android.ModuleContext, apk android.Path, outputFile android.WritablePath) {
- protoFile := android.PathForModuleOut(ctx, apk.Base()+".proto.apk")
- aapt2Convert(ctx, protoFile, apk, "proto")
- strictModeFile := android.PathForSource(ctx, "prebuilts/cmdline-tools/shrinker.xml")
- protoOut := android.PathForModuleOut(ctx, apk.Base()+".proto.out.apk")
- ctx.Build(pctx, android.BuildParams{
- Rule: shrinkResources,
- Input: protoFile,
- Output: protoOut,
- Args: map[string]string{
- "raw_resources": strictModeFile.String(),
- },
- })
- aapt2Convert(ctx, outputFile, protoOut, "binary")
-}
diff --git a/java/resourceshrinker_test.go b/java/resourceshrinker_test.go
deleted file mode 100644
index 3bbf116..0000000
--- a/java/resourceshrinker_test.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2022 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 (
- "testing"
-
- "android/soong/android"
-)
-
-func TestShrinkResourcesArgs(t *testing.T) {
- result := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- ).RunTestWithBp(t, `
- android_app {
- name: "app_shrink",
- platform_apis: true,
- optimize: {
- shrink_resources: true,
- }
- }
-
- android_app {
- name: "app_no_shrink",
- platform_apis: true,
- optimize: {
- shrink_resources: false,
- }
- }
- `)
-
- appShrink := result.ModuleForTests("app_shrink", "android_common")
- appShrinkResources := appShrink.Rule("shrinkResources")
- android.AssertStringDoesContain(t, "expected shrinker.xml in app_shrink resource shrinker flags",
- appShrinkResources.Args["raw_resources"], "shrinker.xml")
-
- appNoShrink := result.ModuleForTests("app_no_shrink", "android_common")
- if appNoShrink.MaybeRule("shrinkResources").Rule != nil {
- t.Errorf("unexpected shrinkResources rule for app_no_shrink")
- }
-}
diff --git a/phony/phony.go b/phony/phony.go
index 760b79b..a8b651a 100644
--- a/phony/phony.go
+++ b/phony/phony.go
@@ -52,7 +52,6 @@
fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)", " # phony.phony")
fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
fmt.Fprintln(w, "LOCAL_MODULE :=", name)
- data.Entries.WriteLicenseVariables(w)
if p.Host() {
fmt.Fprintln(w, "LOCAL_IS_HOST_MODULE := true")
}
diff --git a/remoteexec/remoteexec.go b/remoteexec/remoteexec.go
index 1e181fb..8294c3f 100644
--- a/remoteexec/remoteexec.go
+++ b/remoteexec/remoteexec.go
@@ -91,6 +91,8 @@
NumLocalRuns int
// Number of times the action should be rerun remotely.
NumRemoteRuns int
+ // Boolean indicating whether to update remote cache entry. Rewrapper defaults to true, so the name is negated here.
+ NoRemoteUpdateCache bool
}
func init() {
@@ -146,6 +148,10 @@
args += fmt.Sprintf(" --compare=true --num_local_reruns=%d --num_remote_reruns=%d", r.NumLocalRuns, r.NumRemoteRuns)
}
+ if r.NoRemoteUpdateCache {
+ args += " --remote_update_cache=false"
+ }
+
if len(r.Inputs) > 0 {
args += " --inputs=" + strings.Join(r.Inputs, ",")
}
diff --git a/rust/config/global.go b/rust/config/global.go
index 64c9460..3802bdd 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -25,7 +25,7 @@
pctx = android.NewPackageContext("android/soong/rust/config")
ExportedVars = android.NewExportedVariables(pctx)
- RustDefaultVersion = "1.72.1"
+ RustDefaultVersion = "1.73.0"
RustDefaultBase = "prebuilts/rust/"
DefaultEdition = "2021"
Stdlibs = []string{
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index fe2cc9c..8bf5f14 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -351,7 +351,6 @@
// Actual implementation libraries are created on LoadHookMutator
fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)", " # sysprop.syspropLibrary")
fmt.Fprintln(w, "LOCAL_MODULE :=", m.Name())
- data.Entries.WriteLicenseVariables(w)
fmt.Fprintf(w, "LOCAL_MODULE_CLASS := FAKE\n")
fmt.Fprintf(w, "LOCAL_MODULE_TAGS := optional\n")
fmt.Fprintf(w, "include $(BUILD_SYSTEM)/base_rules.mk\n\n")
diff --git a/ui/status/ninja.go b/ui/status/ninja.go
index 7b25d50..1e97908 100644
--- a/ui/status/ninja.go
+++ b/ui/status/ninja.go
@@ -20,6 +20,7 @@
"io"
"os"
"regexp"
+ "runtime"
"strings"
"syscall"
"time"
@@ -178,7 +179,28 @@
// msgChan is closed
break
}
- // Ignore msg.BuildStarted
+
+ if msg.BuildStarted != nil {
+ parallelism := uint32(runtime.NumCPU())
+ if msg.BuildStarted.GetParallelism() > 0 {
+ parallelism = msg.BuildStarted.GetParallelism()
+ }
+ // It is estimated from total time / parallelism assumming the build is packing enough.
+ estimatedDurationFromTotal := time.Duration(msg.BuildStarted.GetEstimatedTotalTime()/parallelism) * time.Millisecond
+ // It is estimated from critical path time which is useful for small size build.
+ estimatedDurationFromCriticalPath := time.Duration(msg.BuildStarted.GetCriticalPathTime()) * time.Millisecond
+ // Select the longer one.
+ estimatedDuration := max(estimatedDurationFromTotal, estimatedDurationFromCriticalPath)
+
+ if estimatedDuration > 0 {
+ n.status.SetEstimatedTime(time.Now().Add(estimatedDuration))
+ n.status.Verbose(fmt.Sprintf("parallelism: %d, estimiated from total time: %s, critical path time: %s",
+ parallelism,
+ estimatedDurationFromTotal,
+ estimatedDurationFromCriticalPath))
+
+ }
+ }
if msg.TotalEdges != nil {
n.status.SetTotalActions(int(msg.TotalEdges.GetTotalEdges()))
}
diff --git a/ui/status/ninja_frontend/frontend.pb.go b/ui/status/ninja_frontend/frontend.pb.go
index d0c4953..d8344c8 100644
--- a/ui/status/ninja_frontend/frontend.pb.go
+++ b/ui/status/ninja_frontend/frontend.pb.go
@@ -14,7 +14,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.28.1
+// protoc-gen-go v1.30.0
// protoc v3.21.12
// source: frontend.proto
@@ -240,6 +240,10 @@
Parallelism *uint32 `protobuf:"varint,1,opt,name=parallelism" json:"parallelism,omitempty"`
// Verbose value passed to ninja.
Verbose *bool `protobuf:"varint,2,opt,name=verbose" json:"verbose,omitempty"`
+ // Critical path's running time in milliseconds
+ CriticalPathTime *uint32 `protobuf:"varint,3,opt,name=critical_path_time,json=criticalPathTime" json:"critical_path_time,omitempty"`
+ // Total running time of every need-to-build edge in milliseconds
+ EstimatedTotalTime *uint32 `protobuf:"varint,4,opt,name=estimated_total_time,json=estimatedTotalTime" json:"estimated_total_time,omitempty"`
}
func (x *Status_BuildStarted) Reset() {
@@ -288,6 +292,20 @@
return false
}
+func (x *Status_BuildStarted) GetCriticalPathTime() uint32 {
+ if x != nil && x.CriticalPathTime != nil {
+ return *x.CriticalPathTime
+ }
+ return 0
+}
+
+func (x *Status_BuildStarted) GetEstimatedTotalTime() uint32 {
+ if x != nil && x.EstimatedTotalTime != nil {
+ return *x.EstimatedTotalTime
+ }
+ return 0
+}
+
type Status_BuildFinished struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -660,7 +678,7 @@
var file_frontend_proto_rawDesc = []byte{
0x0a, 0x0e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
- 0x12, 0x05, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x22, 0xc8, 0x0a, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74,
+ 0x12, 0x05, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x22, 0xa9, 0x0b, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74,
0x75, 0x73, 0x12, 0x39, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x65, 0x64, 0x67, 0x65,
0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x2e,
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x64, 0x67, 0x65,
@@ -687,67 +705,73 @@
0x67, 0x65, 0x1a, 0x2d, 0x0a, 0x0a, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x64, 0x67, 0x65, 0x73,
0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x65, 0x64, 0x67, 0x65, 0x73, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x64, 0x67, 0x65,
- 0x73, 0x1a, 0x4a, 0x0a, 0x0c, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65,
- 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x69, 0x73, 0x6d,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c,
- 0x69, 0x73, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x1a, 0x0f, 0x0a,
- 0x0d, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x1a, 0xb6,
- 0x01, 0x0a, 0x0b, 0x45, 0x64, 0x67, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x12, 0x0e,
- 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1d,
- 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
- 0x28, 0x0d, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a,
- 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x69,
- 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73,
- 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x12,
- 0x12, 0x0a, 0x04, 0x64, 0x65, 0x73, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64,
- 0x65, 0x73, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x06,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x18, 0x0a,
- 0x07, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07,
- 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x1a, 0xf3, 0x03, 0x0a, 0x0c, 0x45, 0x64, 0x67, 0x65,
- 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01,
- 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f,
- 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x54,
- 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20,
- 0x01, 0x28, 0x11, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f,
- 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74,
- 0x70, 0x75, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x74, 0x69, 0x6d, 0x65,
- 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65,
- 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18,
- 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x54, 0x69, 0x6d,
- 0x65, 0x12, 0x1c, 0x0a, 0x0a, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x73, 0x73, 0x5f, 0x6b, 0x62, 0x18,
- 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x52, 0x73, 0x73, 0x4b, 0x62, 0x12,
- 0x2a, 0x0a, 0x11, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x66, 0x61,
- 0x75, 0x6c, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6d, 0x69, 0x6e, 0x6f,
- 0x72, 0x50, 0x61, 0x67, 0x65, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6d,
- 0x61, 0x6a, 0x6f, 0x72, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73,
- 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x50, 0x61, 0x67,
- 0x65, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x1e, 0x0a, 0x0b, 0x69, 0x6f, 0x5f, 0x69, 0x6e,
- 0x70, 0x75, 0x74, 0x5f, 0x6b, 0x62, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x69, 0x6f,
- 0x49, 0x6e, 0x70, 0x75, 0x74, 0x4b, 0x62, 0x12, 0x20, 0x0a, 0x0c, 0x69, 0x6f, 0x5f, 0x6f, 0x75,
- 0x74, 0x70, 0x75, 0x74, 0x5f, 0x6b, 0x62, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x69,
- 0x6f, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x4b, 0x62, 0x12, 0x3c, 0x0a, 0x1a, 0x76, 0x6f, 0x6c,
- 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x73,
- 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x04, 0x52, 0x18, 0x76,
- 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x53,
- 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x40, 0x0a, 0x1c, 0x69, 0x6e, 0x76, 0x6f, 0x6c,
- 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x73,
- 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1a, 0x69,
- 0x6e, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78,
- 0x74, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67,
- 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x1a, 0x92, 0x01,
- 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x37, 0x0a, 0x05, 0x6c, 0x65, 0x76,
- 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x6e, 0x69, 0x6e, 0x6a, 0x61,
- 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e,
- 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x3a, 0x04, 0x49, 0x4e, 0x46, 0x4f, 0x52, 0x05, 0x6c, 0x65, 0x76,
- 0x65, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x34, 0x0a, 0x05,
- 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x00, 0x12,
- 0x0b, 0x0a, 0x07, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05,
- 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x45, 0x42, 0x55, 0x47,
- 0x10, 0x03, 0x42, 0x2a, 0x48, 0x03, 0x5a, 0x26, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f,
- 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x75, 0x69, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f,
- 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x5f, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64,
+ 0x73, 0x1a, 0xaa, 0x01, 0x0a, 0x0c, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74,
+ 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x69, 0x73,
+ 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65,
+ 0x6c, 0x69, 0x73, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x12, 0x2c,
+ 0x0a, 0x12, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f,
+ 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x63, 0x72, 0x69, 0x74,
+ 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x14,
+ 0x65, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f,
+ 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x65, 0x73, 0x74, 0x69,
+ 0x6d, 0x61, 0x74, 0x65, 0x64, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x1a, 0x0f,
+ 0x0a, 0x0d, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x1a,
+ 0xb6, 0x01, 0x0a, 0x0b, 0x45, 0x64, 0x67, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x12,
+ 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12,
+ 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x0d, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x16,
+ 0x0a, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06,
+ 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74,
+ 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73,
+ 0x12, 0x12, 0x0a, 0x04, 0x64, 0x65, 0x73, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
+ 0x64, 0x65, 0x73, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18,
+ 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x18,
+ 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52,
+ 0x07, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x1a, 0xf3, 0x03, 0x0a, 0x0c, 0x45, 0x64, 0x67,
+ 0x65, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x6e, 0x64,
+ 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x65, 0x6e, 0x64,
+ 0x54, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03,
+ 0x20, 0x01, 0x28, 0x11, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06,
+ 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75,
+ 0x74, 0x70, 0x75, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x74, 0x69, 0x6d,
+ 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x54, 0x69, 0x6d,
+ 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x74, 0x69, 0x6d, 0x65,
+ 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x54, 0x69,
+ 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x0a, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x73, 0x73, 0x5f, 0x6b, 0x62,
+ 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x52, 0x73, 0x73, 0x4b, 0x62,
+ 0x12, 0x2a, 0x0a, 0x11, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x66,
+ 0x61, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6d, 0x69, 0x6e,
+ 0x6f, 0x72, 0x50, 0x61, 0x67, 0x65, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x11,
+ 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x66, 0x61, 0x75, 0x6c, 0x74,
+ 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x50, 0x61,
+ 0x67, 0x65, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x1e, 0x0a, 0x0b, 0x69, 0x6f, 0x5f, 0x69,
+ 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x6b, 0x62, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x69,
+ 0x6f, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x4b, 0x62, 0x12, 0x20, 0x0a, 0x0c, 0x69, 0x6f, 0x5f, 0x6f,
+ 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x6b, 0x62, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a,
+ 0x69, 0x6f, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x4b, 0x62, 0x12, 0x3c, 0x0a, 0x1a, 0x76, 0x6f,
+ 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f,
+ 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x04, 0x52, 0x18,
+ 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
+ 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x40, 0x0a, 0x1c, 0x69, 0x6e, 0x76, 0x6f,
+ 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f,
+ 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1a,
+ 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65,
+ 0x78, 0x74, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61,
+ 0x67, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x1a, 0x92,
+ 0x01, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x37, 0x0a, 0x05, 0x6c, 0x65,
+ 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x6e, 0x69, 0x6e, 0x6a,
+ 0x61, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+ 0x2e, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x3a, 0x04, 0x49, 0x4e, 0x46, 0x4f, 0x52, 0x05, 0x6c, 0x65,
+ 0x76, 0x65, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x34, 0x0a,
+ 0x05, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x00,
+ 0x12, 0x0b, 0x0a, 0x07, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x09, 0x0a,
+ 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x45, 0x42, 0x55,
+ 0x47, 0x10, 0x03, 0x42, 0x2a, 0x48, 0x03, 0x5a, 0x26, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x75, 0x69, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
+ 0x2f, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x5f, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64,
}
var (
diff --git a/ui/status/ninja_frontend/frontend.proto b/ui/status/ninja_frontend/frontend.proto
index 6cb4a0d..42b251b 100644
--- a/ui/status/ninja_frontend/frontend.proto
+++ b/ui/status/ninja_frontend/frontend.proto
@@ -30,6 +30,10 @@
optional uint32 parallelism = 1;
// Verbose value passed to ninja.
optional bool verbose = 2;
+ // Critical path's running time in milliseconds
+ optional uint32 critical_path_time = 3;
+ // Total running time of every need-to-build edge in milliseconds
+ optional uint32 estimated_total_time = 4;
}
message BuildFinished {
diff --git a/ui/status/status.go b/ui/status/status.go
index f3e58b6..da78994 100644
--- a/ui/status/status.go
+++ b/ui/status/status.go
@@ -19,6 +19,7 @@
import (
"sync"
+ "time"
)
// Action describes an action taken (or as Ninja calls them, Edges).
@@ -107,6 +108,8 @@
// FinishedActions are the number of actions that have been finished
// with FinishAction.
FinishedActions int
+
+ EstimatedTime time.Time
}
// ToolStatus is the interface used by tools to report on their Actions, and to
@@ -118,6 +121,7 @@
// This call be will ignored if it sets a number that is less than the
// current number of started actions.
SetTotalActions(total int)
+ SetEstimatedTime(estimatedTime time.Time)
// StartAction specifies that the associated action has been started by
// the tool.
@@ -267,6 +271,13 @@
s.counts.TotalActions += diff
}
+func (s *Status) SetEstimatedTime(estimatedTime time.Time) {
+ s.lock.Lock()
+ defer s.lock.Unlock()
+
+ s.counts.EstimatedTime = estimatedTime
+}
+
func (s *Status) startAction(action *Action) {
s.lock.Lock()
defer s.lock.Unlock()
@@ -329,6 +340,10 @@
}
}
+func (d *toolStatus) SetEstimatedTime(estimatedTime time.Time) {
+ d.status.SetEstimatedTime(estimatedTime)
+}
+
func (d *toolStatus) StartAction(action *Action) {
totalDiff := 0
diff --git a/ui/terminal/format.go b/ui/terminal/format.go
index 4205bdc..241a1dd 100644
--- a/ui/terminal/format.go
+++ b/ui/terminal/format.go
@@ -51,9 +51,22 @@
return ""
}
+func remainingTimeString(t time.Time) string {
+ now := time.Now()
+ if t.After(now) {
+ return t.Sub(now).Round(time.Duration(time.Second)).String()
+ }
+ return time.Duration(0).Round(time.Duration(time.Second)).String()
+}
func (s formatter) progress(counts status.Counts) string {
if s.format == "" {
- return fmt.Sprintf("[%3d%% %d/%d] ", 100*counts.FinishedActions/counts.TotalActions, counts.FinishedActions, counts.TotalActions)
+ output := fmt.Sprintf("[%3d%% %d/%d", 100*counts.FinishedActions/counts.TotalActions, counts.FinishedActions, counts.TotalActions)
+
+ if !counts.EstimatedTime.IsZero() {
+ output += fmt.Sprintf(" %s remaining", remainingTimeString(counts.EstimatedTime))
+ }
+ output += "] "
+ return output
}
buf := &strings.Builder{}
@@ -93,6 +106,13 @@
fmt.Fprintf(buf, "%3d%%", 100*counts.FinishedActions/counts.TotalActions)
case 'e':
fmt.Fprintf(buf, "%.3f", time.Since(s.start).Seconds())
+ case 'l':
+ if counts.EstimatedTime.IsZero() {
+ // No esitimated data
+ buf.WriteRune('?')
+ } else {
+ fmt.Fprintf(buf, "%s", remainingTimeString(counts.EstimatedTime))
+ }
default:
buf.WriteString("unknown placeholder '")
buf.WriteByte(c)
diff --git a/ui/terminal/smart_status.go b/ui/terminal/smart_status.go
index 3880b04..4575ccf 100644
--- a/ui/terminal/smart_status.go
+++ b/ui/terminal/smart_status.go
@@ -31,8 +31,9 @@
const tableHeightEnVar = "SOONG_UI_TABLE_HEIGHT"
type actionTableEntry struct {
- action *status.Action
- startTime time.Time
+ action *status.Action
+ startTime time.Time
+ estimatedEndTime time.Time
}
type smartStatusOutput struct {