Loading core/java/android/app/appfunctions/AppFunctionManagerHelper.java +10 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.app.appfunctions; import static android.app.appfunctions.AppFunctionManager.APP_FUNCTION_STATE_DEFAULT; import static android.app.appfunctions.AppFunctionManager.APP_FUNCTION_STATE_ENABLED; import static android.app.appfunctions.AppFunctionRuntimeMetadata.PROPERTY_APP_FUNCTION_STATIC_METADATA_QUALIFIED_ID; import static android.app.appfunctions.AppFunctionRuntimeMetadata.PROPERTY_ENABLED; import static android.app.appfunctions.AppFunctionStaticMetadataHelper.APP_FUNCTION_INDEXER_PACKAGE; Loading Loading @@ -166,15 +168,18 @@ public class AppFunctionManagerHelper { if (runtimeMetadataResults.isEmpty()) { throw new IllegalArgumentException("App function not found."); } boolean[] enabled = long enabled = runtimeMetadataResults .getFirst() .getGenericDocument() .getPropertyBooleanArray(PROPERTY_ENABLED); if (enabled != null && enabled.length != 0) { return enabled[0]; .getPropertyLong(PROPERTY_ENABLED); // If enabled is not equal to APP_FUNCTION_STATE_DEFAULT, it means it IS overridden and // we should return the overridden value. if (enabled != APP_FUNCTION_STATE_DEFAULT) { return enabled == APP_FUNCTION_STATE_ENABLED; } // Runtime metadata not found. Using the default value in the static metadata. // Runtime metadata not found or enabled is equal to APP_FUNCTION_STATE_DEFAULT. // Using the default value in the static metadata. return joinedStaticRuntimeResults .getFirst() .getGenericDocument() Loading core/java/android/app/appfunctions/AppFunctionRuntimeMetadata.java +18 −14 Original line number Diff line number Diff line Loading @@ -16,11 +16,15 @@ package android.app.appfunctions; import static android.app.appfunctions.AppFunctionManager.APP_FUNCTION_STATE_DEFAULT; import static android.app.appfunctions.AppFunctionManager.APP_FUNCTION_STATE_DISABLED; import static android.app.appfunctions.AppFunctionManager.APP_FUNCTION_STATE_ENABLED; import static android.app.appfunctions.flags.Flags.FLAG_ENABLE_APP_FUNCTION_MANAGER; import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.appfunctions.AppFunctionManager.EnabledState; import android.app.appsearch.AppSearchSchema; import android.app.appsearch.GenericDocument; Loading Loading @@ -162,15 +166,13 @@ public class AppFunctionRuntimeMetadata extends GenericDocument { * Returns if the function is set to be enabled or not. If not set, the {@link * AppFunctionStaticMetadataHelper#STATIC_PROPERTY_ENABLED_BY_DEFAULT} value would be used. */ @Nullable public Boolean getEnabled() { // We can't use getPropertyBoolean here. getPropertyBoolean returns false instead of null // if the value is missing. boolean[] enabled = getPropertyBooleanArray(PROPERTY_ENABLED); if (enabled == null || enabled.length == 0) { return null; } return enabled[0]; @EnabledState public int getEnabled() { // getPropertyLong returns the first long associated with the given path or default value 0 // if there is no such value or the value is of a different type. // APP_FUNCTION_STATE_DEFAULT also equals 0 which means the returned value will be 0 when an // app as either never changed the enabled bit at runtime or has reset it to the default. return (int) getPropertyLong(PROPERTY_ENABLED); } /** Returns the qualified id linking to the static metadata of the app function. */ Loading Loading @@ -217,12 +219,14 @@ public class AppFunctionRuntimeMetadata extends GenericDocument { * TODO(369683073) Replace the tristate Boolean with IntDef EnabledState. */ @NonNull public Builder setEnabled(@Nullable Boolean enabled) { if (enabled == null) { setPropertyBoolean(PROPERTY_ENABLED); } else { setPropertyBoolean(PROPERTY_ENABLED, enabled); public Builder setEnabled(@EnabledState int enabledState) { if (enabledState != APP_FUNCTION_STATE_DEFAULT && enabledState != APP_FUNCTION_STATE_ENABLED && enabledState != APP_FUNCTION_STATE_DISABLED) { throw new IllegalArgumentException( "Value of EnabledState is unsupported."); } setPropertyLong(PROPERTY_ENABLED, enabledState); return this; } Loading services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java +4 −18 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ package com.android.server.appfunctions; import static android.app.appfunctions.AppFunctionManager.APP_FUNCTION_STATE_DISABLED; import static android.app.appfunctions.AppFunctionManager.APP_FUNCTION_STATE_ENABLED; import static android.app.appfunctions.AppFunctionRuntimeMetadata.APP_FUNCTION_RUNTIME_METADATA_DB; import static android.app.appfunctions.AppFunctionRuntimeMetadata.APP_FUNCTION_RUNTIME_NAMESPACE; Loading Loading @@ -363,26 +361,14 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { callingPackage, functionIdentifier, runtimeMetadataSearchSession)); AppFunctionRuntimeMetadata.Builder newMetadata = new AppFunctionRuntimeMetadata.Builder(existingMetadata); switch (enabledState) { case AppFunctionManager.APP_FUNCTION_STATE_DEFAULT -> { newMetadata.setEnabled(null); } case APP_FUNCTION_STATE_ENABLED -> { newMetadata.setEnabled(true); } case APP_FUNCTION_STATE_DISABLED -> { newMetadata.setEnabled(false); } default -> throw new IllegalArgumentException("Value of EnabledState is unsupported."); } AppFunctionRuntimeMetadata newMetadata = new AppFunctionRuntimeMetadata.Builder(existingMetadata) .setEnabled(enabledState).build(); AppSearchBatchResult<String, Void> putDocumentBatchResult = runtimeMetadataSearchSession .put( new PutDocumentsRequest.Builder() .addGenericDocuments(newMetadata.build()) .addGenericDocuments(newMetadata) .build()) .get(); if (!putDocumentBatchResult.isSuccess()) { Loading services/tests/appfunctions/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ android_test { "androidx.test.core", "androidx.test.runner", "androidx.test.ext.truth", "kotlin-test", "platform-test-annotations", "services.appfunctions", "servicestests-core-utils", Loading services/tests/appfunctions/src/android/app/appfunctions/AppFunctionRuntimeMetadataTest.kt +25 −10 Original line number Diff line number Diff line Loading @@ -15,8 +15,12 @@ */ package android.app.appfunctions import android.app.appfunctions.AppFunctionManager.APP_FUNCTION_STATE_DEFAULT import android.app.appfunctions.AppFunctionManager.APP_FUNCTION_STATE_DISABLED import android.app.appfunctions.AppFunctionManager.APP_FUNCTION_STATE_ENABLED import android.app.appsearch.AppSearchSchema import com.google.common.truth.Truth.assertThat import kotlin.test.assertFailsWith import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.JUnit4 Loading Loading @@ -108,32 +112,43 @@ class AppFunctionRuntimeMetadataTest { assertThat(runtimeMetadata.packageName).isEqualTo("com.pkg") assertThat(runtimeMetadata.functionId).isEqualTo("funcId") assertThat(runtimeMetadata.enabled).isNull() assertThat(runtimeMetadata.enabled).isEqualTo(APP_FUNCTION_STATE_DEFAULT) assertThat(runtimeMetadata.appFunctionStaticMetadataQualifiedId) .isEqualTo("android\$apps-db/app_functions#com.pkg/funcId") } @Test fun setEnabled_true() { fun setEnabled_enabled() { val runtimeMetadata = AppFunctionRuntimeMetadata.Builder("com.pkg", "funcId").setEnabled(true).build() AppFunctionRuntimeMetadata.Builder("com.pkg", "funcId").setEnabled(APP_FUNCTION_STATE_ENABLED).build() assertThat(runtimeMetadata.enabled).isTrue() assertThat(runtimeMetadata.enabled).isEqualTo(APP_FUNCTION_STATE_ENABLED) } @Test fun setEnabled_false() { fun setEnabled_disabled() { val runtimeMetadata = AppFunctionRuntimeMetadata.Builder("com.pkg", "funcId").setEnabled(false).build() AppFunctionRuntimeMetadata.Builder("com.pkg", "funcId").setEnabled( APP_FUNCTION_STATE_DISABLED).build() assertThat(runtimeMetadata.enabled).isFalse() assertThat(runtimeMetadata.enabled).isEqualTo(APP_FUNCTION_STATE_DISABLED) } @Test fun setEnabled_null() { fun setEnabled_default() { val runtimeMetadata = AppFunctionRuntimeMetadata.Builder("com.pkg", "funcId").setEnabled(null).build() AppFunctionRuntimeMetadata.Builder("com.pkg", "funcId").setEnabled( APP_FUNCTION_STATE_DEFAULT).build() assertThat(runtimeMetadata.enabled).isNull() assertThat(runtimeMetadata.enabled).isEqualTo(APP_FUNCTION_STATE_DEFAULT) } @Test fun setEnabled_illegalArgument() { val runtimeMetadataBuilder = AppFunctionRuntimeMetadata.Builder("com.pkg", "funcId") assertFailsWith<IllegalArgumentException>("Value of EnabledState is unsupported.") { runtimeMetadataBuilder.setEnabled(-1) } } } Loading
core/java/android/app/appfunctions/AppFunctionManagerHelper.java +10 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.app.appfunctions; import static android.app.appfunctions.AppFunctionManager.APP_FUNCTION_STATE_DEFAULT; import static android.app.appfunctions.AppFunctionManager.APP_FUNCTION_STATE_ENABLED; import static android.app.appfunctions.AppFunctionRuntimeMetadata.PROPERTY_APP_FUNCTION_STATIC_METADATA_QUALIFIED_ID; import static android.app.appfunctions.AppFunctionRuntimeMetadata.PROPERTY_ENABLED; import static android.app.appfunctions.AppFunctionStaticMetadataHelper.APP_FUNCTION_INDEXER_PACKAGE; Loading Loading @@ -166,15 +168,18 @@ public class AppFunctionManagerHelper { if (runtimeMetadataResults.isEmpty()) { throw new IllegalArgumentException("App function not found."); } boolean[] enabled = long enabled = runtimeMetadataResults .getFirst() .getGenericDocument() .getPropertyBooleanArray(PROPERTY_ENABLED); if (enabled != null && enabled.length != 0) { return enabled[0]; .getPropertyLong(PROPERTY_ENABLED); // If enabled is not equal to APP_FUNCTION_STATE_DEFAULT, it means it IS overridden and // we should return the overridden value. if (enabled != APP_FUNCTION_STATE_DEFAULT) { return enabled == APP_FUNCTION_STATE_ENABLED; } // Runtime metadata not found. Using the default value in the static metadata. // Runtime metadata not found or enabled is equal to APP_FUNCTION_STATE_DEFAULT. // Using the default value in the static metadata. return joinedStaticRuntimeResults .getFirst() .getGenericDocument() Loading
core/java/android/app/appfunctions/AppFunctionRuntimeMetadata.java +18 −14 Original line number Diff line number Diff line Loading @@ -16,11 +16,15 @@ package android.app.appfunctions; import static android.app.appfunctions.AppFunctionManager.APP_FUNCTION_STATE_DEFAULT; import static android.app.appfunctions.AppFunctionManager.APP_FUNCTION_STATE_DISABLED; import static android.app.appfunctions.AppFunctionManager.APP_FUNCTION_STATE_ENABLED; import static android.app.appfunctions.flags.Flags.FLAG_ENABLE_APP_FUNCTION_MANAGER; import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.appfunctions.AppFunctionManager.EnabledState; import android.app.appsearch.AppSearchSchema; import android.app.appsearch.GenericDocument; Loading Loading @@ -162,15 +166,13 @@ public class AppFunctionRuntimeMetadata extends GenericDocument { * Returns if the function is set to be enabled or not. If not set, the {@link * AppFunctionStaticMetadataHelper#STATIC_PROPERTY_ENABLED_BY_DEFAULT} value would be used. */ @Nullable public Boolean getEnabled() { // We can't use getPropertyBoolean here. getPropertyBoolean returns false instead of null // if the value is missing. boolean[] enabled = getPropertyBooleanArray(PROPERTY_ENABLED); if (enabled == null || enabled.length == 0) { return null; } return enabled[0]; @EnabledState public int getEnabled() { // getPropertyLong returns the first long associated with the given path or default value 0 // if there is no such value or the value is of a different type. // APP_FUNCTION_STATE_DEFAULT also equals 0 which means the returned value will be 0 when an // app as either never changed the enabled bit at runtime or has reset it to the default. return (int) getPropertyLong(PROPERTY_ENABLED); } /** Returns the qualified id linking to the static metadata of the app function. */ Loading Loading @@ -217,12 +219,14 @@ public class AppFunctionRuntimeMetadata extends GenericDocument { * TODO(369683073) Replace the tristate Boolean with IntDef EnabledState. */ @NonNull public Builder setEnabled(@Nullable Boolean enabled) { if (enabled == null) { setPropertyBoolean(PROPERTY_ENABLED); } else { setPropertyBoolean(PROPERTY_ENABLED, enabled); public Builder setEnabled(@EnabledState int enabledState) { if (enabledState != APP_FUNCTION_STATE_DEFAULT && enabledState != APP_FUNCTION_STATE_ENABLED && enabledState != APP_FUNCTION_STATE_DISABLED) { throw new IllegalArgumentException( "Value of EnabledState is unsupported."); } setPropertyLong(PROPERTY_ENABLED, enabledState); return this; } Loading
services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java +4 −18 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ package com.android.server.appfunctions; import static android.app.appfunctions.AppFunctionManager.APP_FUNCTION_STATE_DISABLED; import static android.app.appfunctions.AppFunctionManager.APP_FUNCTION_STATE_ENABLED; import static android.app.appfunctions.AppFunctionRuntimeMetadata.APP_FUNCTION_RUNTIME_METADATA_DB; import static android.app.appfunctions.AppFunctionRuntimeMetadata.APP_FUNCTION_RUNTIME_NAMESPACE; Loading Loading @@ -363,26 +361,14 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { callingPackage, functionIdentifier, runtimeMetadataSearchSession)); AppFunctionRuntimeMetadata.Builder newMetadata = new AppFunctionRuntimeMetadata.Builder(existingMetadata); switch (enabledState) { case AppFunctionManager.APP_FUNCTION_STATE_DEFAULT -> { newMetadata.setEnabled(null); } case APP_FUNCTION_STATE_ENABLED -> { newMetadata.setEnabled(true); } case APP_FUNCTION_STATE_DISABLED -> { newMetadata.setEnabled(false); } default -> throw new IllegalArgumentException("Value of EnabledState is unsupported."); } AppFunctionRuntimeMetadata newMetadata = new AppFunctionRuntimeMetadata.Builder(existingMetadata) .setEnabled(enabledState).build(); AppSearchBatchResult<String, Void> putDocumentBatchResult = runtimeMetadataSearchSession .put( new PutDocumentsRequest.Builder() .addGenericDocuments(newMetadata.build()) .addGenericDocuments(newMetadata) .build()) .get(); if (!putDocumentBatchResult.isSuccess()) { Loading
services/tests/appfunctions/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ android_test { "androidx.test.core", "androidx.test.runner", "androidx.test.ext.truth", "kotlin-test", "platform-test-annotations", "services.appfunctions", "servicestests-core-utils", Loading
services/tests/appfunctions/src/android/app/appfunctions/AppFunctionRuntimeMetadataTest.kt +25 −10 Original line number Diff line number Diff line Loading @@ -15,8 +15,12 @@ */ package android.app.appfunctions import android.app.appfunctions.AppFunctionManager.APP_FUNCTION_STATE_DEFAULT import android.app.appfunctions.AppFunctionManager.APP_FUNCTION_STATE_DISABLED import android.app.appfunctions.AppFunctionManager.APP_FUNCTION_STATE_ENABLED import android.app.appsearch.AppSearchSchema import com.google.common.truth.Truth.assertThat import kotlin.test.assertFailsWith import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.JUnit4 Loading Loading @@ -108,32 +112,43 @@ class AppFunctionRuntimeMetadataTest { assertThat(runtimeMetadata.packageName).isEqualTo("com.pkg") assertThat(runtimeMetadata.functionId).isEqualTo("funcId") assertThat(runtimeMetadata.enabled).isNull() assertThat(runtimeMetadata.enabled).isEqualTo(APP_FUNCTION_STATE_DEFAULT) assertThat(runtimeMetadata.appFunctionStaticMetadataQualifiedId) .isEqualTo("android\$apps-db/app_functions#com.pkg/funcId") } @Test fun setEnabled_true() { fun setEnabled_enabled() { val runtimeMetadata = AppFunctionRuntimeMetadata.Builder("com.pkg", "funcId").setEnabled(true).build() AppFunctionRuntimeMetadata.Builder("com.pkg", "funcId").setEnabled(APP_FUNCTION_STATE_ENABLED).build() assertThat(runtimeMetadata.enabled).isTrue() assertThat(runtimeMetadata.enabled).isEqualTo(APP_FUNCTION_STATE_ENABLED) } @Test fun setEnabled_false() { fun setEnabled_disabled() { val runtimeMetadata = AppFunctionRuntimeMetadata.Builder("com.pkg", "funcId").setEnabled(false).build() AppFunctionRuntimeMetadata.Builder("com.pkg", "funcId").setEnabled( APP_FUNCTION_STATE_DISABLED).build() assertThat(runtimeMetadata.enabled).isFalse() assertThat(runtimeMetadata.enabled).isEqualTo(APP_FUNCTION_STATE_DISABLED) } @Test fun setEnabled_null() { fun setEnabled_default() { val runtimeMetadata = AppFunctionRuntimeMetadata.Builder("com.pkg", "funcId").setEnabled(null).build() AppFunctionRuntimeMetadata.Builder("com.pkg", "funcId").setEnabled( APP_FUNCTION_STATE_DEFAULT).build() assertThat(runtimeMetadata.enabled).isNull() assertThat(runtimeMetadata.enabled).isEqualTo(APP_FUNCTION_STATE_DEFAULT) } @Test fun setEnabled_illegalArgument() { val runtimeMetadataBuilder = AppFunctionRuntimeMetadata.Builder("com.pkg", "funcId") assertFailsWith<IllegalArgumentException>("Value of EnabledState is unsupported.") { runtimeMetadataBuilder.setEnabled(-1) } } }