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 
17 package android.view;
18 
19 import android.annotation.FlaggedApi;
20 import android.annotation.IntDef;
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.graphics.Insets;
24 import android.inputmethodservice.InputMethodService;
25 import android.os.Build;
26 import android.os.CancellationSignal;
27 import android.view.WindowInsets.Type;
28 import android.view.WindowInsets.Type.InsetsType;
29 import android.view.animation.Interpolator;
30 import android.view.flags.Flags;
31 
32 import java.lang.annotation.Retention;
33 import java.lang.annotation.RetentionPolicy;
34 
35 /**
36  * Interface to control windows that generate insets.
37  */
38 public interface WindowInsetsController {
39 
40     /**
41      * Makes status bars become opaque with solid dark background and light foreground.
42      * @hide
43      */
44     int APPEARANCE_OPAQUE_STATUS_BARS = 1;
45 
46     /**
47      * Makes navigation bars become opaque with solid dark background and light foreground.
48      * @hide
49      */
50     int APPEARANCE_OPAQUE_NAVIGATION_BARS = 1 << 1;
51 
52     /**
53      * Makes items on system bars become less noticeable without changing the layout of the bars.
54      * @hide
55      */
56     int APPEARANCE_LOW_PROFILE_BARS = 1 << 2;
57 
58     /**
59      * Changes the foreground color for light status bars so that the items on the bar can be read
60      * clearly.
61      */
62     int APPEARANCE_LIGHT_STATUS_BARS = 1 << 3;
63 
64     /**
65      * Changes the foreground color for light navigation bars so that the items on the bar can be
66      * read clearly.
67      */
68     int APPEARANCE_LIGHT_NAVIGATION_BARS = 1 << 4;
69 
70     /**
71      * Makes status bars semi-transparent with dark background and light foreground.
72      * @hide
73      */
74     int APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS = 1 << 5;
75 
76     /**
77      * Makes navigation bars semi-transparent with dark background and light foreground.
78      * @hide
79      */
80     int APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS = 1 << 6;
81 
82     /**
83      * Makes the caption bar transparent.
84      */
85     @FlaggedApi(Flags.FLAG_CUSTOMIZABLE_WINDOW_HEADERS)
86     int APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND = 1 << 7;
87 
88     /**
89      * When {@link WindowInsetsController#APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND} is set,
90      * changes the foreground color of the caption bars so that the items on the bar can be read
91      * clearly on light backgrounds.
92      */
93     @FlaggedApi(Flags.FLAG_CUSTOMIZABLE_WINDOW_HEADERS)
94     int APPEARANCE_LIGHT_CAPTION_BARS = 1 << 8;
95 
96     /**
97      * Same as {@link #APPEARANCE_LIGHT_NAVIGATION_BARS} but set by the system. The system will
98      * respect {@link #APPEARANCE_LIGHT_NAVIGATION_BARS} when this is cleared.
99      * @hide
100      */
101     int APPEARANCE_FORCE_LIGHT_NAVIGATION_BARS = 1 << 9;
102 
103     /**
104      * Determines the appearance of system bars.
105      * @hide
106      */
107     @Retention(RetentionPolicy.SOURCE)
108     @IntDef(flag = true, value = {
109             APPEARANCE_OPAQUE_STATUS_BARS,
110             APPEARANCE_OPAQUE_NAVIGATION_BARS,
111             APPEARANCE_LOW_PROFILE_BARS,
112             APPEARANCE_LIGHT_STATUS_BARS,
113             APPEARANCE_LIGHT_NAVIGATION_BARS,
114             APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS,
115             APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS,
116             APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND,
117             APPEARANCE_LIGHT_CAPTION_BARS,
118             APPEARANCE_FORCE_LIGHT_NAVIGATION_BARS})
119     @interface Appearance {
120     }
121 
122     /**
123      * Option for {@link #setSystemBarsBehavior(int)}. System bars will be forcibly shown on any
124      * user interaction on the corresponding display if navigation bars are hidden by
125      * {@link #hide(int)} or
126      * {@link WindowInsetsAnimationController#setInsetsAndAlpha(Insets, float, float)}.
127      * @deprecated This is not supported on Android {@link Build.VERSION_CODES#S} and later. Use
128      *             {@link #BEHAVIOR_DEFAULT} or {@link #BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE}
129      *             instead.
130      */
131     @Deprecated
132     int BEHAVIOR_SHOW_BARS_BY_TOUCH = 0;
133 
134     /**
135      * The default option for {@link #setSystemBarsBehavior(int)}: Window would like to remain
136      * interactive when hiding navigation bars by calling {@link #hide(int)} or
137      * {@link WindowInsetsAnimationController#setInsetsAndAlpha(Insets, float, float)}.
138      *
139      * <p>When system bars are hidden in this mode, they can be revealed with system gestures, such
140      * as swiping from the edge of the screen where the bar is hidden from.</p>
141      *
142      * <p>When the gesture navigation is enabled, the system gestures can be triggered regardless
143      * the visibility of system bars.</p>
144      */
145     int BEHAVIOR_DEFAULT = 1;
146 
147     /**
148      * Option for {@link #setSystemBarsBehavior(int)}: Window would like to remain interactive when
149      * hiding navigation bars by calling {@link #hide(int)} or
150      * {@link WindowInsetsAnimationController#setInsetsAndAlpha(Insets, float, float)}.
151      *
152      * <p>When system bars are hidden in this mode, they can be revealed with system gestures, such
153      * as swiping from the edge of the screen where the bar is hidden from.</p>
154      * @deprecated Use {@link #BEHAVIOR_DEFAULT} instead.
155      */
156     @Deprecated
157     int BEHAVIOR_SHOW_BARS_BY_SWIPE = BEHAVIOR_DEFAULT;
158 
159     /**
160      * Option for {@link #setSystemBarsBehavior(int)}: Window would like to remain interactive when
161      * hiding navigation bars by calling {@link #hide(int)} or
162      * {@link WindowInsetsAnimationController#setInsetsAndAlpha(Insets, float, float)}.
163      *
164      * <p>When system bars are hidden in this mode, they can be revealed temporarily with system
165      * gestures, such as swiping from the edge of the screen where the bar is hidden from. These
166      * transient system bars will overlay app’s content, may have some degree of transparency, and
167      * will automatically hide after a short timeout.</p>
168      */
169     int BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE = 2;
170 
171     /**
172      * Determines the behavior of system bars when hiding them by calling {@link #hide}.
173      * @hide
174      */
175     @Retention(RetentionPolicy.SOURCE)
176     @IntDef(value = {BEHAVIOR_DEFAULT, BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE})
177     @interface Behavior {
178     }
179 
180     /**
181      * Makes a set of windows that cause insets appear on screen.
182      * <p>
183      * Note that if the window currently doesn't have control over a certain type, it will apply the
184      * change as soon as the window gains control. The app can listen to the event by observing
185      * {@link View#onApplyWindowInsets} and checking visibility with {@link WindowInsets#isVisible}.
186      *
187      * @param types A bitmask of {@link WindowInsets.Type} specifying what windows the app
188      *              would like to make appear on screen.
189      */
show(@nsetsType int types)190     void show(@InsetsType int types);
191 
192     /**
193      * Makes a set of windows causing insets disappear.
194      * <p>
195      * Note that if the window currently doesn't have control over a certain type, it will apply the
196      * change as soon as the window gains control. The app can listen to the event by observing
197      * {@link View#onApplyWindowInsets} and checking visibility with {@link WindowInsets#isVisible}.
198      *
199      * @param types A bitmask of {@link WindowInsets.Type} specifying what windows the app
200      *              would like to make disappear.
201      */
hide(@nsetsType int types)202     void hide(@InsetsType int types);
203 
204     /**
205      * Lets the application control window inset animations in a frame-by-frame manner by modifying
206      * the position of the windows in the system causing insets directly.
207      *
208      * @param types The {@link WindowInsets.Type}s the application has requested to control.
209      * @param durationMillis Duration of animation in
210      *                       {@link java.util.concurrent.TimeUnit#MILLISECONDS}, or -1 if the
211      *                       animation doesn't have a predetermined duration. This value will be
212      *                       passed to {@link WindowInsetsAnimation#getDurationMillis()}
213      * @param interpolator The interpolator used for this animation, or {@code null} if this
214      *                     animation doesn't follow an interpolation curve. This value will be
215      *                     passed to {@link WindowInsetsAnimation#getInterpolator()} and used to
216      *                     calculate {@link WindowInsetsAnimation#getInterpolatedFraction()}.
217      * @param listener The {@link WindowInsetsAnimationControlListener} that gets called when the
218      *                 windows are ready to be controlled, among other callbacks.
219      * @param cancellationSignal A cancellation signal that the caller can use to cancel the
220      *                           request to obtain control, or once they have control, to cancel the
221      *                           control.
222      * @see WindowInsetsAnimation#getFraction()
223      * @see WindowInsetsAnimation#getInterpolatedFraction()
224      * @see WindowInsetsAnimation#getInterpolator()
225      * @see WindowInsetsAnimation#getDurationMillis()
226      */
controlWindowInsetsAnimation(@nsetsType int types, long durationMillis, @Nullable Interpolator interpolator, @Nullable CancellationSignal cancellationSignal, @NonNull WindowInsetsAnimationControlListener listener)227     void controlWindowInsetsAnimation(@InsetsType int types, long durationMillis,
228             @Nullable Interpolator interpolator,
229             @Nullable CancellationSignal cancellationSignal,
230             @NonNull WindowInsetsAnimationControlListener listener);
231 
232     /**
233      * Lets the application add non-controllable listener object that can be called back
234      * when animation is invoked by the system by host calling methods such as {@link #show} or
235      * {@link #hide}.
236      *
237      * The listener is supposed to be used for logging only, using the control or
238      * relying on the timing of the callback in any other way is not supported.
239      *
240      * @param listener The {@link WindowInsetsAnimationControlListener} that gets called when
241      *                 the animation is driven by the system and not the host
242      * @hide
243      */
setSystemDrivenInsetsAnimationLoggingListener( @ullable WindowInsetsAnimationControlListener listener)244     void setSystemDrivenInsetsAnimationLoggingListener(
245             @Nullable WindowInsetsAnimationControlListener listener);
246 
247     /**
248      * Controls the appearance of system bars.
249      * <p>
250      * For example, the following statement adds {@link #APPEARANCE_LIGHT_STATUS_BARS}:
251      * <pre>
252      * setSystemBarsAppearance(APPEARANCE_LIGHT_STATUS_BARS, APPEARANCE_LIGHT_STATUS_BARS)
253      * </pre>
254      * And the following statement clears it:
255      * <pre>
256      * setSystemBarsAppearance(0, APPEARANCE_LIGHT_STATUS_BARS)
257      * </pre>
258      *
259      * @param appearance Bitmask of appearance flags.
260      * @param mask Specifies which flags of appearance should be changed.
261      * @see #getSystemBarsAppearance
262      */
setSystemBarsAppearance(@ppearance int appearance, @Appearance int mask)263     void setSystemBarsAppearance(@Appearance int appearance, @Appearance int mask);
264 
265     /**
266      * Similar to {@link #setSystemBarsAppearance} but the given flag will only take effect when it
267      * is not controlled by {@link #setSystemBarsAppearance}.
268      *
269      * @see WindowInsetsController#getSystemBarsAppearance()
270      * @see android.R.attr#windowLightStatusBar
271      * @see android.R.attr#windowLightNavigationBar
272      * @hide
273      */
setSystemBarsAppearanceFromResource(@ppearance int appearance, @Appearance int mask)274     void setSystemBarsAppearanceFromResource(@Appearance int appearance, @Appearance int mask);
275 
276     /**
277      * Retrieves the requested appearance of system bars.
278      *
279      * @return The requested bitmask of system bar appearance controlled by this window.
280      * @see #setSystemBarsAppearance(int, int)
281      * @see android.R.attr#windowLightStatusBar
282      * @see android.R.attr#windowLightNavigationBar
283      */
getSystemBarsAppearance()284     @Appearance int getSystemBarsAppearance();
285 
286     /**
287      * Sets the insets height for the IME caption bar, which corresponds to the
288      * "fake" IME navigation bar.
289      *
290      * @param height the insets height of the IME caption bar.
291      * @hide
292      */
setImeCaptionBarInsetsHeight(int height)293     default void setImeCaptionBarInsetsHeight(int height) {
294     }
295 
296     /**
297      * Controls the behavior of system bars.
298      *
299      * @param behavior Determines how the bars behave when being hidden by the application.
300      * @see #getSystemBarsBehavior
301      */
setSystemBarsBehavior(@ehavior int behavior)302     void setSystemBarsBehavior(@Behavior int behavior);
303 
304     /**
305      * Retrieves the requested behavior of system bars.
306      *
307      * @return the system bar behavior controlled by this window.
308      * @see #setSystemBarsBehavior(int)
309      */
getSystemBarsBehavior()310     @Behavior int getSystemBarsBehavior();
311 
312     /**
313      * Disables or enables the animations.
314      *
315      * @hide
316      */
setAnimationsDisabled(boolean disable)317     void setAnimationsDisabled(boolean disable);
318 
319     /**
320      * @hide
321      */
getState()322     InsetsState getState();
323 
324     /**
325      * @return Insets types that have been requested to be visible.
326      * @hide
327      */
getRequestedVisibleTypes()328     @InsetsType int getRequestedVisibleTypes();
329 
330     /**
331      * Adds a {@link OnControllableInsetsChangedListener} to the window insets controller.
332      *
333      * @param listener The listener to add.
334      *
335      * @see OnControllableInsetsChangedListener
336      * @see #removeOnControllableInsetsChangedListener(OnControllableInsetsChangedListener)
337      */
addOnControllableInsetsChangedListener( @onNull OnControllableInsetsChangedListener listener)338     void addOnControllableInsetsChangedListener(
339             @NonNull OnControllableInsetsChangedListener listener);
340 
341     /**
342      * Removes a {@link OnControllableInsetsChangedListener} from the window insets controller.
343      *
344      * @param listener The listener to remove.
345      *
346      * @see OnControllableInsetsChangedListener
347      * @see #addOnControllableInsetsChangedListener(OnControllableInsetsChangedListener)
348      */
removeOnControllableInsetsChangedListener( @onNull OnControllableInsetsChangedListener listener)349     void removeOnControllableInsetsChangedListener(
350             @NonNull OnControllableInsetsChangedListener listener);
351 
352     /**
353      * Listener to be notified when the set of controllable {@link WindowInsets.Type} controlled by
354      * a {@link WindowInsetsController} changes.
355      * <p>
356      * Once a {@link WindowInsets.Type} becomes controllable, the app will be able to control the
357      * window that is causing this type of insets by calling {@link #controlWindowInsetsAnimation}.
358      * <p>
359      * Note: When listening to controllability of the {@link Type#ime},
360      * {@link #controlWindowInsetsAnimation} may still fail in case the {@link InputMethodService}
361      * decides to cancel the show request. This could happen when there is a hardware keyboard
362      * attached.
363      *
364      * @see #addOnControllableInsetsChangedListener(OnControllableInsetsChangedListener)
365      * @see #removeOnControllableInsetsChangedListener(OnControllableInsetsChangedListener)
366      */
367     interface OnControllableInsetsChangedListener {
368 
369         /**
370          * Called when the set of controllable {@link WindowInsets.Type} changes.
371          *
372          * @param controller The controller for which the set of controllable
373          *                   {@link WindowInsets.Type}s are changing.
374          * @param typeMask Bitwise type-mask of the {@link WindowInsets.Type}s the controller is
375          *                 currently able to control.
376          */
onControllableInsetsChanged(@onNull WindowInsetsController controller, @InsetsType int typeMask)377         void onControllableInsetsChanged(@NonNull WindowInsetsController controller,
378                 @InsetsType int typeMask);
379     }
380 }
381