|
1 package org.mozilla.gecko; |
|
2 |
|
3 import java.util.EnumSet; |
|
4 |
|
5 import org.mozilla.gecko.PrefsHelper.PrefHandlerBase; |
|
6 import org.mozilla.gecko.gfx.LayerView; |
|
7 import org.mozilla.gecko.util.ThreadUtils; |
|
8 |
|
9 import android.os.Bundle; |
|
10 |
|
11 public class DynamicToolbar { |
|
12 private static final String STATE_ENABLED = "dynamic_toolbar"; |
|
13 private static final String CHROME_PREF = "browser.chrome.dynamictoolbar"; |
|
14 |
|
15 // DynamicToolbar is enabled iff prefEnabled is true *and* accessibilityEnabled is false, |
|
16 // so it is disabled by default on startup. We do not enable it until we explicitly get |
|
17 // the pref from Gecko telling us to turn it on. |
|
18 private volatile boolean prefEnabled; |
|
19 private boolean accessibilityEnabled; |
|
20 |
|
21 private final int prefObserverId; |
|
22 private final EnumSet<PinReason> pinFlags = EnumSet.noneOf(PinReason.class); |
|
23 private LayerView layerView; |
|
24 private OnEnabledChangedListener enabledChangedListener; |
|
25 |
|
26 public enum PinReason { |
|
27 RELAYOUT, |
|
28 ACTION_MODE |
|
29 } |
|
30 |
|
31 public enum VisibilityTransition { |
|
32 IMMEDIATE, |
|
33 ANIMATE |
|
34 } |
|
35 |
|
36 /** |
|
37 * Listener for changes to the dynamic toolbar's enabled state. |
|
38 */ |
|
39 public interface OnEnabledChangedListener { |
|
40 /** |
|
41 * This callback is executed on the UI thread. |
|
42 */ |
|
43 public void onEnabledChanged(boolean enabled); |
|
44 } |
|
45 |
|
46 public DynamicToolbar() { |
|
47 // Listen to the dynamic toolbar pref |
|
48 prefObserverId = PrefsHelper.getPref(CHROME_PREF, new PrefHandler()); |
|
49 } |
|
50 |
|
51 public void destroy() { |
|
52 PrefsHelper.removeObserver(prefObserverId); |
|
53 } |
|
54 |
|
55 public void setLayerView(LayerView layerView) { |
|
56 ThreadUtils.assertOnUiThread(); |
|
57 |
|
58 this.layerView = layerView; |
|
59 } |
|
60 |
|
61 public void setEnabledChangedListener(OnEnabledChangedListener listener) { |
|
62 ThreadUtils.assertOnUiThread(); |
|
63 |
|
64 enabledChangedListener = listener; |
|
65 } |
|
66 |
|
67 public void onSaveInstanceState(Bundle outState) { |
|
68 ThreadUtils.assertOnUiThread(); |
|
69 |
|
70 outState.putBoolean(STATE_ENABLED, prefEnabled); |
|
71 } |
|
72 |
|
73 public void onRestoreInstanceState(Bundle savedInstanceState) { |
|
74 ThreadUtils.assertOnUiThread(); |
|
75 |
|
76 if (savedInstanceState != null) { |
|
77 prefEnabled = savedInstanceState.getBoolean(STATE_ENABLED); |
|
78 } |
|
79 } |
|
80 |
|
81 public boolean isEnabled() { |
|
82 ThreadUtils.assertOnUiThread(); |
|
83 |
|
84 return prefEnabled && !accessibilityEnabled; |
|
85 } |
|
86 |
|
87 public void setAccessibilityEnabled(boolean enabled) { |
|
88 ThreadUtils.assertOnUiThread(); |
|
89 |
|
90 if (accessibilityEnabled == enabled) { |
|
91 return; |
|
92 } |
|
93 |
|
94 // Disable the dynamic toolbar when accessibility features are enabled, |
|
95 // and re-read the preference when they're disabled. |
|
96 accessibilityEnabled = enabled; |
|
97 if (prefEnabled) { |
|
98 triggerEnabledListener(); |
|
99 } |
|
100 } |
|
101 |
|
102 public void setVisible(boolean visible, VisibilityTransition transition) { |
|
103 ThreadUtils.assertOnUiThread(); |
|
104 |
|
105 if (layerView == null) { |
|
106 return; |
|
107 } |
|
108 |
|
109 final boolean immediate = transition.equals(VisibilityTransition.IMMEDIATE); |
|
110 if (visible) { |
|
111 layerView.getLayerMarginsAnimator().showMargins(immediate); |
|
112 } else { |
|
113 layerView.getLayerMarginsAnimator().hideMargins(immediate); |
|
114 } |
|
115 } |
|
116 |
|
117 public void setPinned(boolean pinned, PinReason reason) { |
|
118 ThreadUtils.assertOnUiThread(); |
|
119 |
|
120 if (layerView == null) { |
|
121 return; |
|
122 } |
|
123 |
|
124 if (pinned) { |
|
125 pinFlags.add(reason); |
|
126 } else { |
|
127 pinFlags.remove(reason); |
|
128 } |
|
129 |
|
130 layerView.getLayerMarginsAnimator().setMarginsPinned(!pinFlags.isEmpty()); |
|
131 } |
|
132 |
|
133 private void triggerEnabledListener() { |
|
134 if (enabledChangedListener != null) { |
|
135 enabledChangedListener.onEnabledChanged(isEnabled()); |
|
136 } |
|
137 } |
|
138 |
|
139 private class PrefHandler extends PrefHandlerBase { |
|
140 @Override |
|
141 public void prefValue(String pref, boolean value) { |
|
142 if (value == prefEnabled) { |
|
143 return; |
|
144 } |
|
145 |
|
146 prefEnabled = value; |
|
147 |
|
148 ThreadUtils.postToUiThread(new Runnable() { |
|
149 @Override |
|
150 public void run() { |
|
151 // If accessibility is enabled, the dynamic toolbar is |
|
152 // forced to be off. |
|
153 if (!accessibilityEnabled) { |
|
154 triggerEnabledListener(); |
|
155 } |
|
156 } |
|
157 }); |
|
158 } |
|
159 |
|
160 @Override |
|
161 public boolean isObserver() { |
|
162 // We want to be notified of changes to be able to switch mode |
|
163 // without restarting. |
|
164 return true; |
|
165 } |
|
166 } |
|
167 } |