1 /*
2  * Copyright (C) 2023 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 
17 package com.android.server.wm;
18 
19 import android.annotation.NonNull;
20 import android.graphics.Rect;
21 import android.view.SurfaceControl;
22 
23 import com.android.internal.annotations.VisibleForTesting;
24 import com.android.window.flags.Flags;
25 
26 /**
27  * Utility class for use by a WindowContainer implementation to add "DimLayer" support, that is
28  * black layers of varying opacity at various Z-levels which create the effect of a Dim.
29  */
30 public abstract class Dimmer {
31 
32     static final boolean DIMMER_REFACTOR = Flags.introduceSmootherDimmer();
33 
34     /**
35      * The {@link WindowContainer} that our Dims are bounded to. We may be dimming on behalf of the
36      * host, some controller of it, or one of the hosts children.
37      */
38     protected final WindowContainer mHost;
39 
Dimmer(WindowContainer host)40     protected Dimmer(WindowContainer host) {
41         mHost = host;
42     }
43 
44     // Constructs the correct type of dimmer
create(WindowContainer host)45     static Dimmer create(WindowContainer host) {
46         return DIMMER_REFACTOR ? new SmoothDimmer(host) : new LegacyDimmer(host);
47     }
48 
49     @NonNull
getHost()50     WindowContainer<?> getHost() {
51         return mHost;
52     }
53 
54     /**
55      * Position the dim relatively to the dimming container.
56      * Normally called together with #setAppearance, it can be called alone to keep the dim parented
57      * to a visible container until the next dimming container is ready.
58      * If multiple containers call this method, only the changes relative to the topmost will be
59      * applied.
60      *
61      * For each call to {@link WindowContainer#prepareSurfaces()} the DimState will be reset, and
62      * the child of the host should call adjustRelativeLayer and {@link Dimmer#adjustAppearance} to
63      * continue dimming. Indeed, this method won't be able to keep dimming or get a new DimState
64      * without also adjusting the appearance.
65      * @param container      The container which to dim above. Should be a child of the host.
66      * @param relativeLayer  The position of the dim wrt the container
67      */
adjustRelativeLayer(WindowContainer container, int relativeLayer)68     protected abstract void adjustRelativeLayer(WindowContainer container, int relativeLayer);
69 
70     /**
71      * Set the aspect of the dim layer, and request to keep dimming.
72      * For each call to {@link WindowContainer#prepareSurfaces} the Dim state will be reset, and the
73      * child should call setAppearance again to request the Dim to continue.
74      * If multiple containers call this method, only the changes relative to the topmost will be
75      * applied.
76      * @param container  Container requesting the dim
77      * @param alpha      Dim amount
78      * @param blurRadius Blur amount
79      */
adjustAppearance( WindowContainer container, float alpha, int blurRadius)80     protected abstract void adjustAppearance(
81             WindowContainer container, float alpha, int blurRadius);
82 
83     /**
84      * Mark all dims as pending completion on the next call to {@link #updateDims}
85      *
86      * Called before iterating on mHost's children, first step of dimming.
87      * This is intended for us by the host container, to be called at the beginning of
88      * {@link WindowContainer#prepareSurfaces}. After calling this, the container should
89      * chain {@link WindowContainer#prepareSurfaces} down to it's children to give them
90      * a chance to request dims to continue.
91      */
resetDimStates()92     abstract void resetDimStates();
93 
94     /** Returns non-null bounds if the dimmer is showing. */
getDimBounds()95     abstract Rect getDimBounds();
96 
dontAnimateExit()97     abstract void dontAnimateExit();
98 
99     @VisibleForTesting
getDimLayer()100     abstract SurfaceControl getDimLayer();
101 
102     /**
103      * Call after invoking {@link WindowContainer#prepareSurfaces} on children as
104      * described in {@link #resetDimStates}.
105      *
106      * @param t      A transaction in which to update the dims.
107      * @return true if any Dims were updated.
108      */
updateDims(SurfaceControl.Transaction t)109     abstract boolean updateDims(SurfaceControl.Transaction t);
110 }
111