Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 package org.mozilla.gecko;
3 import java.util.EnumSet;
5 import org.mozilla.gecko.PrefsHelper.PrefHandlerBase;
6 import org.mozilla.gecko.gfx.LayerView;
7 import org.mozilla.gecko.util.ThreadUtils;
9 import android.os.Bundle;
11 public class DynamicToolbar {
12 private static final String STATE_ENABLED = "dynamic_toolbar";
13 private static final String CHROME_PREF = "browser.chrome.dynamictoolbar";
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;
21 private final int prefObserverId;
22 private final EnumSet<PinReason> pinFlags = EnumSet.noneOf(PinReason.class);
23 private LayerView layerView;
24 private OnEnabledChangedListener enabledChangedListener;
26 public enum PinReason {
27 RELAYOUT,
28 ACTION_MODE
29 }
31 public enum VisibilityTransition {
32 IMMEDIATE,
33 ANIMATE
34 }
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 }
46 public DynamicToolbar() {
47 // Listen to the dynamic toolbar pref
48 prefObserverId = PrefsHelper.getPref(CHROME_PREF, new PrefHandler());
49 }
51 public void destroy() {
52 PrefsHelper.removeObserver(prefObserverId);
53 }
55 public void setLayerView(LayerView layerView) {
56 ThreadUtils.assertOnUiThread();
58 this.layerView = layerView;
59 }
61 public void setEnabledChangedListener(OnEnabledChangedListener listener) {
62 ThreadUtils.assertOnUiThread();
64 enabledChangedListener = listener;
65 }
67 public void onSaveInstanceState(Bundle outState) {
68 ThreadUtils.assertOnUiThread();
70 outState.putBoolean(STATE_ENABLED, prefEnabled);
71 }
73 public void onRestoreInstanceState(Bundle savedInstanceState) {
74 ThreadUtils.assertOnUiThread();
76 if (savedInstanceState != null) {
77 prefEnabled = savedInstanceState.getBoolean(STATE_ENABLED);
78 }
79 }
81 public boolean isEnabled() {
82 ThreadUtils.assertOnUiThread();
84 return prefEnabled && !accessibilityEnabled;
85 }
87 public void setAccessibilityEnabled(boolean enabled) {
88 ThreadUtils.assertOnUiThread();
90 if (accessibilityEnabled == enabled) {
91 return;
92 }
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 }
102 public void setVisible(boolean visible, VisibilityTransition transition) {
103 ThreadUtils.assertOnUiThread();
105 if (layerView == null) {
106 return;
107 }
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 }
117 public void setPinned(boolean pinned, PinReason reason) {
118 ThreadUtils.assertOnUiThread();
120 if (layerView == null) {
121 return;
122 }
124 if (pinned) {
125 pinFlags.add(reason);
126 } else {
127 pinFlags.remove(reason);
128 }
130 layerView.getLayerMarginsAnimator().setMarginsPinned(!pinFlags.isEmpty());
131 }
133 private void triggerEnabledListener() {
134 if (enabledChangedListener != null) {
135 enabledChangedListener.onEnabledChanged(isEnabled());
136 }
137 }
139 private class PrefHandler extends PrefHandlerBase {
140 @Override
141 public void prefValue(String pref, boolean value) {
142 if (value == prefEnabled) {
143 return;
144 }
146 prefEnabled = value;
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 }
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 }