e4a9469156
The scrim visibility drives whether the launcher window is opaque or not. We should track it and apply the flag instead of trying to catch it through other Launcher life cycles. Fixes: 195365607 Test: tap on home button while launching app from overview Change-Id: I2a00b86b602b5dd12c901433b92adcf0170be15e
182 lines
5.7 KiB
Java
182 lines
5.7 KiB
Java
/*
|
|
* Copyright (C) 2018 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
package com.android.launcher3.views;
|
|
|
|
import static com.android.launcher3.util.SystemUiController.UI_STATE_SCRIM_VIEW;
|
|
|
|
import android.content.Context;
|
|
import android.graphics.Canvas;
|
|
import android.graphics.Color;
|
|
import android.graphics.Rect;
|
|
import android.graphics.drawable.ColorDrawable;
|
|
import android.util.AttributeSet;
|
|
import android.view.View;
|
|
|
|
import androidx.annotation.NonNull;
|
|
import androidx.core.graphics.ColorUtils;
|
|
|
|
import com.android.launcher3.BaseActivity;
|
|
import com.android.launcher3.Insettable;
|
|
import com.android.launcher3.util.SystemUiController;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
/**
|
|
* Simple scrim which draws a flat color
|
|
*/
|
|
public class ScrimView extends View implements Insettable {
|
|
private static final float STATUS_BAR_COLOR_FORCE_UPDATE_THRESHOLD = 0.9f;
|
|
|
|
private final ArrayList<Runnable> mOpaquenessListeners = new ArrayList<>(1);
|
|
private SystemUiController mSystemUiController;
|
|
private ScrimDrawingController mDrawingController;
|
|
private int mBackgroundColor;
|
|
private boolean mIsVisible = true;
|
|
private boolean mLastDispatchedOpaqueness;
|
|
|
|
public ScrimView(Context context, AttributeSet attrs) {
|
|
super(context, attrs);
|
|
setFocusable(false);
|
|
}
|
|
|
|
@Override
|
|
public void setInsets(Rect insets) {
|
|
}
|
|
|
|
@Override
|
|
public boolean hasOverlappingRendering() {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
protected boolean onSetAlpha(int alpha) {
|
|
updateSysUiColors();
|
|
dispatchVisibilityListenersIfNeeded();
|
|
return super.onSetAlpha(alpha);
|
|
}
|
|
|
|
@Override
|
|
public void setBackgroundColor(int color) {
|
|
mBackgroundColor = color;
|
|
updateSysUiColors();
|
|
dispatchVisibilityListenersIfNeeded();
|
|
super.setBackgroundColor(color);
|
|
}
|
|
|
|
@Override
|
|
public void onVisibilityAggregated(boolean isVisible) {
|
|
super.onVisibilityAggregated(isVisible);
|
|
mIsVisible = isVisible;
|
|
dispatchVisibilityListenersIfNeeded();
|
|
}
|
|
|
|
public boolean isFullyOpaque() {
|
|
return mIsVisible && getAlpha() == 1 && Color.alpha(mBackgroundColor) == 255;
|
|
}
|
|
|
|
@Override
|
|
protected void onDraw(Canvas canvas) {
|
|
super.onDraw(canvas);
|
|
if (mDrawingController != null) {
|
|
mDrawingController.drawOnScrim(canvas);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void onVisibilityChanged(View changedView, int visibility) {
|
|
super.onVisibilityChanged(changedView, visibility);
|
|
updateSysUiColors();
|
|
}
|
|
|
|
private void updateSysUiColors() {
|
|
// Use a light system UI (dark icons) if all apps is behind at least half of the
|
|
// status bar.
|
|
final float threshold = STATUS_BAR_COLOR_FORCE_UPDATE_THRESHOLD;
|
|
boolean forceChange = getVisibility() == VISIBLE
|
|
&& getAlpha() > threshold
|
|
&& (Color.alpha(mBackgroundColor) / 255f) > threshold;
|
|
if (forceChange) {
|
|
getSystemUiController().updateUiState(UI_STATE_SCRIM_VIEW, !isScrimDark());
|
|
} else {
|
|
getSystemUiController().updateUiState(UI_STATE_SCRIM_VIEW, 0);
|
|
}
|
|
}
|
|
|
|
private void dispatchVisibilityListenersIfNeeded() {
|
|
boolean fullyOpaque = isFullyOpaque();
|
|
if (mLastDispatchedOpaqueness == fullyOpaque) {
|
|
return;
|
|
}
|
|
mLastDispatchedOpaqueness = fullyOpaque;
|
|
for (int i = 0; i < mOpaquenessListeners.size(); i++) {
|
|
mOpaquenessListeners.get(i).run();
|
|
}
|
|
}
|
|
|
|
private SystemUiController getSystemUiController() {
|
|
if (mSystemUiController == null) {
|
|
mSystemUiController = BaseActivity.fromContext(getContext()).getSystemUiController();
|
|
}
|
|
return mSystemUiController;
|
|
}
|
|
|
|
private boolean isScrimDark() {
|
|
if (!(getBackground() instanceof ColorDrawable)) {
|
|
throw new IllegalStateException(
|
|
"ScrimView must have a ColorDrawable background, this one has: "
|
|
+ getBackground());
|
|
}
|
|
return ColorUtils.calculateLuminance(
|
|
((ColorDrawable) getBackground()).getColor()) < 0.5f;
|
|
}
|
|
|
|
/**
|
|
* Sets drawing controller. Invalidates ScrimView if drawerController has changed.
|
|
*/
|
|
public void setDrawingController(ScrimDrawingController drawingController) {
|
|
if (mDrawingController != drawingController) {
|
|
mDrawingController = drawingController;
|
|
invalidate();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Registers a listener to be notified of whether the scrim is occluding other UI elements.
|
|
* @see #isFullyOpaque()
|
|
*/
|
|
public void addOpaquenessListener(@NonNull Runnable listener) {
|
|
mOpaquenessListeners.add(listener);
|
|
}
|
|
|
|
/**
|
|
* Removes previously registered listener.
|
|
* @see #addOpaquenessListener(Runnable)
|
|
*/
|
|
public void removeOpaquenessListener(@NonNull Runnable listener) {
|
|
mOpaquenessListeners.remove(listener);
|
|
}
|
|
|
|
/**
|
|
* A Utility interface allowing for other surfaces to draw on ScrimView
|
|
*/
|
|
public interface ScrimDrawingController {
|
|
/**
|
|
* Called inside ScrimView#OnDraw
|
|
*/
|
|
void drawOnScrim(Canvas canvas);
|
|
}
|
|
}
|