Merge "Enforce mainline modules to have latest target sdk version by default."
This commit is contained in:
@@ -270,7 +270,7 @@ var extractAssetsRule = pctx.AndroidStaticRule("extractAssets",
|
|||||||
|
|
||||||
func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkContext,
|
func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkContext,
|
||||||
classLoaderContexts dexpreopt.ClassLoaderContextMap, excludedLibs []string,
|
classLoaderContexts dexpreopt.ClassLoaderContextMap, excludedLibs []string,
|
||||||
extraLinkFlags ...string) {
|
enforceDefaultTargetSdkVersion bool, extraLinkFlags ...string) {
|
||||||
|
|
||||||
transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assetPackages, libDeps, libFlags :=
|
transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assetPackages, libDeps, libFlags :=
|
||||||
aaptLibs(ctx, sdkContext, classLoaderContexts)
|
aaptLibs(ctx, sdkContext, classLoaderContexts)
|
||||||
@@ -292,6 +292,7 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon
|
|||||||
UseEmbeddedDex: a.useEmbeddedDex,
|
UseEmbeddedDex: a.useEmbeddedDex,
|
||||||
HasNoCode: a.hasNoCode,
|
HasNoCode: a.hasNoCode,
|
||||||
LoggingParent: a.LoggingParent,
|
LoggingParent: a.LoggingParent,
|
||||||
|
EnforceDefaultTargetSdkVersion: enforceDefaultTargetSdkVersion,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Add additional manifest files to transitive manifests.
|
// Add additional manifest files to transitive manifests.
|
||||||
@@ -535,7 +536,7 @@ func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|||||||
func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
a.aapt.isLibrary = true
|
a.aapt.isLibrary = true
|
||||||
a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
|
a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
|
||||||
a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts, nil)
|
a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts, nil, false)
|
||||||
|
|
||||||
a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()
|
a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()
|
||||||
|
|
||||||
|
@@ -43,13 +43,12 @@ var manifestMergerRule = pctx.AndroidStaticRule("manifestMerger",
|
|||||||
// targetSdkVersion for manifest_fixer
|
// targetSdkVersion for manifest_fixer
|
||||||
// When TARGET_BUILD_APPS is not empty, this method returns 10000 for modules targeting an unreleased SDK
|
// When TARGET_BUILD_APPS is not empty, this method returns 10000 for modules targeting an unreleased SDK
|
||||||
// This enables release builds (that run with TARGET_BUILD_APPS=[val...]) to target APIs that have not yet been finalized as part of an SDK
|
// This enables release builds (that run with TARGET_BUILD_APPS=[val...]) to target APIs that have not yet been finalized as part of an SDK
|
||||||
func targetSdkVersionForManifestFixer(ctx android.ModuleContext, sdkContext android.SdkContext) string {
|
func targetSdkVersionForManifestFixer(ctx android.ModuleContext, params ManifestFixerParams) string {
|
||||||
targetSdkVersionSpec := sdkContext.TargetSdkVersion(ctx)
|
targetSdkVersionSpec := params.SdkContext.TargetSdkVersion(ctx)
|
||||||
// Return 10000 for modules targeting "current" if either
|
|
||||||
// 1. The module is built in unbundled mode (TARGET_BUILD_APPS not empty)
|
// Check if we want to return 10000
|
||||||
// 2. The module is run as part of MTS, and should be testable on stable branches
|
|
||||||
// TODO(b/240294501): Determine the rules for handling test apexes
|
// TODO(b/240294501): Determine the rules for handling test apexes
|
||||||
if targetSdkVersionSpec.ApiLevel.IsPreview() && (ctx.Config().UnbundledBuildApps() || includedInMts(ctx.Module())) {
|
if shouldReturnFinalOrFutureInt(ctx, targetSdkVersionSpec, params.EnforceDefaultTargetSdkVersion) {
|
||||||
return strconv.Itoa(android.FutureApiLevel.FinalOrFutureInt())
|
return strconv.Itoa(android.FutureApiLevel.FinalOrFutureInt())
|
||||||
}
|
}
|
||||||
targetSdkVersion, err := targetSdkVersionSpec.EffectiveVersionString(ctx)
|
targetSdkVersion, err := targetSdkVersionSpec.EffectiveVersionString(ctx)
|
||||||
@@ -59,6 +58,17 @@ func targetSdkVersionForManifestFixer(ctx android.ModuleContext, sdkContext andr
|
|||||||
return targetSdkVersion
|
return targetSdkVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return true for modules targeting "current" if either
|
||||||
|
// 1. The module is built in unbundled mode (TARGET_BUILD_APPS not empty)
|
||||||
|
// 2. The module is run as part of MTS, and should be testable on stable branches
|
||||||
|
// Do not return 10000 if we are enforcing default targetSdkVersion and sdk has been finalised
|
||||||
|
func shouldReturnFinalOrFutureInt(ctx android.ModuleContext, targetSdkVersionSpec android.SdkSpec, enforceDefaultTargetSdkVersion bool) bool {
|
||||||
|
if enforceDefaultTargetSdkVersion && ctx.Config().PlatformSdkFinal() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return targetSdkVersionSpec.ApiLevel.IsPreview() && (ctx.Config().UnbundledBuildApps() || includedInMts(ctx.Module()))
|
||||||
|
}
|
||||||
|
|
||||||
// Helper function that casts android.Module to java.androidTestApp
|
// Helper function that casts android.Module to java.androidTestApp
|
||||||
// If this type conversion is possible, it queries whether the test app is included in an MTS suite
|
// If this type conversion is possible, it queries whether the test app is included in an MTS suite
|
||||||
func includedInMts(module android.Module) bool {
|
func includedInMts(module android.Module) bool {
|
||||||
@@ -79,6 +89,7 @@ type ManifestFixerParams struct {
|
|||||||
HasNoCode bool
|
HasNoCode bool
|
||||||
TestOnly bool
|
TestOnly bool
|
||||||
LoggingParent string
|
LoggingParent string
|
||||||
|
EnforceDefaultTargetSdkVersion bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml
|
// Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml
|
||||||
@@ -137,7 +148,7 @@ func ManifestFixer(ctx android.ModuleContext, manifest android.Path,
|
|||||||
var argsMapper = make(map[string]string)
|
var argsMapper = make(map[string]string)
|
||||||
|
|
||||||
if params.SdkContext != nil {
|
if params.SdkContext != nil {
|
||||||
targetSdkVersion := targetSdkVersionForManifestFixer(ctx, params.SdkContext)
|
targetSdkVersion := targetSdkVersionForManifestFixer(ctx, params)
|
||||||
args = append(args, "--targetSdkVersion ", targetSdkVersion)
|
args = append(args, "--targetSdkVersion ", targetSdkVersion)
|
||||||
|
|
||||||
if UseApiFingerprint(ctx) && ctx.ModuleName() != "framework-res" {
|
if UseApiFingerprint(ctx) && ctx.ModuleName() != "framework-res" {
|
||||||
|
31
java/app.go
31
java/app.go
@@ -101,6 +101,15 @@ type appProperties struct {
|
|||||||
PreventInstall bool `blueprint:"mutated"`
|
PreventInstall bool `blueprint:"mutated"`
|
||||||
IsCoverageVariant bool `blueprint:"mutated"`
|
IsCoverageVariant bool `blueprint:"mutated"`
|
||||||
|
|
||||||
|
// It can be set to test the behaviour of default target sdk version.
|
||||||
|
// Only required when updatable: false. It is an error if updatable: true and this is false.
|
||||||
|
Enforce_default_target_sdk_version *bool
|
||||||
|
|
||||||
|
// If set, the targetSdkVersion for the target is set to the latest default API level.
|
||||||
|
// This would be by default false, unless updatable: true or
|
||||||
|
// enforce_default_target_sdk_version: true in which case this defaults to true.
|
||||||
|
EnforceDefaultTargetSdkVersion bool `blueprint:"mutated"`
|
||||||
|
|
||||||
// Whether this app is considered mainline updatable or not. When set to true, this will enforce
|
// Whether this app is considered mainline updatable or not. When set to true, this will enforce
|
||||||
// additional rules to make sure an app can safely be updated. Default is false.
|
// additional rules to make sure an app can safely be updated. Default is false.
|
||||||
// Prefer using other specific properties if build behaviour must be changed; avoid using this
|
// Prefer using other specific properties if build behaviour must be changed; avoid using this
|
||||||
@@ -296,6 +305,18 @@ func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
|
|||||||
} else {
|
} else {
|
||||||
ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
|
ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !BoolDefault(a.appProperties.Enforce_default_target_sdk_version, true) {
|
||||||
|
ctx.PropertyErrorf("enforce_default_target_sdk_version", "Updatable apps must enforce default target sdk version")
|
||||||
|
}
|
||||||
|
// TODO(b/227460469) after all the modules removes the target sdk version, throw an error if the target sdk version is explicitly set.
|
||||||
|
if a.deviceProperties.Target_sdk_version == nil {
|
||||||
|
a.SetEnforceDefaultTargetSdkVersion(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if Bool(a.appProperties.Enforce_default_target_sdk_version) {
|
||||||
|
a.SetEnforceDefaultTargetSdkVersion(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
a.checkPlatformAPI(ctx)
|
a.checkPlatformAPI(ctx)
|
||||||
@@ -427,7 +448,7 @@ func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
|
|||||||
a.aapt.defaultManifestVersion = android.DefaultUpdatableModuleVersion
|
a.aapt.defaultManifestVersion = android.DefaultUpdatableModuleVersion
|
||||||
}
|
}
|
||||||
a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts,
|
a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts,
|
||||||
a.usesLibraryProperties.Exclude_uses_libs, aaptLinkFlags...)
|
a.usesLibraryProperties.Exclude_uses_libs, a.enforceDefaultTargetSdkVersion(), aaptLinkFlags...)
|
||||||
|
|
||||||
// apps manifests are handled by aapt, don't let Module see them
|
// apps manifests are handled by aapt, don't let Module see them
|
||||||
a.properties.Manifest = nil
|
a.properties.Manifest = nil
|
||||||
@@ -865,6 +886,14 @@ func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
|
|||||||
a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo)
|
a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *AndroidApp) enforceDefaultTargetSdkVersion() bool {
|
||||||
|
return a.appProperties.EnforceDefaultTargetSdkVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AndroidApp) SetEnforceDefaultTargetSdkVersion(val bool) {
|
||||||
|
a.appProperties.EnforceDefaultTargetSdkVersion = val
|
||||||
|
}
|
||||||
|
|
||||||
func (a *AndroidApp) Updatable() bool {
|
func (a *AndroidApp) Updatable() bool {
|
||||||
return Bool(a.appProperties.Updatable)
|
return Bool(a.appProperties.Updatable)
|
||||||
}
|
}
|
||||||
|
173
java/app_test.go
173
java/app_test.go
@@ -3057,6 +3057,179 @@ func TestTargetSdkVersionManifestFixer(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDefaultAppTargetSdkVersionForUpdatableModules(t *testing.T) {
|
||||||
|
platform_sdk_codename := "Tiramisu"
|
||||||
|
platform_sdk_version := 33
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
platform_sdk_final bool
|
||||||
|
targetSdkVersionInBp *string
|
||||||
|
targetSdkVersionExpected *string
|
||||||
|
updatable bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Non-Updatable Module: Android.bp has older targetSdkVersion",
|
||||||
|
targetSdkVersionInBp: proptools.StringPtr("29"),
|
||||||
|
targetSdkVersionExpected: proptools.StringPtr("29"),
|
||||||
|
updatable: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Updatable Module: Android.bp has older targetSdkVersion",
|
||||||
|
targetSdkVersionInBp: proptools.StringPtr("30"),
|
||||||
|
targetSdkVersionExpected: proptools.StringPtr("30"),
|
||||||
|
updatable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Updatable Module: Android.bp has no targetSdkVersion",
|
||||||
|
targetSdkVersionExpected: proptools.StringPtr("10000"),
|
||||||
|
updatable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "[SDK finalised] Non-Updatable Module: Android.bp has older targetSdkVersion",
|
||||||
|
platform_sdk_final: true,
|
||||||
|
targetSdkVersionInBp: proptools.StringPtr("30"),
|
||||||
|
targetSdkVersionExpected: proptools.StringPtr("30"),
|
||||||
|
updatable: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "[SDK finalised] Updatable Module: Android.bp has older targetSdkVersion",
|
||||||
|
platform_sdk_final: true,
|
||||||
|
targetSdkVersionInBp: proptools.StringPtr("30"),
|
||||||
|
targetSdkVersionExpected: proptools.StringPtr("30"),
|
||||||
|
updatable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "[SDK finalised] Updatable Module: Android.bp has targetSdkVersion as platform sdk codename",
|
||||||
|
platform_sdk_final: true,
|
||||||
|
targetSdkVersionInBp: proptools.StringPtr(platform_sdk_codename),
|
||||||
|
targetSdkVersionExpected: proptools.StringPtr("33"),
|
||||||
|
updatable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "[SDK finalised] Updatable Module: Android.bp has no targetSdkVersion",
|
||||||
|
platform_sdk_final: true,
|
||||||
|
targetSdkVersionExpected: proptools.StringPtr("33"),
|
||||||
|
updatable: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
bp := fmt.Sprintf(`
|
||||||
|
android_app {
|
||||||
|
name: "foo",
|
||||||
|
sdk_version: "current",
|
||||||
|
min_sdk_version: "29",
|
||||||
|
target_sdk_version: "%v",
|
||||||
|
updatable: %t,
|
||||||
|
enforce_default_target_sdk_version: %t
|
||||||
|
}
|
||||||
|
`, proptools.String(testCase.targetSdkVersionInBp), testCase.updatable, testCase.updatable) // enforce default target sdk version if app is updatable
|
||||||
|
|
||||||
|
fixture := android.GroupFixturePreparers(
|
||||||
|
PrepareForTestWithJavaDefaultModules,
|
||||||
|
android.PrepareForTestWithAllowMissingDependencies,
|
||||||
|
android.PrepareForTestWithAndroidMk,
|
||||||
|
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
|
||||||
|
// explicitly set following platform variables to make the test deterministic
|
||||||
|
variables.Platform_sdk_final = &testCase.platform_sdk_final
|
||||||
|
variables.Platform_sdk_version = &platform_sdk_version
|
||||||
|
variables.Platform_sdk_codename = &platform_sdk_codename
|
||||||
|
variables.Platform_version_active_codenames = []string{platform_sdk_codename}
|
||||||
|
variables.Unbundled_build_apps = []string{"sampleModule"}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
result := fixture.RunTestWithBp(t, bp)
|
||||||
|
foo := result.ModuleForTests("foo", "android_common")
|
||||||
|
|
||||||
|
manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
|
||||||
|
android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+*testCase.targetSdkVersionExpected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEnforceDefaultAppTargetSdkVersionFlag(t *testing.T) {
|
||||||
|
platform_sdk_codename := "Tiramisu"
|
||||||
|
platform_sdk_version := 33
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
enforceDefaultTargetSdkVersion bool
|
||||||
|
expectedError string
|
||||||
|
platform_sdk_final bool
|
||||||
|
targetSdkVersionInBp string
|
||||||
|
targetSdkVersionExpected string
|
||||||
|
updatable bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Not enforcing Target SDK Version: Android.bp has older targetSdkVersion",
|
||||||
|
enforceDefaultTargetSdkVersion: false,
|
||||||
|
targetSdkVersionInBp: "29",
|
||||||
|
targetSdkVersionExpected: "29",
|
||||||
|
updatable: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion",
|
||||||
|
enforceDefaultTargetSdkVersion: true,
|
||||||
|
platform_sdk_final: true,
|
||||||
|
targetSdkVersionInBp: "current",
|
||||||
|
targetSdkVersionExpected: "33",
|
||||||
|
updatable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion",
|
||||||
|
enforceDefaultTargetSdkVersion: true,
|
||||||
|
platform_sdk_final: false,
|
||||||
|
targetSdkVersionInBp: "current",
|
||||||
|
targetSdkVersionExpected: "10000",
|
||||||
|
updatable: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Not enforcing Target SDK Version for Updatable app",
|
||||||
|
enforceDefaultTargetSdkVersion: false,
|
||||||
|
expectedError: "Updatable apps must enforce default target sdk version",
|
||||||
|
targetSdkVersionInBp: "29",
|
||||||
|
targetSdkVersionExpected: "29",
|
||||||
|
updatable: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
errExpected := testCase.expectedError != ""
|
||||||
|
bp := fmt.Sprintf(`
|
||||||
|
android_app {
|
||||||
|
name: "foo",
|
||||||
|
enforce_default_target_sdk_version: %t,
|
||||||
|
sdk_version: "current",
|
||||||
|
min_sdk_version: "29",
|
||||||
|
target_sdk_version: "%v",
|
||||||
|
updatable: %t
|
||||||
|
}
|
||||||
|
`, testCase.enforceDefaultTargetSdkVersion, testCase.targetSdkVersionInBp, testCase.updatable)
|
||||||
|
|
||||||
|
fixture := android.GroupFixturePreparers(
|
||||||
|
PrepareForTestWithJavaDefaultModules,
|
||||||
|
android.PrepareForTestWithAllowMissingDependencies,
|
||||||
|
android.PrepareForTestWithAndroidMk,
|
||||||
|
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
|
||||||
|
// explicitly set following platform variables to make the test deterministic
|
||||||
|
variables.Platform_sdk_final = &testCase.platform_sdk_final
|
||||||
|
variables.Platform_sdk_version = &platform_sdk_version
|
||||||
|
variables.Platform_sdk_codename = &platform_sdk_codename
|
||||||
|
variables.Unbundled_build_apps = []string{"sampleModule"}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
errorHandler := android.FixtureExpectsNoErrors
|
||||||
|
if errExpected {
|
||||||
|
errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError)
|
||||||
|
}
|
||||||
|
result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp)
|
||||||
|
|
||||||
|
if !errExpected {
|
||||||
|
foo := result.ModuleForTests("foo", "android_common")
|
||||||
|
manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
|
||||||
|
android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestAppMissingCertificateAllowMissingDependencies(t *testing.T) {
|
func TestAppMissingCertificateAllowMissingDependencies(t *testing.T) {
|
||||||
result := android.GroupFixturePreparers(
|
result := android.GroupFixturePreparers(
|
||||||
PrepareForTestWithJavaDefaultModules,
|
PrepareForTestWithJavaDefaultModules,
|
||||||
|
@@ -142,7 +142,7 @@ func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleC
|
|||||||
aaptLinkFlags = append(aaptLinkFlags,
|
aaptLinkFlags = append(aaptLinkFlags,
|
||||||
"--rename-overlay-target-package "+*r.overridableProperties.Target_package_name)
|
"--rename-overlay-target-package "+*r.overridableProperties.Target_package_name)
|
||||||
}
|
}
|
||||||
r.aapt.buildActions(ctx, r, nil, nil, aaptLinkFlags...)
|
r.aapt.buildActions(ctx, r, nil, nil, false, aaptLinkFlags...)
|
||||||
|
|
||||||
// Sign the built package
|
// Sign the built package
|
||||||
_, _, certificates := collectAppDeps(ctx, r, false, false)
|
_, _, certificates := collectAppDeps(ctx, r, false, false)
|
||||||
|
Reference in New Issue
Block a user