Merge "Enable -Wsizeof-array-div for 3P code." into main
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 2438726..fb2e0d7 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -228,6 +228,7 @@
 		"frameworks/base/services/tests/servicestests/aidl":  Bp2BuildDefaultTrue,
 		"frameworks/base/startop/apps/test":                  Bp2BuildDefaultTrue,
 		"frameworks/base/tests/appwidgets/AppWidgetHostTest": Bp2BuildDefaultTrueRecursively,
+		"frameworks/base/tools/aapt":                         Bp2BuildDefaultTrue,
 		"frameworks/base/tools/aapt2":                        Bp2BuildDefaultTrue,
 		"frameworks/base/tools/codegen":                      Bp2BuildDefaultTrueRecursively,
 		"frameworks/base/tools/streaming_proto":              Bp2BuildDefaultTrueRecursively,
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 42ba9b4..4b98345 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -1382,10 +1382,7 @@
 			WriteFileRuleVerbatim(ctx, out, "")
 		case "FileWrite", "SourceSymlinkManifest":
 			out := PathForBazelOut(ctx, buildStatement.OutputPaths[0])
-			// TODO(b/297366783) This is a hack to make files from skylib's diff_test executable.
-			// We need to update bazel to have aquery tell us whether a file is supposed to be
-			// executable or not.
-			if strings.HasSuffix(buildStatement.OutputPaths[0], "-test.sh") {
+			if buildStatement.IsExecutable {
 				WriteExecutableFileRuleVerbatim(ctx, out, buildStatement.FileContents)
 			} else {
 				WriteFileRuleVerbatim(ctx, out, buildStatement.FileContents)
diff --git a/android/config.go b/android/config.go
index 0b15c79..1a3b539 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1792,30 +1792,6 @@
 	return c.PlatformSepolicyVersion()
 }
 
-func (c *deviceConfig) BoardPlatVendorPolicy() []string {
-	return c.config.productVariables.BoardPlatVendorPolicy
-}
-
-func (c *deviceConfig) BoardReqdMaskPolicy() []string {
-	return c.config.productVariables.BoardReqdMaskPolicy
-}
-
-func (c *deviceConfig) BoardSystemExtPublicPrebuiltDirs() []string {
-	return c.config.productVariables.BoardSystemExtPublicPrebuiltDirs
-}
-
-func (c *deviceConfig) BoardSystemExtPrivatePrebuiltDirs() []string {
-	return c.config.productVariables.BoardSystemExtPrivatePrebuiltDirs
-}
-
-func (c *deviceConfig) BoardProductPublicPrebuiltDirs() []string {
-	return c.config.productVariables.BoardProductPublicPrebuiltDirs
-}
-
-func (c *deviceConfig) BoardProductPrivatePrebuiltDirs() []string {
-	return c.config.productVariables.BoardProductPrivatePrebuiltDirs
-}
-
 func (c *deviceConfig) SystemExtSepolicyPrebuiltApiDir() string {
 	return String(c.config.productVariables.SystemExtSepolicyPrebuiltApiDir)
 }
diff --git a/android/defs.go b/android/defs.go
index 682111e..b28d2fa 100644
--- a/android/defs.go
+++ b/android/defs.go
@@ -107,8 +107,8 @@
 
 	Cat = pctx.AndroidStaticRule("Cat",
 		blueprint.RuleParams{
-			Command:     "cat $in > $out",
-			Description: "concatenate licenses $out",
+			Command:     "rm -f $out && cat $in > $out",
+			Description: "concatenate files to $out",
 		})
 
 	// ubuntu 14.04 offcially use dash for /bin/sh, and its builtin echo command
@@ -116,7 +116,7 @@
 	// content to file.
 	writeFile = pctx.AndroidStaticRule("writeFile",
 		blueprint.RuleParams{
-			Command:     `/bin/bash -c 'echo -e -n "$$0" > $out' $content`,
+			Command:     `rm -f $out && /bin/bash -c 'echo -e -n "$$0" > $out' $content`,
 			Description: "writing file $out",
 		},
 		"content")
diff --git a/android/proto.go b/android/proto.go
index 3c4b4c7..7c418c6 100644
--- a/android/proto.go
+++ b/android/proto.go
@@ -350,13 +350,12 @@
 var (
 	protoIncludeDirGeneratedSuffix = ".include_dir_bp2build_generated_proto"
 	protoIncludeDirsBp2buildKey    = NewOnceKey("protoIncludeDirsBp2build")
-	protoIncludeDirsBp2buildLock   sync.Mutex
 )
 
-func getProtoIncludeDirsBp2build(config Config) *map[protoIncludeDirKey]bool {
+func getProtoIncludeDirsBp2build(config Config) *sync.Map {
 	return config.Once(protoIncludeDirsBp2buildKey, func() interface{} {
-		return &map[protoIncludeDirKey]bool{}
-	}).(*map[protoIncludeDirKey]bool)
+		return &sync.Map{}
+	}).(*sync.Map)
 }
 
 // key for dynamically creating proto_library per proto.include_dirs
@@ -370,9 +369,6 @@
 // might create the targets in a subdirectory of `includeDir`
 // Returns the labels of the proto_library targets
 func createProtoLibraryTargetsForIncludeDirs(ctx Bp2buildMutatorContext, includeDirs []string) bazel.LabelList {
-	protoIncludeDirsBp2buildLock.Lock()
-	defer protoIncludeDirsBp2buildLock.Unlock()
-
 	var ret bazel.LabelList
 	for _, dir := range includeDirs {
 		if exists, _, _ := ctx.Config().fs.Exists(filepath.Join(dir, "Android.bp")); !exists {
@@ -389,11 +385,10 @@
 				Label: "//" + pkg + ":" + label,
 			})
 			key := protoIncludeDirKey{dir: dir, subpackgeInDir: pkg}
-			if _, exists := (*dirMap)[key]; exists {
+			if _, exists := dirMap.LoadOrStore(key, true); exists {
 				// A proto_library has already been created for this package relative to this include dir
 				continue
 			}
-			(*dirMap)[key] = true
 			srcs := protoLabelelsPartitionedByPkg[pkg]
 			rel, err := filepath.Rel(dir, pkg)
 			if err != nil {
diff --git a/android/variable.go b/android/variable.go
index 8805fe5..89ac915 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -372,17 +372,11 @@
 
 	MultitreeUpdateMeta bool `json:",omitempty"`
 
-	BoardVendorSepolicyDirs           []string `json:",omitempty"`
-	BoardOdmSepolicyDirs              []string `json:",omitempty"`
-	BoardReqdMaskPolicy               []string `json:",omitempty"`
-	BoardPlatVendorPolicy             []string `json:",omitempty"`
-	BoardSystemExtPublicPrebuiltDirs  []string `json:",omitempty"`
-	BoardSystemExtPrivatePrebuiltDirs []string `json:",omitempty"`
-	BoardProductPublicPrebuiltDirs    []string `json:",omitempty"`
-	BoardProductPrivatePrebuiltDirs   []string `json:",omitempty"`
-	SystemExtPublicSepolicyDirs       []string `json:",omitempty"`
-	SystemExtPrivateSepolicyDirs      []string `json:",omitempty"`
-	BoardSepolicyM4Defs               []string `json:",omitempty"`
+	BoardVendorSepolicyDirs      []string `json:",omitempty"`
+	BoardOdmSepolicyDirs         []string `json:",omitempty"`
+	SystemExtPublicSepolicyDirs  []string `json:",omitempty"`
+	SystemExtPrivateSepolicyDirs []string `json:",omitempty"`
+	BoardSepolicyM4Defs          []string `json:",omitempty"`
 
 	BoardSepolicyVers       *string `json:",omitempty"`
 	PlatformSepolicyVersion *string `json:",omitempty"`
diff --git a/bazel/aquery.go b/bazel/aquery.go
index d77d59a..76cd972 100644
--- a/bazel/aquery.go
+++ b/bazel/aquery.go
@@ -123,6 +123,7 @@
 	// Unlike most properties in BuildStatement, these paths must be relative to the root of
 	// the whole out/ folder, instead of relative to ctx.Config().BazelContext.OutputBase()
 	ImplicitDeps []string
+	IsExecutable bool
 }
 
 // A helper type for aquery processing which facilitates retrieval of path IDs from their
@@ -560,6 +561,7 @@
 		Mnemonic:          actionEntry.Mnemonic,
 		InputDepsetHashes: depsetHashes,
 		FileContents:      actionEntry.FileContents,
+		IsExecutable:      actionEntry.IsExecutable,
 	}, nil
 }
 
diff --git a/bp2build/android_app_conversion_test.go b/bp2build/android_app_conversion_test.go
index 25494a1..f2ee322 100644
--- a/bp2build/android_app_conversion_test.go
+++ b/bp2build/android_app_conversion_test.go
@@ -47,6 +47,11 @@
 		name: "TestApp",
 		srcs: ["app.java"],
 		sdk_version: "current",
+		optimize: {
+			shrink: true,
+			optimize: true,
+			obfuscate: true,
+		},
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -75,17 +80,25 @@
 		},
 		Blueprint: simpleModuleDoNotConvertBp2build("android_app", "static_lib_dep") + `
 android_app {
-		name: "TestApp",
-		srcs: ["app.java"],
-		sdk_version: "current",
-		package_name: "com.google",
-		resource_dirs: ["resa", "resb"],
-		manifest: "manifest/AndroidManifest.xml",
-		static_libs: ["static_lib_dep"],
-		java_version: "7",
-		certificate: "foocert",
-		required: ["static_lib_dep"],
-		asset_dirs: ["assets_"],
+	name: "TestApp",
+	srcs: ["app.java"],
+	sdk_version: "current",
+	package_name: "com.google",
+	resource_dirs: ["resa", "resb"],
+	manifest: "manifest/AndroidManifest.xml",
+	static_libs: ["static_lib_dep"],
+	java_version: "7",
+	certificate: "foocert",
+	required: ["static_lib_dep"],
+	asset_dirs: ["assets_"],
+	optimize: {
+		enabled: true,
+		optimize: false,
+		proguard_flags_files: ["proguard.flags"],
+		shrink: false,
+		obfuscate: false,
+		ignore_warnings: true,
+	},
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -103,6 +116,14 @@
 				"java_version":     `"7"`,
 				"sdk_version":      `"current"`,
 				"certificate_name": `"foocert"`,
+				"proguard_specs": `[
+        "proguard.flags",
+        ":TestApp_proguard_flags",
+    ]`,
+			}),
+			MakeBazelTarget("genrule", "TestApp_proguard_flags", AttrNameToString{
+				"outs": `["TestApp_proguard.flags"]`,
+				"cmd":  `"echo -ignorewarning -dontshrink -dontoptimize -dontobfuscate > $(OUTS)"`,
 			}),
 		}})
 }
@@ -129,7 +150,10 @@
 		x86: {
 			srcs: ["x86.java"],
 		}
-	}
+	},
+	optimize: {
+		enabled: false,
+	},
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -142,6 +166,7 @@
 				"manifest":       `"AndroidManifest.xml"`,
 				"resource_files": `["res/res.png"]`,
 				"sdk_version":    `"current"`,
+				"optimize":       `False`,
 			}),
 		}})
 }
@@ -157,6 +182,9 @@
 	name: "TestApp",
 	certificate: ":foocert",
 	sdk_version: "current",
+	optimize: {
+		enabled: false,
+	},
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -165,6 +193,7 @@
 				"manifest":       `"AndroidManifest.xml"`,
 				"resource_files": `[]`,
 				"sdk_version":    `"current"`, // use as default
+				"optimize":       `False`,
 			}),
 		}})
 }
@@ -182,6 +211,9 @@
 	name: "TestApp",
 	certificate: "foocert",
 	sdk_version: "current",
+	optimize: {
+		enabled: false,
+	},
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -190,6 +222,7 @@
 				"manifest":       `"AndroidManifest.xml"`,
 				"resource_files": `[]`,
 				"sdk_version":    `"current"`, // use as default
+				"optimize":       `False`,
 			}),
 		}})
 }
@@ -207,6 +240,9 @@
 	name: "TestApp",
 	certificate: "foocert",
 	sdk_version: "current",
+	optimize: {
+		enabled: false,
+	},
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -215,6 +251,7 @@
 				"manifest":         `"AndroidManifest.xml"`,
 				"resource_files":   `[]`,
 				"sdk_version":      `"current"`, // use as default
+				"optimize":         `False`,
 			}),
 		}})
 }
@@ -225,12 +262,14 @@
 		ModuleTypeUnderTest:        "android_app",
 		ModuleTypeUnderTestFactory: java.AndroidAppFactory,
 		Filesystem:                 map[string]string{},
-		Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") +
-			simpleModuleDoNotConvertBp2build("java_library", "barLib") + `
+		Blueprint: simpleModuleDoNotConvertBp2build("java_library", "barLib") + `
 android_app {
 	name: "foo",
 	libs: ["barLib"],
 	sdk_version: "current",
+	optimize: {
+		enabled: false,
+	},
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -239,6 +278,7 @@
 				"resource_files": `[]`,
 				"deps":           `[":barLib-neverlink"]`,
 				"sdk_version":    `"current"`, // use as default
+				"optimize":       `False`,
 			}),
 		}})
 }
@@ -260,6 +300,9 @@
 	manifest: "fooManifest.xml",
 	libs: ["barLib"],
 	sdk_version: "current",
+	optimize: {
+		enabled: false,
+	},
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -278,6 +321,7 @@
 				"certificate": `":foocert"`,
 				"manifest":    `"fooManifest.xml"`,
 				"sdk_version": `"current"`, // use as default
+				"optimize":    `False`,
 			}),
 		}})
 }
@@ -290,15 +334,17 @@
 		Filesystem: map[string]string{
 			"res/res.png": "",
 		},
-		Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") + `
+		Blueprint: `
 android_app {
 	name: "foo",
 	srcs: ["a.java"],
 	common_srcs: ["b.kt"],
-	certificate: "foocert",
 	manifest: "fooManifest.xml",
 	libs:        ["barLib"],
 	sdk_version: "current",
+	optimize: {
+		enabled: false,
+	},
 }
 java_library{
 	name:   "barLib",
@@ -315,10 +361,10 @@
 				"sdk_version":    `"current"`, // use as default
 			}),
 			MakeBazelTarget("android_binary", "foo", AttrNameToString{
-				"deps":             `[":foo_kt"]`,
-				"certificate_name": `"foocert"`,
-				"manifest":         `"fooManifest.xml"`,
-				"sdk_version":      `"current"`, // use as default
+				"deps":        `[":foo_kt"]`,
+				"manifest":    `"fooManifest.xml"`,
+				"sdk_version": `"current"`, // use as default
+				"optimize":    `False`,
 			}),
 		}})
 }
@@ -331,14 +377,16 @@
 		Filesystem: map[string]string{
 			"res/res.png": "",
 		},
-		Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") + `
+		Blueprint: `
 android_app {
 	name: "foo",
 	srcs: ["a.java", "b.kt"],
-	certificate: ":foocert",
 	manifest: "fooManifest.xml",
 	kotlincflags: ["-flag1", "-flag2"],
 	sdk_version: "current",
+	optimize: {
+		enabled: false,
+	},
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -357,9 +405,9 @@
 			}),
 			MakeBazelTarget("android_binary", "foo", AttrNameToString{
 				"deps":        `[":foo_kt"]`,
-				"certificate": `":foocert"`,
 				"manifest":    `"fooManifest.xml"`,
 				"sdk_version": `"current"`,
+				"optimize":    `False`,
 			}),
 		}})
 }
@@ -370,13 +418,16 @@
 		ModuleTypeUnderTest:        "android_app",
 		ModuleTypeUnderTestFactory: java.AndroidAppFactory,
 		Filesystem:                 map[string]string{},
-		Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") + `
+		Blueprint: `
 android_app {
 	name: "foo",
 	sdk_version: "current",
 	min_sdk_version: "24",
 	max_sdk_version: "30",
 	target_sdk_version: "29",
+	optimize: {
+		enabled: false,
+	},
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -389,6 +440,7 @@
         "targetSdkVersion": "29",
     }`,
 				"sdk_version": `"current"`,
+				"optimize":    `False`,
 			}),
 		}})
 }
@@ -399,10 +451,13 @@
 		ModuleTypeUnderTest:        "android_app",
 		ModuleTypeUnderTestFactory: java.AndroidAppFactory,
 		Filesystem:                 map[string]string{},
-		Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") + `
+		Blueprint: `
 android_app {
 	name: "foo",
 	sdk_version: "30",
+	optimize: {
+		enabled: false,
+	},
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -414,6 +469,7 @@
         "targetSdkVersion": "30",
     }`,
 				"sdk_version": `"30"`,
+				"optimize":    `False`,
 			}),
 		}})
 }
diff --git a/cc/config/global.go b/cc/config/global.go
index 5fbb311..b662ef0 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -317,7 +317,7 @@
 
 	// prebuilts/clang default settings.
 	ClangDefaultBase         = "prebuilts/clang/host"
-	ClangDefaultVersion      = "clang-r498229"
+	ClangDefaultVersion      = "clang-r498229b"
 	ClangDefaultShortVersion = "17"
 
 	// Directories with warnings from Android.bp files.
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 8e3f278..d1c2f13 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -912,7 +912,7 @@
 	Out []string
 }
 
-type bazelGenruleAttributes struct {
+type BazelGenruleAttributes struct {
 	Srcs  bazel.LabelListAttribute
 	Outs  []string
 	Tools bazel.LabelListAttribute
@@ -1036,7 +1036,7 @@
 				break
 			}
 		}
-		attrs := &bazelGenruleAttributes{
+		attrs := &BazelGenruleAttributes{
 			Srcs:  srcs,
 			Outs:  outs,
 			Cmd:   cmdProp,
diff --git a/java/app.go b/java/app.go
index dadae48..d71cd77 100755
--- a/java/app.go
+++ b/java/app.go
@@ -29,6 +29,7 @@
 	"android/soong/bazel"
 	"android/soong/cc"
 	"android/soong/dexpreopt"
+	"android/soong/genrule"
 	"android/soong/tradefed"
 )
 
@@ -1614,6 +1615,8 @@
 	Certificate      bazel.LabelAttribute
 	Certificate_name bazel.StringAttribute
 	Manifest_values  *manifestValueAttribute
+	Optimize         *bool
+	Proguard_specs   bazel.LabelListAttribute
 }
 
 // ConvertWithBp2build is used to convert android_app to Bazel.
@@ -1665,6 +1668,41 @@
 		Manifest_values:  manifestValues,
 	}
 
+	if !BoolDefault(a.dexProperties.Optimize.Enabled, true) {
+		appAttrs.Optimize = proptools.BoolPtr(false)
+	} else {
+		handCraftedFlags := ""
+		if Bool(a.dexProperties.Optimize.Ignore_warnings) {
+			handCraftedFlags += "-ignorewarning "
+		}
+		if !Bool(a.dexProperties.Optimize.Shrink) {
+			handCraftedFlags += "-dontshrink "
+		}
+		if !Bool(a.dexProperties.Optimize.Optimize) {
+			handCraftedFlags += "-dontoptimize "
+		}
+		if !Bool(a.dexProperties.Optimize.Obfuscate) {
+			handCraftedFlags += "-dontobfuscate "
+		}
+		appAttrs.Proguard_specs = bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, a.dexProperties.Optimize.Proguard_flags_files))
+		if handCraftedFlags != "" {
+			generatedFlagFileRuleName := a.Name() + "_proguard_flags"
+			ctx.CreateBazelTargetModule(bazel.BazelTargetModuleProperties{
+				Rule_class: "genrule",
+			}, android.CommonAttributes{
+				Name:     generatedFlagFileRuleName,
+				SkipData: proptools.BoolPtr(true),
+			}, &genrule.BazelGenruleAttributes{
+				Outs: []string{a.Name() + "_proguard.flags"},
+				Cmd: bazel.StringAttribute{
+					Value: proptools.StringPtr("echo " + handCraftedFlags + "> $(OUTS)"),
+				},
+			})
+			appAttrs.Proguard_specs.Add(bazel.MakeLabelAttribute(":" + generatedFlagFileRuleName))
+		}
+
+	}
+
 	props := bazel.BazelTargetModuleProperties{
 		Rule_class:        "android_binary",
 		Bzl_load_location: "//build/bazel/rules/android:android_binary.bzl",
diff --git a/java/java.go b/java/java.go
index 6c448a2..521aef3 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1735,7 +1735,6 @@
 
 	cmd.Flag("--color").
 		Flag("--quiet").
-		Flag("--format=v2").
 		Flag("--include-annotations").
 		// The flag makes nullability issues as warnings rather than errors by replacing
 		// @Nullable/@NonNull in the listed packages APIs with @RecentlyNullable/@RecentlyNonNull,
@@ -1747,14 +1746,13 @@
 		FlagWithArg("--hide ", "InvalidNullabilityOverride").
 		FlagWithArg("--hide ", "ChangedDefault")
 
-	// Force metalava to ignore classes on the classpath when an API file contains missing classes.
-	// See b/285140653 for more information.
+	// The main purpose of the `--api-class-resolution api` option is to force metalava to ignore
+	// classes on the classpath when an API file contains missing classes. However, as this command
+	// does not specify `--classpath` this is not needed for that. However, this is also used as a
+	// signal to the special metalava code for generating stubs from text files that it needs to add
+	// some additional items into the API (e.g. default constructors).
 	cmd.FlagWithArg("--api-class-resolution ", "api")
 
-	// Force metalava to sort overloaded methods by their order in the source code.
-	// See b/285312164 for more information.
-	cmd.FlagWithArg("--api-overloaded-method-order ", "source")
-
 	return cmd
 }
 
@@ -1916,7 +1914,7 @@
 		FlagWithArg("-C ", stubsDir.String()).
 		FlagWithArg("-D ", stubsDir.String())
 
-	rule.Build("metalava", "metalava merged")
+	rule.Build("metalava", "metalava merged text")
 
 	if depApiSrcsStubsJar == nil {
 		var flags javaBuilderFlags
diff --git a/python/python.go b/python/python.go
index 8b31c6c..7d77ca7 100644
--- a/python/python.go
+++ b/python/python.go
@@ -462,8 +462,7 @@
 
 	// generate the zipfile of all source and data files
 	p.srcsZip = p.createSrcsZip(ctx, pkgPath)
-	// TODO(b/278602456): precompilation temporarily disabled for python3.11 upgrade
-	p.precompiledSrcsZip = p.srcsZip //p.precompileSrcs(ctx)
+	p.precompiledSrcsZip = p.precompileSrcs(ctx)
 }
 
 func isValidPythonPath(path string) error {
diff --git a/tests/sbom_test.sh b/tests/sbom_test.sh
index 9801a8e..9ba19cf 100755
--- a/tests/sbom_test.sh
+++ b/tests/sbom_test.sh
@@ -91,6 +91,7 @@
   diff_excludes[system]="\
     -I /system/bin/assemble_cvd \
     -I /system/bin/console_forwarder \
+    -I /system/bin/hwservicemanager \
     -I /system/bin/kernel_log_monitor \
     -I /system/bin/logcat_receiver \
     -I /system/bin/mkenvimage_slim \