blob: 6d6163cdd1aa70a579d0fc667adcdceec83c94d7 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.offlinepages.indicator;
import android.app.Activity;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import org.chromium.base.ActivityState;
import org.chromium.base.ApplicationStatus;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager.FullscreenListener;
import org.chromium.chrome.browser.snackbar.Snackbar;
/**
* Manager for one-off snackbar showing at the top of activity.
*/
public class TopSnackbarManager
implements OnClickListener, ApplicationStatus.ActivityStateListener, FullscreenListener {
private final Handler mDismissSnackbarHandler;
private final Runnable mDismissSnackbarRunnable = new Runnable() {
@Override
public void run() {
dismissSnackbar(false);
}
};
private Activity mActivity;
private Snackbar mSnackbar;
private TopSnackbarView mSnackbarView;
public TopSnackbarManager() {
mDismissSnackbarHandler = new Handler();
}
@Override
public void onClick(View v) {
dismissSnackbar(true);
}
@Override
public void onActivityStateChange(Activity activity, int newState) {
if (newState == ActivityState.PAUSED || newState == ActivityState.STOPPED) {
dismissSnackbar(false);
}
}
@Override
public void onControlsOffsetChanged(int topOffset, int bottomOffset, boolean needsAnimate) {
// When the top toolbar offset changes, dismiss the top snackbar. Ideally we want to move
// the top snackbar together with the top toolbar, but they can't be made sync because they
// are drawn in different layers (C++ vs Android native).
dismissSnackbar(false);
}
@Override
public void onBottomControlsHeightChanged(int bottomControlsHeight) {}
@Override
public void onContentOffsetChanged(int offset) {}
@Override
public void onToggleOverlayVideoMode(boolean enabled) {}
/**
* Shows a snackbar at the top of the given activity.
*/
public void show(Snackbar snackbar, Activity activity) {
if (mSnackbar != null) return;
@ActivityState
int state = ApplicationStatus.getStateForActivity(activity);
if (state != ActivityState.STARTED && state != ActivityState.RESUMED) return;
mActivity = activity;
mSnackbar = snackbar;
mSnackbarView = new TopSnackbarView(activity, this, mSnackbar, null);
mSnackbarView.show();
mSnackbarView.announceforAccessibility();
mDismissSnackbarHandler.removeCallbacks(mDismissSnackbarRunnable);
mDismissSnackbarHandler.postDelayed(mDismissSnackbarRunnable, mSnackbar.getDuration());
if (activity instanceof ChromeActivity) {
ChromeActivity chromeActivity = (ChromeActivity) activity;
chromeActivity.getFullscreenManager().addListener(this);
}
ApplicationStatus.registerStateListenerForActivity(this, activity);
}
/**
* Dismisses the snackbar if it is shown.
*/
public void hide() {
dismissSnackbar(false);
}
private void dismissSnackbar(boolean byAction) {
if (mSnackbar == null) return;
if (byAction) {
mSnackbar.getController().onAction(null);
} else {
mSnackbar.getController().onDismissNoAction(null);
}
ApplicationStatus.unregisterActivityStateListener(this);
if (mActivity instanceof ChromeActivity) {
ChromeActivity chromeActivity = (ChromeActivity) mActivity;
chromeActivity.getFullscreenManager().removeListener(this);
}
mDismissSnackbarHandler.removeCallbacks(mDismissSnackbarRunnable);
if (mSnackbarView != null) {
mSnackbarView.dismiss();
mSnackbarView = null;
}
mSnackbar = null;
}
@VisibleForTesting
boolean isShowing() {
return mSnackbar != null;
}
}