diff --git a/README.md b/README.md index d093b4bc..e6ae3a2a 100644 --- a/README.md +++ b/README.md @@ -46,4 +46,4 @@ https://developer.android.com/studio/command-line/bundletool ## Releases -Latest release: [1.17.0](https://github.com/google/bundletool/releases) +Latest release: [1.17.1](https://github.com/google/bundletool/releases) diff --git a/gradle.properties b/gradle.properties index 996134a8..fe59b282 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -release_version = 1.17.0 +release_version = 1.17.1 diff --git a/src/main/java/com/android/tools/build/bundletool/model/AndroidManifest.java b/src/main/java/com/android/tools/build/bundletool/model/AndroidManifest.java index d29b2cf2..4ca41388 100644 --- a/src/main/java/com/android/tools/build/bundletool/model/AndroidManifest.java +++ b/src/main/java/com/android/tools/build/bundletool/model/AndroidManifest.java @@ -98,6 +98,7 @@ public abstract class AndroidManifest { public static final String MAIN_ACTION_ELEMENT_NAME = "action"; public static final String DATA_ELEMENT_NAME = "data"; + public static final String APP_CATEGORY_ATTRIBUTE_NAME = "appCategory"; public static final String DEBUGGABLE_ATTRIBUTE_NAME = "debuggable"; public static final String EXTRACT_NATIVE_LIBS_ATTRIBUTE_NAME = "extractNativeLibs"; public static final String ICON_ATTRIBUTE_NAME = "icon"; @@ -192,6 +193,7 @@ public abstract class AndroidManifest { /** name that specifies native library for native activity */ public static final String NATIVE_ACTIVITY_LIB_NAME = "android.app.lib_name"; + public static final int APP_CATEGORY_RESOURCE_ID = 0x01010545; public static final int DEBUGGABLE_RESOURCE_ID = 0x0101000f; public static final int EXTRACT_NATIVE_LIBS_RESOURCE_ID = 0x10104ea; public static final int REQUIRED_RESOURCE_ID = 0x0101028e; @@ -373,6 +375,17 @@ public AndroidManifest applyMutators(ImmutableList manifestMuta return manifestEditor.save(); } + /** + * Extracts value of the {@code } attribute. + * + * @return An optional containing the value of the {@code appCategory} attribute if set, or an + * empty optional if not set. + */ + public Optional getApplicationAppCategory() { + return getApplicationAttribute(APP_CATEGORY_RESOURCE_ID) + .map(XmlProtoAttribute::getValueAsString); + } + /** * Extracts value of the {@code } attribute. * diff --git a/src/main/java/com/android/tools/build/bundletool/model/ManifestEditor.java b/src/main/java/com/android/tools/build/bundletool/model/ManifestEditor.java index 1a4d13ef..2db7c243 100644 --- a/src/main/java/com/android/tools/build/bundletool/model/ManifestEditor.java +++ b/src/main/java/com/android/tools/build/bundletool/model/ManifestEditor.java @@ -207,6 +207,16 @@ public ManifestEditor setLocaleConfig(int resourceId) { LOCALE_CONFIG_ATTRIBUTE_NAME, LOCALE_CONFIG_RESOURCE_ID, resourceId); } + @CanIgnoreReturnValue + public ManifestEditor setAppCategory(String appCategory) { + manifestElement + .getOrCreateChildElement(APPLICATION_ELEMENT_NAME) + .getOrCreateAndroidAttribute( + AndroidManifest.APP_CATEGORY_ATTRIBUTE_NAME, AndroidManifest.APP_CATEGORY_RESOURCE_ID) + .setValueAsString(appCategory); + return this; + } + @CanIgnoreReturnValue public ManifestEditor addMetaDataString(String key, String value) { return addMetaDataValue( diff --git a/src/main/java/com/android/tools/build/bundletool/model/OptimizationDimension.java b/src/main/java/com/android/tools/build/bundletool/model/OptimizationDimension.java index 445b0c6f..39c34ed2 100644 --- a/src/main/java/com/android/tools/build/bundletool/model/OptimizationDimension.java +++ b/src/main/java/com/android/tools/build/bundletool/model/OptimizationDimension.java @@ -23,5 +23,6 @@ public enum OptimizationDimension { LANGUAGE, TEXTURE_COMPRESSION_FORMAT, DEVICE_TIER, - COUNTRY_SET + COUNTRY_SET, + AI_MODEL_VERSION } diff --git a/src/main/java/com/android/tools/build/bundletool/model/version/BundleToolVersion.java b/src/main/java/com/android/tools/build/bundletool/model/version/BundleToolVersion.java index e29e4194..805bfd94 100644 --- a/src/main/java/com/android/tools/build/bundletool/model/version/BundleToolVersion.java +++ b/src/main/java/com/android/tools/build/bundletool/model/version/BundleToolVersion.java @@ -26,7 +26,7 @@ */ public final class BundleToolVersion { - private static final String CURRENT_VERSION = "1.17.0"; + private static final String CURRENT_VERSION = "1.17.1"; /** Returns the version of BundleTool being run. */ diff --git a/src/main/java/com/android/tools/build/bundletool/validation/AndroidManifestValidator.java b/src/main/java/com/android/tools/build/bundletool/validation/AndroidManifestValidator.java index 295dfbd2..a2c5a72c 100644 --- a/src/main/java/com/android/tools/build/bundletool/validation/AndroidManifestValidator.java +++ b/src/main/java/com/android/tools/build/bundletool/validation/AndroidManifestValidator.java @@ -384,7 +384,13 @@ private static void validateNumberOfDistinctSplitIds(BundleModule module) { private static void validateAssetModuleManifest(BundleModule module) { ImmutableMultimap allowedManifestElementChildren = - ImmutableMultimap.of(DISTRIBUTION_NAMESPACE_URI, "module", NO_NAMESPACE_URI, "uses-split"); + ImmutableMultimap.of( + DISTRIBUTION_NAMESPACE_URI, + "module", + NO_NAMESPACE_URI, + "uses-split", + NO_NAMESPACE_URI, + "application"); AndroidManifest manifest = module.getAndroidManifest(); if (!manifest.getModuleType().equals(ModuleType.ASSET_MODULE)) { diff --git a/src/main/proto/config.proto b/src/main/proto/config.proto index 55539770..5f955a07 100644 --- a/src/main/proto/config.proto +++ b/src/main/proto/config.proto @@ -280,6 +280,7 @@ message SplitDimension { TEXTURE_COMPRESSION_FORMAT = 4; DEVICE_TIER = 6; COUNTRY_SET = 7; + AI_MODEL_VERSION = 8; } Value value = 1; diff --git a/src/test/java/com/android/tools/build/bundletool/model/AndroidManifestTest.java b/src/test/java/com/android/tools/build/bundletool/model/AndroidManifestTest.java index 886bf30c..7f9bb8df 100644 --- a/src/test/java/com/android/tools/build/bundletool/model/AndroidManifestTest.java +++ b/src/test/java/com/android/tools/build/bundletool/model/AndroidManifestTest.java @@ -16,6 +16,7 @@ package com.android.tools.build.bundletool.model; +import static com.android.tools.build.bundletool.model.AndroidManifest.APP_CATEGORY_RESOURCE_ID; import static com.android.tools.build.bundletool.model.AndroidManifest.APP_COMPONENT_FACTORY_ATTRIBUTE_NAME; import static com.android.tools.build.bundletool.model.AndroidManifest.APP_COMPONENT_FACTORY_RESOURCE_ID; import static com.android.tools.build.bundletool.model.AndroidManifest.AUTHORITIES_ATTRIBUTE_NAME; @@ -149,6 +150,24 @@ public void hasMainActivity_definedAsActivityAlias_returnTrue() { assertThat(androidManifest.hasMainActivity()).isTrue(); } + @Test + public void getApplicationAppCategory_equalsGame() { + AndroidManifest androidManifest = + AndroidManifest.create( + xmlNode( + xmlElement( + "manifest", + xmlNode( + xmlElement( + "application", + xmlAttribute( + ANDROID_NAMESPACE_URI, + "appCategory", + APP_CATEGORY_RESOURCE_ID, + "game")))))); + assertThat(androidManifest.getApplicationAppCategory()).hasValue("game"); + } + @Test public void getApplicationDebuggable_presentFalse() { AndroidManifest androidManifest = diff --git a/src/test/java/com/android/tools/build/bundletool/model/ManifestEditorTest.java b/src/test/java/com/android/tools/build/bundletool/model/ManifestEditorTest.java index 173f1ffb..c2a111bb 100644 --- a/src/test/java/com/android/tools/build/bundletool/model/ManifestEditorTest.java +++ b/src/test/java/com/android/tools/build/bundletool/model/ManifestEditorTest.java @@ -20,6 +20,8 @@ import static com.android.tools.build.bundletool.model.AndroidManifest.ALLOW_BACKUP_ATTRIBUTE_NAME; import static com.android.tools.build.bundletool.model.AndroidManifest.ALLOW_BACKUP_RESOURCE_ID; import static com.android.tools.build.bundletool.model.AndroidManifest.APPLICATION_ELEMENT_NAME; +import static com.android.tools.build.bundletool.model.AndroidManifest.APP_CATEGORY_ATTRIBUTE_NAME; +import static com.android.tools.build.bundletool.model.AndroidManifest.APP_CATEGORY_RESOURCE_ID; import static com.android.tools.build.bundletool.model.AndroidManifest.CATEGORY_ELEMENT_NAME; import static com.android.tools.build.bundletool.model.AndroidManifest.CERTIFICATE_DIGEST_ATTRIBUTE_NAME; import static com.android.tools.build.bundletool.model.AndroidManifest.DELIVERY_ELEMENT_NAME; @@ -386,6 +388,21 @@ public void setVersionCode() { ANDROID_NAMESPACE_URI, "versionCode", VERSION_CODE_RESOURCE_ID, 123)); } + @Test + public void setAppCategory() { + AndroidManifest androidManifest = createManifestWithApplicationElement(); + + AndroidManifest editedManifest = androidManifest.toEditor().setAppCategory("game").save(); + + assertThat(getApplicationElement(editedManifest).getAttributeList()) + .containsExactly( + xmlAttribute( + ANDROID_NAMESPACE_URI, + APP_CATEGORY_ATTRIBUTE_NAME, + APP_CATEGORY_RESOURCE_ID, + "game")); + } + @Test public void setConfigForSplit() { AndroidManifest androidManifest = createManifestWithApplicationElement(); diff --git a/src/test/java/com/android/tools/build/bundletool/validation/AndroidManifestValidatorTest.java b/src/test/java/com/android/tools/build/bundletool/validation/AndroidManifestValidatorTest.java index 1acb8395..3debc257 100644 --- a/src/test/java/com/android/tools/build/bundletool/validation/AndroidManifestValidatorTest.java +++ b/src/test/java/com/android/tools/build/bundletool/validation/AndroidManifestValidatorTest.java @@ -722,7 +722,7 @@ public void assetModule_noApplication_ok() throws Exception { } @Test - public void assetModule_withApplication_throws() throws Exception { + public void assetModule_withApplication_ok() throws Exception { BundleModule module = new BundleModuleBuilder("asset_module") .setManifest( @@ -730,13 +730,7 @@ public void assetModule_withApplication_throws() throws Exception { "com.test.app", withOnDemandDelivery(), withApplication())) .build(); - Throwable exception = - assertThrows( - InvalidBundleException.class, - () -> new AndroidManifestValidator().validateModule(module)); - assertThat(exception) - .hasMessageThat() - .matches("Unexpected element declaration in manifest of asset pack 'asset_module'."); + new AndroidManifestValidator().validateModule(module); } @DataPoints("sdkMutators")