// Copyright 2013 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.infobar; import android.content.Context; import android.graphics.Bitmap; import android.view.View; import android.widget.TextView; import org.chromium.base.annotations.CalledByNative; import org.chromium.chrome.R; import org.chromium.chrome.browser.tab.Tab; /** * The base class for all InfoBar classes. * Note that infobars expire by default when a new navigation occurs. * Make sure to use setExpireOnNavigation(false) if you want an infobar to be sticky. */ public abstract class InfoBar implements InfoBarView { private static final String TAG = "InfoBar"; private final int mIconDrawableId; private final Bitmap mIconBitmap; private final CharSequence mMessage; private InfoBarContainer mContainer; private View mView; private Context mContext; private boolean mIsDismissed; private boolean mControlsEnabled = true; // This points to the InfoBarAndroid class not any of its subclasses. private long mNativeInfoBarPtr; /** * @param iconDrawableId ID of the resource to use for the Icon. If 0, no icon will be shown. * @param message The message to show in the infobar. */ public InfoBar(int iconDrawableId, Bitmap iconBitmap, CharSequence message) { mIconDrawableId = iconDrawableId; mIconBitmap = iconBitmap; mMessage = message; } /** * Stores a pointer to the native-side counterpart of this InfoBar. * @param nativeInfoBarPtr Pointer to the native InfoBarAndroid, not to its subclass. */ @CalledByNative private void setNativeInfoBar(long nativeInfoBarPtr) { assert mNativeInfoBarPtr == 0; mNativeInfoBarPtr = nativeInfoBarPtr; } @CalledByNative protected void onNativeDestroyed() { mNativeInfoBarPtr = 0; } /** * Sets the Context used when creating the InfoBar. */ protected void setContext(Context context) { mContext = context; } /** * @return The Context used to create the InfoBar. This will be null until the InfoBar is added * to the InfoBarContainer, and should never be null afterward. */ protected Context getContext() { return mContext; } /** * Creates the View that represents the InfoBar. * @return The View representing the InfoBar. */ protected final View createView() { assert mContext != null; InfoBarLayout layout = new InfoBarLayout(mContext, this, mIconDrawableId, mIconBitmap, mMessage); createContent(layout); layout.onContentCreated(); mView = layout; return mView; } /** * Replaces the View currently shown in the infobar with the given View. Triggers the swap * animation via the InfoBarContainer. */ protected void replaceView(View newView) { mView = newView; mContainer.notifyInfoBarViewChanged(); } /** * Called when the given tab has been reparented. */ public void onTabReparented(Tab tab) { } /** * Returns the View shown in this infobar. Only valid after createView() has been called. */ @Override public View getView() { return mView; } @Override public CharSequence getAccessibilityText() { if (mView == null) return ""; TextView messageView = (TextView) mView.findViewById(R.id.infobar_message); if (messageView == null) return ""; return messageView.getText() + mContext.getString(R.string.bottom_bar_screen_position); } /** * @return whether the infobar actually needed closing. */ @CalledByNative private boolean closeInfoBar() { if (!mIsDismissed) { mIsDismissed = true; if (!mContainer.hasBeenDestroyed()) { // If the container was destroyed, it's already been emptied of all its infobars. mContainer.removeInfoBar(this); } return true; } return false; } long getNativeInfoBarPtr() { return mNativeInfoBarPtr; } void setInfoBarContainer(InfoBarContainer container) { mContainer = container; } @Override public boolean areControlsEnabled() { return mControlsEnabled; } @Override public void setControlsEnabled(boolean state) { mControlsEnabled = state; } @Override public void onButtonClicked(boolean isPrimaryButton) { } @Override public void onLinkClicked() { if (mNativeInfoBarPtr != 0) nativeOnLinkClicked(mNativeInfoBarPtr); } /** * Performs some action related to the button being clicked. * @param action The type of action defined as ACTION_* in this class. */ protected void onButtonClicked(int action) { if (mNativeInfoBarPtr != 0) nativeOnButtonClicked(mNativeInfoBarPtr, action); } @Override public void onCloseButtonClicked() { if (mNativeInfoBarPtr != 0) nativeOnCloseButtonClicked(mNativeInfoBarPtr); } @Override public void createContent(InfoBarLayout layout) { } private native void nativeOnLinkClicked(long nativeInfoBarAndroid); private native void nativeOnButtonClicked(long nativeInfoBarAndroid, int action); private native void nativeOnCloseButtonClicked(long nativeInfoBarAndroid); }