Files
tenfourfox/mobile/android/base/java/org/mozilla/gecko/DynamicToolbar.java
Cameron Kaiser c9b2922b70 hello FPR
2017-04-19 00:56:45 -07:00

231 lines
6.8 KiB
Java

package org.mozilla.gecko;
import java.util.EnumSet;
import org.mozilla.gecko.PrefsHelper.PrefHandlerBase;
import org.mozilla.gecko.gfx.LayerView;
import org.mozilla.gecko.util.ThreadUtils;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
public class DynamicToolbar {
private static final String LOGTAG = "DynamicToolbar";
private static final String STATE_ENABLED = "dynamic_toolbar";
private static final String CHROME_PREF = "browser.chrome.dynamictoolbar";
// DynamicToolbar is enabled iff prefEnabled is true *and* accessibilityEnabled is false,
// so it is disabled by default on startup. We do not enable it until we explicitly get
// the pref from Gecko telling us to turn it on.
private volatile boolean prefEnabled;
private boolean accessibilityEnabled;
// On some device we have to force-disable the dynamic toolbar because of
// bugs in the Android code. See bug 1231554.
private final boolean forceDisabled;
private final int prefObserverId;
private final EnumSet<PinReason> pinFlags = EnumSet.noneOf(PinReason.class);
private LayerView layerView;
private OnEnabledChangedListener enabledChangedListener;
private boolean temporarilyVisible;
public enum PinReason {
RELAYOUT,
ACTION_MODE,
FULL_SCREEN
}
public enum VisibilityTransition {
IMMEDIATE,
ANIMATE
}
/**
* Listener for changes to the dynamic toolbar's enabled state.
*/
public interface OnEnabledChangedListener {
/**
* This callback is executed on the UI thread.
*/
public void onEnabledChanged(boolean enabled);
}
public DynamicToolbar() {
// Listen to the dynamic toolbar pref
prefObserverId = PrefsHelper.getPref(CHROME_PREF, new PrefHandler());
forceDisabled = isForceDisabled();
if (forceDisabled) {
Log.i(LOGTAG, "Force-disabling dynamic toolbar for " + Build.MODEL + " (" + Build.DEVICE + "/" + Build.PRODUCT + ")");
}
}
public static boolean isForceDisabled() {
// Force-disable dynamic toolbar on the variants of the Galaxy Note 10.1
// and Note 8.0 running Android 4.1.2. (Bug 1231554). This includes
// the following model numbers:
// GT-N8000, GT-N8005, GT-N8010, GT-N8013, GT-N8020
// GT-N5100, GT-N5110, GT-N5120
return Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN
&& (Build.MODEL.startsWith("GT-N80") ||
Build.MODEL.startsWith("GT-N51"));
}
public void destroy() {
PrefsHelper.removeObserver(prefObserverId);
}
public void setLayerView(LayerView layerView) {
ThreadUtils.assertOnUiThread();
this.layerView = layerView;
}
public void setEnabledChangedListener(OnEnabledChangedListener listener) {
ThreadUtils.assertOnUiThread();
enabledChangedListener = listener;
}
public void onSaveInstanceState(Bundle outState) {
ThreadUtils.assertOnUiThread();
outState.putBoolean(STATE_ENABLED, prefEnabled);
}
public void onRestoreInstanceState(Bundle savedInstanceState) {
ThreadUtils.assertOnUiThread();
if (savedInstanceState != null) {
prefEnabled = savedInstanceState.getBoolean(STATE_ENABLED);
}
}
public boolean isEnabled() {
ThreadUtils.assertOnUiThread();
if (forceDisabled) {
return false;
}
return prefEnabled && !accessibilityEnabled;
}
public void setAccessibilityEnabled(boolean enabled) {
ThreadUtils.assertOnUiThread();
if (accessibilityEnabled == enabled) {
return;
}
// Disable the dynamic toolbar when accessibility features are enabled,
// and re-read the preference when they're disabled.
accessibilityEnabled = enabled;
if (prefEnabled) {
triggerEnabledListener();
}
}
public void setVisible(boolean visible, VisibilityTransition transition) {
ThreadUtils.assertOnUiThread();
if (layerView == null) {
return;
}
// Don't hide the ActionBar/Toolbar, if it's pinned open by TextSelection.
if (visible == false && pinFlags.contains(PinReason.ACTION_MODE)) {
return;
}
final boolean isImmediate = transition == VisibilityTransition.IMMEDIATE;
if (visible) {
layerView.getDynamicToolbarAnimator().showToolbar(isImmediate);
} else {
layerView.getDynamicToolbarAnimator().hideToolbar(isImmediate);
}
}
public void setTemporarilyVisible(boolean visible, VisibilityTransition transition) {
ThreadUtils.assertOnUiThread();
if (layerView == null) {
return;
}
if (visible == temporarilyVisible) {
// nothing to do
return;
}
temporarilyVisible = visible;
final boolean isImmediate = transition == VisibilityTransition.IMMEDIATE;
if (visible) {
layerView.getDynamicToolbarAnimator().showToolbar(isImmediate);
} else {
layerView.getDynamicToolbarAnimator().hideToolbar(isImmediate);
}
}
public void persistTemporaryVisibility() {
ThreadUtils.assertOnUiThread();
if (temporarilyVisible) {
temporarilyVisible = false;
setVisible(true, VisibilityTransition.IMMEDIATE);
}
}
public void setPinned(boolean pinned, PinReason reason) {
ThreadUtils.assertOnUiThread();
if (layerView == null) {
return;
}
if (pinned) {
pinFlags.add(reason);
} else {
pinFlags.remove(reason);
}
layerView.getDynamicToolbarAnimator().setPinned(!pinFlags.isEmpty());
}
private void triggerEnabledListener() {
if (enabledChangedListener != null) {
enabledChangedListener.onEnabledChanged(isEnabled());
}
}
private class PrefHandler extends PrefHandlerBase {
@Override
public void prefValue(String pref, boolean value) {
if (value == prefEnabled) {
return;
}
prefEnabled = value;
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
// If accessibility is enabled, the dynamic toolbar is
// forced to be off.
if (!accessibilityEnabled) {
triggerEnabledListener();
}
}
});
}
@Override
public boolean isObserver() {
// We want to be notified of changes to be able to switch mode
// without restarting.
return true;
}
}
}