Manual re-land "Ban the use of Layer::SetFillsBoundsOpaquely()
for LAYER_SOLID_COLOR"
This CL re-lands crrev.com/c/6068397. The CL was reverted because, the original CL did not remove the usage of the banned method in `SurfaceTreeHost` class. Bug: b:382345847 Change-Id: I82e6170983d77be3a97e201c4364e5f0c42a9d91 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6175787 Reviewed-by: Mitsuru Oshima <oshima@chromium.org> Reviewed-by: Jonathan Ross <jonross@chromium.org> Commit-Queue: Zoraiz Naeem <zoraiznaeem@chromium.org> Reviewed-by: Allen Bauer <kylixrd@chromium.org> Cr-Commit-Position: refs/heads/main@{#1408170}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
7c2031fc2c
commit
dede65eb23
ash
accessibility
magnifier
app_list
views
capture_mode
rotator
style
system
privacy
tray
unified
video_conference
bubble
user_education
welcome_tour
utility
wm
chromeos/ui/frame
components/exo
content/browser/renderer_host
ui
aura
compositor
touch_selection
views
@ -196,7 +196,6 @@ void MagnifierGlass::CreateMagnifierWindow(aura::Window* root_window,
|
||||
zoom_layer_ = std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR);
|
||||
zoom_layer_->SetBounds(window_bounds);
|
||||
zoom_layer_->SetBackgroundZoom(params_.scale, kZoomInset);
|
||||
zoom_layer_->SetFillsBoundsOpaquely(false);
|
||||
root_layer->Add(zoom_layer_.get());
|
||||
|
||||
// Create a rounded rect clip, so that only we see a circle of the zoomed
|
||||
|
@ -105,7 +105,6 @@ class SeparatorWithLayer : public views::View {
|
||||
SeparatorWithLayer() {
|
||||
SetPaintToLayer(ui::LAYER_SOLID_COLOR);
|
||||
// Color is set in OnThemeChanged().
|
||||
layer()->SetFillsBoundsOpaquely(false);
|
||||
}
|
||||
SeparatorWithLayer(const SeparatorWithLayer&) = delete;
|
||||
SeparatorWithLayer& operator=(const SeparatorWithLayer&) = delete;
|
||||
|
@ -692,7 +692,6 @@ AppListFolderView::AppListFolderView(AppListFolderController* folder_controller,
|
||||
ColorProvider::kBackgroundBlurSigma);
|
||||
animating_background_->layer()->SetBackdropFilterQuality(
|
||||
ColorProvider::kBackgroundBlurQuality);
|
||||
animating_background_->layer()->SetFillsBoundsOpaquely(false);
|
||||
}
|
||||
|
||||
animating_background_->SetVisible(false);
|
||||
|
@ -663,7 +663,6 @@ AppListItemView::AppListItemView(const AppListConfig* app_list_config,
|
||||
|
||||
icon_background_ = AddChildView(std::make_unique<views::View>());
|
||||
icon_background_->SetPaintToLayer(ui::LAYER_SOLID_COLOR);
|
||||
icon_background_->layer()->SetFillsBoundsOpaquely(false);
|
||||
icon_background_->SetCanProcessEventsWithinSubtree(false);
|
||||
icon_background_->SetVisible(is_folder_);
|
||||
|
||||
|
@ -413,7 +413,6 @@ void AssistantPageView::OnThemeChanged() {
|
||||
void AssistantPageView::InitLayout() {
|
||||
// Use a solid color layer. The color is set in OnThemeChanged().
|
||||
SetPaintToLayer(ui::LAYER_SOLID_COLOR);
|
||||
layer()->SetFillsBoundsOpaquely(!chromeos::features::IsSystemBlurEnabled());
|
||||
|
||||
view_shadow_ = std::make_unique<views::ViewShadow>(this, kShadowElevation);
|
||||
view_shadow_->SetRoundedCornerRadius(
|
||||
|
@ -47,7 +47,6 @@ TopIconAnimationView::TopIconAnimationView(AppsGridView* grid,
|
||||
icon_background_ = AddChildView(std::make_unique<views::View>());
|
||||
if (item_in_folder_icon_) {
|
||||
icon_background_->SetPaintToLayer(ui::LAYER_SOLID_COLOR);
|
||||
icon_background_->layer()->SetFillsBoundsOpaquely(false);
|
||||
} else {
|
||||
const int background_diameter =
|
||||
app_list_config->GetShortcutBackgroundContainerDimension();
|
||||
|
@ -68,10 +68,8 @@ UserNudgeController::UserNudgeController(CaptureModeSession* session,
|
||||
DarkLightModeControllerImpl::Get()->IsDarkModeEnabled() ? SK_ColorWHITE
|
||||
: SK_ColorBLACK;
|
||||
base_ring_.SetColor(ring_color);
|
||||
base_ring_.SetFillsBoundsOpaquely(false);
|
||||
base_ring_.SetOpacity(0);
|
||||
ripple_ring_.SetColor(ring_color);
|
||||
ripple_ring_.SetFillsBoundsOpaquely(false);
|
||||
ripple_ring_.SetOpacity(0);
|
||||
|
||||
Reposition();
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "ui/compositor/layer_animator.h"
|
||||
#include "ui/compositor/layer_owner.h"
|
||||
#include "ui/compositor/layer_tree_owner.h"
|
||||
#include "ui/compositor/layer_type.h"
|
||||
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
|
||||
#include "ui/display/display.h"
|
||||
#include "ui/display/manager/display_manager.h"
|
||||
@ -367,12 +368,10 @@ std::unique_ptr<ui::LayerTreeOwner> ScreenRotationAnimator::CopyLayerTree(
|
||||
GetScreenRotationContainer(root_window_)->layer()->size();
|
||||
std::unique_ptr<ui::Layer> copy_layer =
|
||||
CreateLayerFromCopyOutputResult(std::move(result), layer_size);
|
||||
CHECK_EQ(copy_layer->type(), ui::LAYER_SOLID_COLOR);
|
||||
DCHECK_EQ(copy_layer->size(),
|
||||
GetScreenRotationContainer(root_window_)->layer()->size());
|
||||
|
||||
// TODO(crbug.com/40113966): This is a workaround and should be removed once
|
||||
// the issue is fixed.
|
||||
copy_layer->SetFillsBoundsOpaquely(false);
|
||||
return std::make_unique<ui::LayerTreeOwner>(std::move(copy_layer));
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,6 @@ CounterExpandButton::CounterExpandButton() {
|
||||
views::FocusRing::Get(this)->SetOutsetFocusRingDisabled(true);
|
||||
|
||||
SetPaintToLayer(ui::LAYER_SOLID_COLOR);
|
||||
layer()->SetFillsBoundsOpaquely(false);
|
||||
layer()->SetRoundedCornerRadius(gfx::RoundedCornersF{kTrayItemCornerRadius});
|
||||
layer()->SetIsFastRoundedCorner(true);
|
||||
}
|
||||
|
@ -165,7 +165,6 @@ PrivacyIndicatorsTrayItemView::PrivacyIndicatorsTrayItemView(Shelf* shelf)
|
||||
// Set up a solid color layer to paint the background color, then add a layer
|
||||
// to each child so that they are visible and can perform layer animation.
|
||||
SetPaintToLayer(ui::LAYER_SOLID_COLOR);
|
||||
layer()->SetFillsBoundsOpaquely(false);
|
||||
layer()->SetRoundedCornerRadius(
|
||||
gfx::RoundedCornersF{kPrivacyIndicatorsViewExpandedShorterSideSize / 2});
|
||||
layer()->SetIsFastRoundedCorner(true);
|
||||
@ -173,7 +172,6 @@ PrivacyIndicatorsTrayItemView::PrivacyIndicatorsTrayItemView(Shelf* shelf)
|
||||
auto add_icon_to_container = [&container_view]() {
|
||||
auto icon = std::make_unique<views::ImageView>();
|
||||
icon->SetPaintToLayer();
|
||||
icon->layer()->SetFillsBoundsOpaquely(false);
|
||||
icon->SetVisible(false);
|
||||
return container_view->AddChildView(std::move(icon));
|
||||
};
|
||||
|
@ -75,7 +75,7 @@ TEST_P(PrivacyIndicatorsTrayItemViewPixelTest, Basics) {
|
||||
SimulateAnimateToFullyExpandedState(privacy_indicators_view);
|
||||
EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
|
||||
"full_view" + GetScreenshotNameSuffix(),
|
||||
/*revision_number=*/1, notification_center_tray));
|
||||
/*revision_number=*/2, notification_center_tray));
|
||||
|
||||
SimulateAnimationEnded(privacy_indicators_view);
|
||||
EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
|
||||
|
@ -298,7 +298,6 @@ TrayBackgroundView::TrayBackgroundView(
|
||||
// Use layer color to provide background color. Note that children views
|
||||
// need to have their own layers to be visible.
|
||||
SetPaintToLayer(ui::LAYER_SOLID_COLOR);
|
||||
layer()->SetFillsBoundsOpaquely(!chromeos::features::IsSystemBlurEnabled());
|
||||
|
||||
// Start the tray items not visible, because visibility changes are animated.
|
||||
views::View::SetVisible(false);
|
||||
|
@ -398,7 +398,6 @@ PowerButton::PowerButton(UnifiedSystemTrayController* tray_controller)
|
||||
background_view_->SetPaintToLayer(ui::LAYER_SOLID_COLOR);
|
||||
auto* background_layer = background_view_->layer();
|
||||
background_layer->SetRoundedCornerRadius(kAllRoundedCorners);
|
||||
background_layer->SetFillsBoundsOpaquely(false);
|
||||
background_layer->SetIsFastRoundedCorner(true);
|
||||
|
||||
set_context_menu_controller(context_menu_.get());
|
||||
|
@ -107,7 +107,6 @@ MicTestButton::MicTestButton() {
|
||||
background_view_->SetPaintToLayer(ui::LAYER_SOLID_COLOR);
|
||||
auto* background_layer = background_view_->layer();
|
||||
background_layer->SetRoundedCornerRadius(gfx::RoundedCornersF(16));
|
||||
background_layer->SetFillsBoundsOpaquely(false);
|
||||
|
||||
button_container_ =
|
||||
AddChildView(std::make_unique<MicTestButtonContainer>(base::BindRepeating(
|
||||
|
@ -208,7 +208,6 @@ class WelcomeTourScrim::Scrim : public aura::WindowObserver,
|
||||
// Invoked once to initialize `this` scrim.
|
||||
void Init() {
|
||||
// Configure static scrim layer properties.
|
||||
layer_owner_.layer()->SetFillsBoundsOpaquely(false);
|
||||
layer_owner_.layer()->SetMaskLayer(mask_layer_owner_.layer());
|
||||
layer_owner_.layer()->SetName(WelcomeTourScrim::kLayerName);
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "ui/base/class_property.h"
|
||||
#include "ui/compositor/layer_animation_sequence.h"
|
||||
#include "ui/compositor/layer_animator.h"
|
||||
#include "ui/compositor/layer_type.h"
|
||||
|
||||
DEFINE_UI_CLASS_PROPERTY_TYPE(ash::LayerCopyAnimator*)
|
||||
|
||||
@ -114,7 +115,7 @@ void LayerCopyAnimator::OnWindowBoundsChanged(aura::Window* window,
|
||||
}
|
||||
|
||||
void LayerCopyAnimator::RunAnimation() {
|
||||
copied_layer_->SetFillsBoundsOpaquely(false);
|
||||
CHECK_EQ(copied_layer_->type(), ui::LAYER_SOLID_COLOR);
|
||||
|
||||
auto* parent_layer = window_->layer()->parent();
|
||||
parent_layer->Add(copied_layer_.get());
|
||||
|
@ -136,9 +136,7 @@ void WindowMiniView::SetBackdropVisibility(bool visible) {
|
||||
backdrop_view_->SetPaintToLayer(ui::LAYER_SOLID_COLOR);
|
||||
|
||||
ui::Layer* layer = backdrop_view_->layer();
|
||||
|
||||
layer->SetName("BackdropView");
|
||||
layer->SetFillsBoundsOpaquely(false);
|
||||
|
||||
const int corner_radius = window_util::GetMiniWindowRoundedCornerRadius();
|
||||
layer->SetRoundedCornerRadius(
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "ui/compositor/layer.h"
|
||||
#include "ui/compositor/layer_animation_observer.h"
|
||||
#include "ui/compositor/layer_tree_owner.h"
|
||||
#include "ui/compositor/layer_type.h"
|
||||
#include "ui/compositor/scoped_layer_animation_settings.h"
|
||||
#include "ui/gfx/canvas.h"
|
||||
#include "ui/gfx/color_utils.h"
|
||||
@ -115,7 +116,9 @@ void FrameHeader::FrameAnimatorView::StartAnimation(base::TimeDelta duration) {
|
||||
old_layer->SetTransform(gfx::Transform());
|
||||
// Layer in maximized / fullscreen / snapped state is set to
|
||||
// opaque, which can prevent resterizing the new layer immediately.
|
||||
old_layer->SetFillsBoundsOpaquely(false);
|
||||
if (old_layer->type() != ui::LAYER_SOLID_COLOR) {
|
||||
old_layer->SetFillsBoundsOpaquely(false);
|
||||
}
|
||||
|
||||
layer_owner_ = std::move(old_layer_owner);
|
||||
|
||||
|
@ -380,9 +380,6 @@ void SurfaceTreeHost::SubmitCompositorFrame() {
|
||||
: std::make_optional(GetScaleFactor()),
|
||||
&frame);
|
||||
|
||||
// Update after resource is updated.
|
||||
UpdateHostLayerOpacity();
|
||||
|
||||
std::vector<GLbyte*> sync_tokens;
|
||||
// We track previously verified tokens and set them to be verified to avoid
|
||||
// the considerable overhead of flush verification in
|
||||
@ -493,17 +490,8 @@ void SurfaceTreeHost::UpdateSurfaceLayerSizeAndRootSurfaceOrigin() {
|
||||
root_surface_->window()->SetBounds(updated_bounds);
|
||||
}
|
||||
|
||||
UpdateHostWindowOpaqueRegion();
|
||||
}
|
||||
|
||||
void SurfaceTreeHost::UpdateHostLayerOpacity() {
|
||||
ui::Layer* commit_target_layer = GetCommitTargetLayer();
|
||||
|
||||
if (commit_target_layer == host_window_->layer()) {
|
||||
UpdateHostWindowOpaqueRegion();
|
||||
} else if (commit_target_layer) {
|
||||
commit_target_layer->SetFillsBoundsOpaquely(
|
||||
ContentsFillsHostWindowOpaquely());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -210,10 +210,6 @@ class SurfaceTreeHost : public SurfaceDelegate,
|
||||
// It also updates `root_surface_origin_` accordingly to the origin.
|
||||
void UpdateSurfaceLayerSizeAndRootSurfaceOrigin();
|
||||
|
||||
// Updates the host layer's opacity. This has to be called after root
|
||||
// surface's resource is updated.
|
||||
void UpdateHostLayerOpacity();
|
||||
|
||||
void UpdateHostWindowOpaqueRegion();
|
||||
|
||||
bool client_submits_surfaces_in_pixel_coordinates() const {
|
||||
|
@ -754,8 +754,6 @@ void RenderWidgetHostViewAura::UpdateBackgroundColor() {
|
||||
CHECK(GetBackgroundColor());
|
||||
|
||||
SkColor color = *GetBackgroundColor();
|
||||
bool opaque = SkColorGetA(color) == SK_AlphaOPAQUE;
|
||||
window_->layer()->SetFillsBoundsOpaquely(opaque);
|
||||
window_->layer()->SetColor(color);
|
||||
}
|
||||
|
||||
|
@ -62,6 +62,7 @@
|
||||
#include "ui/compositor/compositor.h"
|
||||
#include "ui/compositor/layer.h"
|
||||
#include "ui/compositor/layer_animator.h"
|
||||
#include "ui/compositor/layer_type.h"
|
||||
#include "ui/display/display.h"
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/events/event_target_iterator.h"
|
||||
@ -333,7 +334,9 @@ void Window::SetTransparent(bool transparent) {
|
||||
return;
|
||||
transparent_ = transparent;
|
||||
|
||||
layer()->SetFillsBoundsOpaquely(!transparent_);
|
||||
if (layer()->type() != ui::LAYER_SOLID_COLOR) {
|
||||
layer()->SetFillsBoundsOpaquely(!transparent_);
|
||||
}
|
||||
TriggerChangedCallback(&transparent_);
|
||||
}
|
||||
|
||||
|
@ -307,12 +307,14 @@ std::unique_ptr<Layer> Layer::Clone() const {
|
||||
clone->SetVisible(GetTargetVisibility());
|
||||
clone->SetClipRect(GetTargetClipRect());
|
||||
clone->SetAcceptEvents(accept_events());
|
||||
clone->SetFillsBoundsOpaquely(fills_bounds_opaquely_);
|
||||
clone->SetFillsBoundsCompletely(fills_bounds_completely_);
|
||||
clone->SetRoundedCornerRadius(GetTargetRoundedCornerRadius());
|
||||
clone->SetGradientMask(gradient_mask());
|
||||
clone->SetIsFastRoundedCorner(is_fast_rounded_corner());
|
||||
clone->SetName(name_);
|
||||
if (type() != LAYER_SOLID_COLOR) {
|
||||
clone->SetFillsBoundsOpaquely(fills_bounds_opaquely_);
|
||||
}
|
||||
|
||||
// the |damaged_region_| will be sent to cc later in SendDamagedRects().
|
||||
clone->damaged_region_ = damaged_region_;
|
||||
@ -896,6 +898,7 @@ void Layer::ConvertPointToLayer(const Layer* source,
|
||||
}
|
||||
|
||||
void Layer::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) {
|
||||
CHECK_NE(type_, LayerType::LAYER_SOLID_COLOR);
|
||||
SetFillsBoundsOpaquelyWithReason(fills_bounds_opaquely,
|
||||
PropertyChangeReason::NOT_FROM_ANIMATION);
|
||||
}
|
||||
|
@ -414,6 +414,8 @@ class COMPOSITOR_EXPORT Layer : public LayerAnimationDelegate,
|
||||
// Note: Setting a layer non-opaque has significant performance impact,
|
||||
// especially on low-end Chrome OS devices. Please ensure you are not
|
||||
// adding unnecessary overdraw. When in doubt, talk to the graphics team.
|
||||
// NOTE: Opacity of SOLID_COLOR layer is determined by the color's alpha
|
||||
// channel. Calling this on SOLID_COLOR results in check failure.
|
||||
void SetFillsBoundsOpaquely(bool fills_bounds_opaquely);
|
||||
bool fills_bounds_opaquely() const { return fills_bounds_opaquely_; }
|
||||
|
||||
|
@ -865,7 +865,7 @@ TEST_F(LayerWithDelegateTest, Cloning) {
|
||||
|
||||
constexpr SkColor kTransparent = SK_ColorTRANSPARENT;
|
||||
layer->SetColor(kTransparent);
|
||||
layer->SetFillsBoundsOpaquely(false);
|
||||
|
||||
// Color and opaqueness targets should be preserved during cloning, even after
|
||||
// switching away from solid color content.
|
||||
ASSERT_TRUE(layer->SwitchCCLayerForTest());
|
||||
@ -882,23 +882,6 @@ TEST_F(LayerWithDelegateTest, Cloning) {
|
||||
EXPECT_FALSE(clone->LayerHasCustomColorMatrix());
|
||||
EXPECT_FALSE(clone->fills_bounds_opaquely());
|
||||
|
||||
// A solid color layer with transparent color can be marked as opaque. The
|
||||
// clone should retain this state.
|
||||
layer = CreateLayer(LAYER_SOLID_COLOR);
|
||||
layer->SetColor(kTransparent);
|
||||
layer->SetFillsBoundsOpaquely(true);
|
||||
|
||||
clone = layer->Clone();
|
||||
EXPECT_TRUE(clone->GetTargetTransform().IsIdentity());
|
||||
EXPECT_EQ(kTransparent, clone->background_color());
|
||||
EXPECT_EQ(kTransparent, clone->GetTargetColor());
|
||||
EXPECT_FALSE(clone->layer_inverted());
|
||||
// Sepia and hue rotation should be off by default.
|
||||
EXPECT_FLOAT_EQ(0, layer->layer_sepia());
|
||||
EXPECT_FLOAT_EQ(0, clone->layer_hue_rotation());
|
||||
EXPECT_FALSE(clone->LayerHasCustomColorMatrix());
|
||||
EXPECT_TRUE(clone->fills_bounds_opaquely());
|
||||
|
||||
layer = CreateLayer(LAYER_SOLID_COLOR);
|
||||
layer->SetVisible(true);
|
||||
layer->SetOpacity(1.0f);
|
||||
@ -1143,7 +1126,6 @@ TEST_F(LayerWithNullDelegateTest, LayerContentOpaqueness) {
|
||||
|
||||
TEST_F(LayerWithNullDelegateTest, SwitchLayerPreservesCCLayerState) {
|
||||
std::unique_ptr<Layer> l1 = CreateLayer(LAYER_SOLID_COLOR);
|
||||
l1->SetFillsBoundsOpaquely(true);
|
||||
l1->SetVisible(false);
|
||||
l1->SetBounds(gfx::Rect(4, 5));
|
||||
|
||||
@ -2690,7 +2672,6 @@ TEST_F(LayerWithRealCompositorTest, SwitchCCLayerSolidColorNotAnimating) {
|
||||
SkColor transparent = SK_ColorTRANSPARENT;
|
||||
std::unique_ptr<Layer> root = CreateLayer(LAYER_SOLID_COLOR);
|
||||
GetCompositor()->SetRootLayer(root.get());
|
||||
root->SetFillsBoundsOpaquely(false);
|
||||
root->SetColor(transparent);
|
||||
|
||||
EXPECT_FALSE(root->fills_bounds_opaquely());
|
||||
@ -2727,7 +2708,6 @@ TEST_F(LayerWithRealCompositorTest, SwitchCCLayerSolidColorWhileAnimating) {
|
||||
{
|
||||
ui::ScopedLayerAnimationSettings animation(root->GetAnimator());
|
||||
animation.SetTransitionDuration(base::Milliseconds(1000));
|
||||
root->SetFillsBoundsOpaquely(false);
|
||||
root->SetColor(transparent);
|
||||
}
|
||||
|
||||
|
@ -300,7 +300,6 @@ void TouchSelectionMagnifierAura::CreateMagnifierLayer() {
|
||||
// Create the zoom layer, which will show the zoomed contents.
|
||||
zoom_layer_ = std::make_unique<Layer>(LAYER_SOLID_COLOR);
|
||||
zoom_layer_->SetBackgroundZoom(kMagnifierScale, 0);
|
||||
zoom_layer_->SetFillsBoundsOpaquely(false);
|
||||
// BackdropFilterBounds applies after the backdrop filter (the zoom effect)
|
||||
// but before anything else, meaning its clipping effect is transformed by
|
||||
// the layer_offset() filter operation. SetRoundedCornerRadius() applies too
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include "ui/compositor/clip_recorder.h"
|
||||
#include "ui/compositor/compositor.h"
|
||||
#include "ui/compositor/layer.h"
|
||||
#include "ui/compositor/layer_type.h"
|
||||
#include "ui/compositor/paint_context.h"
|
||||
#include "ui/compositor/paint_recorder.h"
|
||||
#include "ui/compositor/transform_recorder.h"
|
||||
@ -2561,7 +2562,9 @@ void View::AddLayerToRegionImpl(
|
||||
|
||||
CreateOrDestroyLayer();
|
||||
|
||||
layer()->SetFillsBoundsOpaquely(false);
|
||||
if (layer()->type() != ui::LAYER_SOLID_COLOR) {
|
||||
layer()->SetFillsBoundsOpaquely(false);
|
||||
}
|
||||
}
|
||||
|
||||
void View::SetLayerParent(ui::Layer* parent_layer) {
|
||||
|
Reference in New Issue
Block a user