1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.chrome.browser.ui;
6 
7 import org.chromium.base.ObserverList;
8 import org.chromium.ui.util.TokenHolder;
9 
10 /**
11  * Passes around the ability to set a view that is obscuring all tabs.
12  */
13 public class TabObscuringHandler {
14     /**
15      * Interface for the observers of the tab-obscuring state change.
16      */
17     public interface Observer {
18         /**
19          * @param isObscured {@code true} if the observer is obscured by another view.
20          */
updateObscured(boolean isObscured)21         void updateObscured(boolean isObscured);
22     }
23 
24     /** A mechanism for distributing unique tokens to users of this system. */
25     private final TokenHolder mTokenHolder;
26 
27     private final ObserverList<Observer> mVisibilityObservers = new ObserverList<>();
28 
29     /** Default constructor */
TabObscuringHandler()30     public TabObscuringHandler() {
31         mTokenHolder = new TokenHolder(this::notifyUpdate);
32     }
33 
34     /**
35      * Notify the system that there is a feature obscuring all visible tabs for accessibility. As
36      * long as this set is nonempty, all tabs should be hidden from the accessibility tree.
37      *
38      * @return A token to hold while the feature is obscuring all tabs. This token is required to
39      *         un-obscure the tabs.
40      */
obscureAllTabs()41     public int obscureAllTabs() {
42         return mTokenHolder.acquireToken();
43     }
44 
45     /**
46      * Remove a feature that previously obscured the content of all tabs.
47      *
48      * @param token The unique token that identified the feature (acquired in
49      *              {@link #obscureAllTabs()}.
50      */
unobscureAllTabs(int token)51     public void unobscureAllTabs(int token) {
52         assert token != TokenHolder.INVALID_TOKEN;
53         mTokenHolder.releaseToken(token);
54     }
55 
56     /** @return Whether or not any features obscure all tabs. */
areAllTabsObscured()57     public boolean areAllTabsObscured() {
58         return mTokenHolder.hasTokens();
59     }
60 
61     /**
62      * Add {@link Observer} object.
63      * @param observer Observer object monitoring tab visibility.
64      */
addObserver(Observer observer)65     public void addObserver(Observer observer) {
66         mVisibilityObservers.addObserver(observer);
67     }
68 
69     /**
70      * Remove {@link Observer} object.
71      * @param observer Observer object monitoring tab visibility.
72      */
removeObserver(Observer observer)73     public void removeObserver(Observer observer) {
74         mVisibilityObservers.removeObserver(observer);
75     }
76 
77     /**
78      * Notify all the observers of the visibility update.
79      */
notifyUpdate()80     private void notifyUpdate() {
81         for (Observer observer : mVisibilityObservers) {
82             observer.updateObscured(mTokenHolder.hasTokens());
83         }
84     }
85 }
86