• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.launcher3.views;
17 
18 import static com.android.launcher3.util.SystemUiController.UI_STATE_SCRIM_VIEW;
19 
20 import android.content.Context;
21 import android.graphics.Canvas;
22 import android.graphics.Color;
23 import android.graphics.Rect;
24 import android.graphics.drawable.ColorDrawable;
25 import android.util.AttributeSet;
26 import android.view.View;
27 
28 import androidx.core.graphics.ColorUtils;
29 
30 import com.android.launcher3.BaseActivity;
31 import com.android.launcher3.Insettable;
32 import com.android.launcher3.util.SystemUiController;
33 
34 /**
35  * Simple scrim which draws a flat color
36  */
37 public class ScrimView extends View implements Insettable {
38     private static final float STATUS_BAR_COLOR_FORCE_UPDATE_THRESHOLD = 0.9f;
39 
40     private SystemUiController mSystemUiController;
41 
42     private ScrimDrawingController mDrawingController;
43     private int mBackgroundColor;
44     private boolean mIsVisible = true;
45 
ScrimView(Context context, AttributeSet attrs)46     public ScrimView(Context context, AttributeSet attrs) {
47         super(context, attrs);
48         setFocusable(false);
49     }
50 
51     @Override
setInsets(Rect insets)52     public void setInsets(Rect insets) {
53     }
54 
55     @Override
hasOverlappingRendering()56     public boolean hasOverlappingRendering() {
57         return false;
58     }
59 
60     @Override
onSetAlpha(int alpha)61     protected boolean onSetAlpha(int alpha) {
62         updateSysUiColors();
63         return super.onSetAlpha(alpha);
64     }
65 
66     @Override
setBackgroundColor(int color)67     public void setBackgroundColor(int color) {
68         mBackgroundColor = color;
69         updateSysUiColors();
70         super.setBackgroundColor(color);
71     }
72 
73     @Override
onVisibilityAggregated(boolean isVisible)74     public void onVisibilityAggregated(boolean isVisible) {
75         super.onVisibilityAggregated(isVisible);
76         mIsVisible = isVisible;
77     }
78 
isFullyOpaque()79     public boolean isFullyOpaque() {
80         return mIsVisible && getAlpha() == 1 && Color.alpha(mBackgroundColor) == 255;
81     }
82 
83     @Override
onDraw(Canvas canvas)84     protected void onDraw(Canvas canvas) {
85         super.onDraw(canvas);
86         if (mDrawingController != null) {
87             mDrawingController.drawOnScrim(canvas);
88         }
89     }
90 
91     @Override
onVisibilityChanged(View changedView, int visibility)92     protected void onVisibilityChanged(View changedView, int visibility) {
93         super.onVisibilityChanged(changedView, visibility);
94         updateSysUiColors();
95     }
96 
updateSysUiColors()97     private void updateSysUiColors() {
98         // Use a light system UI (dark icons) if all apps is behind at least half of the
99         // status bar.
100         final float threshold = STATUS_BAR_COLOR_FORCE_UPDATE_THRESHOLD;
101         boolean forceChange = getVisibility() == VISIBLE
102                 && getAlpha() > threshold
103                 && (Color.alpha(mBackgroundColor) / 255f) > threshold;
104         if (forceChange) {
105             getSystemUiController().updateUiState(UI_STATE_SCRIM_VIEW, !isScrimDark());
106         } else {
107             getSystemUiController().updateUiState(UI_STATE_SCRIM_VIEW, 0);
108         }
109     }
110 
getSystemUiController()111     private SystemUiController getSystemUiController() {
112         if (mSystemUiController == null) {
113             mSystemUiController = BaseActivity.fromContext(getContext()).getSystemUiController();
114         }
115         return mSystemUiController;
116     }
117 
isScrimDark()118     private boolean isScrimDark() {
119         if (!(getBackground() instanceof ColorDrawable)) {
120             throw new IllegalStateException(
121                     "ScrimView must have a ColorDrawable background, this one has: "
122                             + getBackground());
123         }
124         return ColorUtils.calculateLuminance(
125                 ((ColorDrawable) getBackground()).getColor()) < 0.5f;
126     }
127 
128     /**
129      * Sets drawing controller. Invalidates ScrimView if drawerController has changed.
130      */
setDrawingController(ScrimDrawingController drawingController)131     public void setDrawingController(ScrimDrawingController drawingController) {
132         if (mDrawingController != drawingController) {
133             mDrawingController = drawingController;
134             invalidate();
135         }
136     }
137 
138     /**
139      * A Utility interface allowing for other surfaces to draw on ScrimView
140      */
141     public interface ScrimDrawingController {
142         /**
143          * Called inside ScrimView#OnDraw
144          */
drawOnScrim(Canvas canvas)145         void drawOnScrim(Canvas canvas);
146     }
147 }
148