Backed out changeset 486a6b3af95b (bug 942862) for bustage on android and windows builds on a CLOSED TREE

This commit is contained in:
Carsten "Tomcat" Book 2014-01-09 12:40:14 +01:00
parent cad598d059
commit 6d727701ba
9 changed files with 422 additions and 679 deletions

View File

@ -1418,13 +1418,12 @@ abstract public class BrowserApp extends GeckoApp
int id = Favicons.getFaviconForSize(tab.getURL(), tab.getFaviconURL(), tabFaviconSize, flags, sFaviconLoadedListener);
tab.setFaviconLoadId(id);
final Tabs tabs = Tabs.getInstance();
if (id != Favicons.LOADED && tabs.isSelectedTab(tab)) {
if (id != Favicons.LOADED &&
Tabs.getInstance().isSelectedTab(tab)) {
// We're loading the current tab's favicon from somewhere
// other than the cache. Display the globe favicon until then.
tab.updateFavicon(Favicons.sDefaultFavicon);
tabs.notifyListeners(tab, Tabs.TabEvents.FAVICON);
// other than the cache.
// Display the globe favicon until then.
mBrowserToolbar.showDefaultFavicon();
}
}

View File

@ -313,7 +313,6 @@ gbjar.sources += [
'toolbar/ShapedButton.java',
'toolbar/SiteIdentityPopup.java',
'toolbar/TabCounter.java',
'toolbar/ToolbarDisplayLayout.java',
'toolbar/ToolbarEditLayout.java',
'toolbar/ToolbarEditText.java',
'TouchEventInterceptor.java',

View File

@ -69,10 +69,58 @@
android:layout_toRightOf="@id/back"
android:layout_toLeftOf="@id/menu_items"/>
<org.mozilla.gecko.toolbar.ToolbarDisplayLayout android:id="@+id/display_layout"
<LinearLayout android:id="@+id/url_display_container"
style="@style/UrlBar.Button.Container"
android:layout_toRightOf="@id/back"
android:layout_toLeftOf="@id/menu_items"/>
android:layout_toLeftOf="@id/menu_items">
<ImageButton android:id="@+id/favicon"
style="@style/UrlBar.ImageButton"
android:layout_width="@dimen/browser_toolbar_favicon_size"
android:layout_height="fill_parent"
android:scaleType="fitCenter"
android:layout_marginLeft="4dip"
android:paddingLeft="4dip"
android:paddingRight="4dip"
android:layout_gravity="center_vertical"
android:src="@drawable/favicon"/>
<ImageButton android:id="@+id/site_security"
style="@style/UrlBar.ImageButton"
android:layout_width="@dimen/browser_toolbar_lock_width"
android:scaleType="fitCenter"
android:layout_marginLeft="-4dip"
android:src="@drawable/site_security_level"
android:contentDescription="@string/site_security"
android:visibility="gone"/>
<org.mozilla.gecko.widget.GeckoTextView android:id="@+id/url_bar_title"
style="@style/UrlBar.Button"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1.0"
android:singleLine="true"
android:paddingRight="8dp"
android:textColor="@color/url_bar_title"
android:textColorHint="@color/url_bar_title_hint"
android:gravity="center_vertical|left"
android:layout_gravity="center_vertical"
gecko:autoUpdateTheme="false"/>
<org.mozilla.gecko.toolbar.PageActionLayout android:id="@+id/page_action_layout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginRight="@dimen/browser_toolbar_button_padding"
android:visibility="gone"
android:orientation="horizontal"/>
<ImageButton android:id="@+id/stop"
style="@style/UrlBar.ImageButton.Icon"
android:src="@drawable/urlbar_stop"
android:contentDescription="@string/stop"
android:visibility="gone"/>
</LinearLayout>
<LinearLayout android:id="@+id/menu_items"
android:layout_width="wrap_content"

View File

@ -93,10 +93,59 @@
android:paddingLeft="8dp"
android:visibility="gone"/>
<org.mozilla.gecko.toolbar.ToolbarDisplayLayout android:id="@+id/display_layout"
<LinearLayout android:id="@+id/url_display_container"
style="@style/UrlBar.Button"
android:layout_toLeftOf="@id/tabs"
android:layout_marginRight="-24dp"/>
android:layout_marginRight="-24dp"
android:orientation="horizontal">
<ImageButton android:id="@+id/favicon"
style="@style/UrlBar.ImageButton"
android:layout_width="@dimen/browser_toolbar_favicon_size"
android:layout_height="fill_parent"
android:scaleType="fitCenter"
android:layout_marginLeft="8dip"
android:paddingLeft="4dip"
android:paddingRight="4dip"
android:layout_gravity="center_vertical"/>
<ImageButton android:id="@+id/site_security"
style="@style/UrlBar.ImageButton"
android:layout_width="@dimen/browser_toolbar_lock_width"
android:scaleType="fitCenter"
android:layout_marginLeft="-4dip"
android:src="@drawable/site_security_level"
android:contentDescription="@string/site_security"
android:visibility="gone"/>
<org.mozilla.gecko.widget.GeckoTextView android:id="@+id/url_bar_title"
style="@style/UrlBar.Button"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1.0"
android:singleLine="true"
android:paddingRight="8dp"
android:textColor="@color/url_bar_title"
android:textColorHint="@color/url_bar_title_hint"
android:gravity="center_vertical|left"
android:hint="@string/url_bar_default_text"
android:layout_gravity="center_vertical"
gecko:autoUpdateTheme="false"/>
<org.mozilla.gecko.toolbar.PageActionLayout android:id="@+id/page_action_layout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginRight="12dp"
android:visibility="gone"
android:orientation="horizontal"/>
<ImageButton android:id="@+id/stop"
style="@style/UrlBar.ImageButton.Icon"
android:src="@drawable/urlbar_stop"
android:contentDescription="@string/stop"
android:visibility="gone"/>
</LinearLayout>
<ImageView android:id="@+id/shadow"
android:layout_width="fill_parent"

View File

@ -1,55 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:gecko="http://schemas.android.com/apk/res-auto">
<ImageButton android:id="@+id/favicon"
style="@style/UrlBar.ImageButton"
android:layout_width="@dimen/browser_toolbar_favicon_size"
android:layout_height="fill_parent"
android:scaleType="fitCenter"
android:layout_marginLeft="8dip"
android:paddingLeft="4dip"
android:paddingRight="4dip"
android:layout_gravity="center_vertical"/>
<ImageButton android:id="@+id/site_security"
style="@style/UrlBar.ImageButton"
android:layout_width="@dimen/browser_toolbar_lock_width"
android:scaleType="fitCenter"
android:layout_marginLeft="-4dip"
android:src="@drawable/site_security_level"
android:contentDescription="@string/site_security"
android:visibility="gone"/>
<org.mozilla.gecko.widget.GeckoTextView android:id="@+id/url_bar_title"
style="@style/UrlBar.Button"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1.0"
android:singleLine="true"
android:paddingRight="8dp"
android:textColor="@color/url_bar_title"
android:textColorHint="@color/url_bar_title_hint"
android:gravity="center_vertical|left"
android:hint="@string/url_bar_default_text"
android:layout_gravity="center_vertical"
gecko:autoUpdateTheme="false"/>
<org.mozilla.gecko.toolbar.PageActionLayout android:id="@+id/page_action_layout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginRight="@dimen/browser_toolbar_button_padding"
android:visibility="gone"
android:orientation="horizontal"/>
<ImageButton android:id="@+id/stop"
style="@style/UrlBar.ImageButton.Icon"
android:src="@drawable/urlbar_stop"
android:contentDescription="@string/stop"
android:visibility="gone"/>
</merge>

View File

@ -59,8 +59,8 @@ public class ToolbarComponent extends BaseComponent {
return (EditText) getToolbarView().findViewById(R.id.url_edit_text);
}
private View getUrlDisplayLayout() {
return getToolbarView().findViewById(R.id.display_layout);
private View getUrlDisplayContainer() {
return getToolbarView().findViewById(R.id.url_display_container);
}
private TextView getUrlTitleText() {
@ -106,7 +106,7 @@ public class ToolbarComponent extends BaseComponent {
}
private boolean isEditing() {
return getUrlDisplayLayout().getVisibility() != View.VISIBLE &&
return getUrlDisplayContainer().getVisibility() != View.VISIBLE &&
getUrlEditText().getVisibility() == View.VISIBLE;
}

View File

@ -12,6 +12,7 @@ import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoProfile;
import org.mozilla.gecko.LightweightTheme;
import org.mozilla.gecko.R;
import org.mozilla.gecko.SiteIdentity;
import org.mozilla.gecko.SiteIdentity.SecurityMode;
import org.mozilla.gecko.Tab;
import org.mozilla.gecko.Tabs;
@ -29,6 +30,7 @@ import org.mozilla.gecko.util.StringUtils;
import org.mozilla.gecko.widget.GeckoImageButton;
import org.mozilla.gecko.widget.GeckoImageView;
import org.mozilla.gecko.widget.GeckoRelativeLayout;
import org.mozilla.gecko.widget.GeckoTextView;
import org.json.JSONObject;
@ -38,6 +40,7 @@ import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.os.Build;
import android.os.SystemClock;
import android.text.style.ForegroundColorSpan;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
@ -53,7 +56,11 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.AlphaAnimation;
import android.view.animation.Interpolator;
import android.view.animation.TranslateAnimation;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.ImageButton;
@ -62,12 +69,12 @@ import android.widget.LinearLayout;
import android.widget.PopupWindow;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
public class BrowserToolbar extends GeckoRelativeLayout
implements Tabs.OnTabsChangedListener,
GeckoMenu.ActionItemBarPresenter,
Animation.AnimationListener,
GeckoEventListener {
private static final String LOGTAG = "GeckoToolbar";
public static final String PREF_TITLEBAR_MODE = "browser.chrome.titlebarMode";
@ -97,26 +104,37 @@ public class BrowserToolbar extends GeckoRelativeLayout
public void onStopEditing();
}
enum ForwardButtonAnimation {
private enum ForwardButtonAnimation {
SHOW,
HIDE
}
private ToolbarDisplayLayout mUrlDisplayLayout;
private View mUrlDisplayContainer;
private ToolbarEditLayout mUrlEditLayout;
private View mUrlBarEntry;
private ImageView mUrlBarRightEdge;
private GeckoTextView mTitle;
private int mTitlePadding;
private boolean mSiteSecurityVisible;
private boolean mSwitchingTabs;
private ShapedButton mTabs;
private ImageButton mBack;
private ImageButton mForward;
private ImageButton mStop;
// To de-bounce sets.
private Bitmap mLastFavicon;
private ImageButton mFavicon;
private ImageButton mSiteSecurity;
private PageActionLayout mPageActionLayout;
private Animation mProgressSpinner;
private TabCounter mTabsCounter;
private GeckoImageButton mMenu;
private GeckoImageView mMenuIcon;
private LinearLayout mActionItemBar;
private MenuPopup mMenuPopup;
private List<View> mFocusOrder;
private List<? extends View> mFocusOrder;
private OnActivateListener mActivateListener;
private OnCommitListener mCommitListener;
@ -125,14 +143,26 @@ public class BrowserToolbar extends GeckoRelativeLayout
private OnStartEditingListener mStartEditingListener;
private OnStopEditingListener mStopEditingListener;
private SiteIdentityPopup mSiteIdentityPopup;
final private BrowserApp mActivity;
private boolean mHasSoftMenuButton;
private boolean mShowSiteSecurity;
private boolean mSpinnerVisible;
private boolean mIsEditing;
private boolean mAnimatingEntry;
private AlphaAnimation mLockFadeIn;
private TranslateAnimation mTitleSlideLeft;
private TranslateAnimation mTitleSlideRight;
private int mUrlBarViewOffset;
private int mDefaultForwardMargin;
private PropertyAnimator mForwardAnim = null;
private int mFaviconSize;
private static final Interpolator sButtonsInterpolator = new AccelerateInterpolator();
@ -230,11 +260,13 @@ public class BrowserToolbar extends GeckoRelativeLayout
registerEventListener("Reader:Click");
registerEventListener("Reader:LongClick");
mShowSiteSecurity = false;
mAnimatingEntry = false;
mUrlBarViewOffset = res.getDimensionPixelSize(R.dimen.url_bar_offset_left);
mDefaultForwardMargin = res.getDimensionPixelSize(R.dimen.forward_default_offset);
mUrlDisplayLayout = (ToolbarDisplayLayout) findViewById(R.id.display_layout);
mUrlDisplayContainer = findViewById(R.id.url_display_container);
mUrlBarEntry = findViewById(R.id.url_bar_entry);
mUrlEditLayout = (ToolbarEditLayout) findViewById(R.id.edit_layout);
@ -244,6 +276,9 @@ public class BrowserToolbar extends GeckoRelativeLayout
mUrlBarRightEdge.getDrawable().setLevel(6000);
}
mTitle = (GeckoTextView) findViewById(R.id.url_bar_title);
mTitlePadding = mTitle.getPaddingRight();
mTabs = (ShapedButton) findViewById(R.id.tabs);
mTabsCounter = (TabCounter) findViewById(R.id.tabs_counter);
@ -252,6 +287,26 @@ public class BrowserToolbar extends GeckoRelativeLayout
mForward = (ImageButton) findViewById(R.id.forward);
setButtonEnabled(mForward, false);
mFavicon = (ImageButton) findViewById(R.id.favicon);
if (Build.VERSION.SDK_INT >= 11) {
if (Build.VERSION.SDK_INT >= 16) {
mFavicon.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
}
mFavicon.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
mFaviconSize = Math.round(res.getDimension(R.dimen.browser_toolbar_favicon_size));
mSiteSecurity = (ImageButton) findViewById(R.id.site_security);
mSiteSecurityVisible = (mSiteSecurity.getVisibility() == View.VISIBLE);
mSiteIdentityPopup = new SiteIdentityPopup(mActivity);
mSiteIdentityPopup.setAnchor(mSiteSecurity);
mProgressSpinner = AnimationUtils.loadAnimation(mActivity, R.anim.progress_spinner);
mStop = (ImageButton) findViewById(R.id.stop);
mPageActionLayout = (PageActionLayout) findViewById(R.id.page_action_layout);
mMenu = (GeckoImageButton) findViewById(R.id.menu);
mMenuIcon = (GeckoImageView) findViewById(R.id.menu_icon);
mActionItemBar = (LinearLayout) findViewById(R.id.menu_items);
@ -259,15 +314,12 @@ public class BrowserToolbar extends GeckoRelativeLayout
// We use different layouts on phones and tablets, so adjust the focus
// order appropriately.
mFocusOrder = new ArrayList<View>();
if (HardwareUtils.isTablet()) {
mFocusOrder.addAll(Arrays.asList(mTabs, mBack, mForward, this));
mFocusOrder.addAll(mUrlDisplayLayout.getFocusOrder());
mFocusOrder.addAll(Arrays.asList(mActionItemBar, mMenu));
mFocusOrder = Arrays.asList(mTabs, mBack, mForward, this,
mSiteSecurity, mPageActionLayout, mStop, mActionItemBar, mMenu);
} else {
mFocusOrder.add(this);
mFocusOrder.addAll(mUrlDisplayLayout.getFocusOrder());
mFocusOrder.addAll(Arrays.asList(mTabs, mMenu));
mFocusOrder = Arrays.asList(this, mSiteSecurity, mPageActionLayout, mStop,
mTabs, mMenu);
}
setIsEditing(false);
@ -368,6 +420,58 @@ public class BrowserToolbar extends GeckoRelativeLayout
}
});
Button.OnClickListener faviconListener = new Button.OnClickListener() {
@Override
public void onClick(View view) {
if (mSiteSecurity.getVisibility() != View.VISIBLE)
return;
final Tab tab = Tabs.getInstance().getSelectedTab();
final SiteIdentity siteIdentity = tab.getSiteIdentity();
if (siteIdentity.getSecurityMode() == SecurityMode.UNKNOWN) {
Log.e(LOGTAG, "Selected tab has no identity data");
return;
}
mSiteIdentityPopup.updateIdentity(siteIdentity);
mSiteIdentityPopup.show();
}
};
mFavicon.setOnClickListener(faviconListener);
mSiteSecurity.setOnClickListener(faviconListener);
mStop.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
Tab tab = Tabs.getInstance().getSelectedTab();
if (tab != null)
tab.doStop();
setProgressVisibility(false);
}
});
float slideWidth = getResources().getDimension(R.dimen.browser_toolbar_lock_width);
LinearLayout.LayoutParams siteSecParams = (LinearLayout.LayoutParams) mSiteSecurity.getLayoutParams();
final float scale = getResources().getDisplayMetrics().density;
slideWidth += (siteSecParams.leftMargin + siteSecParams.rightMargin) * scale + 0.5f;
mLockFadeIn = new AlphaAnimation(0.0f, 1.0f);
mLockFadeIn.setAnimationListener(this);
mTitleSlideLeft = new TranslateAnimation(slideWidth, 0, 0, 0);
mTitleSlideLeft.setAnimationListener(this);
mTitleSlideRight = new TranslateAnimation(-slideWidth, 0, 0, 0);
mTitleSlideRight.setAnimationListener(this);
final int lockAnimDuration = 300;
mLockFadeIn.setDuration(lockAnimDuration);
mTitleSlideLeft.setDuration(lockAnimDuration);
mTitleSlideRight.setDuration(lockAnimDuration);
if (mHasSoftMenuButton) {
mMenu.setVisibility(View.VISIBLE);
mMenuIcon.setVisibility(View.VISIBLE);
@ -382,11 +486,11 @@ public class BrowserToolbar extends GeckoRelativeLayout
}
public void refresh() {
mUrlDisplayLayout.dismissSiteIdentityPopup();
dismissSiteIdentityPopup();
}
public boolean onBackPressed() {
return mUrlDisplayLayout.dismissSiteIdentityPopup();
return dismissSiteIdentityPopup();
}
public boolean onKey(int keyCode, KeyEvent event) {
@ -465,7 +569,7 @@ public class BrowserToolbar extends GeckoRelativeLayout
case RESTORED:
// TabCount fixup after OOM
case SELECTED:
mUrlDisplayLayout.dismissSiteIdentityPopup();
dismissSiteIdentityPopup();
updateTabCount(tabs.getDisplayCount());
mSwitchingTabs = true;
// Fall through.
@ -484,7 +588,7 @@ public class BrowserToolbar extends GeckoRelativeLayout
setProgressVisibility(true);
}
setSecurityMode(tab.getSecurityMode());
setPageActionVisibility(mUrlDisplayLayout.isShowingProgress());
setPageActionVisibility(mStop.getVisibility() == View.VISIBLE);
break;
case STOP:
@ -520,7 +624,7 @@ public class BrowserToolbar extends GeckoRelativeLayout
break;
case READER_ENABLED:
setPageActionVisibility(mUrlDisplayLayout.isShowingProgress());
setPageActionVisibility(mStop.getVisibility() == View.VISIBLE);
break;
}
}
@ -537,16 +641,55 @@ public class BrowserToolbar extends GeckoRelativeLayout
return ViewHelper.getTranslationY(this) == 0;
}
@Override
public void setNextFocusDownId(int nextId) {
super.setNextFocusDownId(nextId);
mTabs.setNextFocusDownId(nextId);
mBack.setNextFocusDownId(nextId);
mForward.setNextFocusDownId(nextId);
mUrlDisplayLayout.setNextFocusDownId(nextId);
mFavicon.setNextFocusDownId(nextId);
mStop.setNextFocusDownId(nextId);
mSiteSecurity.setNextFocusDownId(nextId);
mPageActionLayout.setNextFocusDownId(nextId);
mMenu.setNextFocusDownId(nextId);
}
@Override
public void onAnimationStart(Animation animation) {
if (animation.equals(mLockFadeIn)) {
if (mSiteSecurityVisible)
mSiteSecurity.setVisibility(View.VISIBLE);
} else if (animation.equals(mTitleSlideLeft)) {
// These two animations may be scheduled to start while the forward
// animation is occurring. If we're showing the site security icon, make
// sure it doesn't take any space during the forward transition.
mSiteSecurity.setVisibility(View.GONE);
} else if (animation.equals(mTitleSlideRight)) {
// If we're hiding the icon, make sure that we keep its padding
// in place during the forward transition
mSiteSecurity.setVisibility(View.INVISIBLE);
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
if (animation.equals(mTitleSlideRight)) {
mSiteSecurity.startAnimation(mLockFadeIn);
}
}
private boolean dismissSiteIdentityPopup() {
if (mSiteIdentityPopup != null && mSiteIdentityPopup.isShowing()) {
mSiteIdentityPopup.dismiss();
return true;
}
return false;
}
private int getUrlBarEntryTranslation() {
return getWidth() - mUrlBarEntry.getRight();
}
@ -630,14 +773,85 @@ public class BrowserToolbar extends GeckoRelativeLayout
}
public void setProgressVisibility(boolean visible) {
mUrlDisplayLayout.setProgressVisibility(visible);
Log.d(LOGTAG, "setProgressVisibility: " + visible);
// The "Throbber start" and "Throbber stop" log messages in this method
// are needed by S1/S2 tests (http://mrcote.info/phonedash/#).
// See discussion in Bug 804457. Bug 805124 tracks paring these down.
if (visible) {
mFavicon.setImageResource(R.drawable.progress_spinner);
mLastFavicon = null;
// To stop the glitch caused by multiple start() calls.
if (!mSpinnerVisible) {
setPageActionVisibility(true);
mFavicon.setAnimation(mProgressSpinner);
mProgressSpinner.start();
mSpinnerVisible = true;
}
Log.i(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - Throbber start");
} else {
Tab selectedTab = Tabs.getInstance().getSelectedTab();
if (selectedTab != null) {
setFavicon(selectedTab.getFavicon());
}
if (mSpinnerVisible) {
setPageActionVisibility(false);
mFavicon.setAnimation(null);
mProgressSpinner.cancel();
mSpinnerVisible = false;
}
Log.i(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - Throbber stop");
}
}
public void setPageActionVisibility(boolean isLoading) {
mUrlDisplayLayout.setPageActionVisibility(isLoading, !mSwitchingTabs);
// Handle the loading mode page actions
mStop.setVisibility(isLoading ? View.VISIBLE : View.GONE);
// Handle the viewing mode page actions
setSiteSecurityVisibility(mShowSiteSecurity && !isLoading);
mPageActionLayout.setVisibility(!isLoading ? View.VISIBLE : View.GONE);
// We want title to fill the whole space available for it when there are icons
// being shown on the right side of the toolbar as the icons already have some
// padding in them. This is just to avoid wasting space when icons are shown.
mTitle.setPadding(0, 0, (!isLoading ? mTitlePadding : 0), 0);
updateFocusOrder();
}
private void setSiteSecurityVisibility(final boolean visible) {
if (visible == mSiteSecurityVisible)
return;
mSiteSecurityVisible = visible;
if (mSwitchingTabs) {
mSiteSecurity.setVisibility(visible ? View.VISIBLE : View.GONE);
return;
}
mTitle.clearAnimation();
mSiteSecurity.clearAnimation();
// If any of these animations were cancelled as a result of the
// clearAnimation() calls above, we need to reset them.
mLockFadeIn.reset();
mTitleSlideLeft.reset();
mTitleSlideRight.reset();
if (mForwardAnim != null) {
long delay = mForwardAnim.getRemainingTime();
mTitleSlideRight.setStartOffset(delay);
mTitleSlideLeft.setStartOffset(delay);
} else {
mTitleSlideRight.setStartOffset(0);
mTitleSlideLeft.setStartOffset(0);
}
mTitle.startAnimation(visible ? mTitleSlideRight : mTitleSlideLeft);
}
private void updateFocusOrder() {
View prevView = null;
@ -686,16 +900,8 @@ public class BrowserToolbar extends GeckoRelativeLayout
}
public void setTitle(CharSequence title) {
mUrlDisplayLayout.setTitle(title);
final String contentDescription;
if (title != null) {
contentDescription = title.toString();
} else {
contentDescription = mActivity.getString(R.string.url_bar_default_text);
}
setContentDescription(contentDescription);
mTitle.setText(title);
setContentDescription(title != null ? title : mTitle.getHint());
}
// Sets the toolbar title according to the selected tab, obeying the mShowUrl preference.
@ -752,17 +958,37 @@ public class BrowserToolbar extends GeckoRelativeLayout
setTitle(title);
}
public void showDefaultFavicon() {
mFavicon.setImageResource(R.drawable.favicon);
mLastFavicon = null;
}
private void setFavicon(Bitmap image) {
Log.d(LOGTAG, "setFavicon(" + image + ")");
if (Tabs.getInstance().getSelectedTab().getState() == Tab.STATE_LOADING) {
return;
}
mUrlDisplayLayout.setFavicon(image);
}
if (image == mLastFavicon) {
Log.d(LOGTAG, "Ignoring favicon set: new favicon is identical to previous favicon.");
return;
}
mLastFavicon = image; // Cache the original so we can debounce without scaling.
if (image != null) {
image = Bitmap.createScaledBitmap(image, mFaviconSize, mFaviconSize, false);
mFavicon.setImageBitmap(image);
} else {
mFavicon.setImageDrawable(null);
}
}
private void setSecurityMode(SecurityMode mode) {
mUrlDisplayLayout.setSecurityMode(mode);
mSiteSecurity.setImageLevel(mode.ordinal());
mShowSiteSecurity = (mode != SecurityMode.UNKNOWN);
setPageActionVisibility(mStop.getVisibility() == View.VISIBLE);
}
public void prepareTabsAnimation(PropertyAnimator animator, boolean tabsAreShown) {
@ -856,8 +1082,8 @@ public class BrowserToolbar extends GeckoRelativeLayout
}
private void setUrlEditLayoutVisibility(final boolean showEditLayout, PropertyAnimator animator) {
final View viewToShow = (showEditLayout ? mUrlEditLayout : mUrlDisplayLayout);
final View viewToHide = (showEditLayout ? mUrlDisplayLayout : mUrlEditLayout);
final View viewToShow = (showEditLayout ? mUrlEditLayout : mUrlDisplayContainer);
final View viewToHide = (showEditLayout ? mUrlDisplayContainer : mUrlEditLayout);
if (showEditLayout) {
mUrlEditLayout.prepareShowAnimation(animator);
@ -998,7 +1224,9 @@ public class BrowserToolbar extends GeckoRelativeLayout
// Highlight the toolbar from the start of the animation.
setSelected(true);
mUrlDisplayLayout.prepareStartEditingAnimation();
// Hide page actions/stop buttons immediately
ViewHelper.setAlpha(mPageActionLayout, 0);
ViewHelper.setAlpha(mStop, 0);
// Slide the right side elements of the toolbar
@ -1147,7 +1375,16 @@ public class BrowserToolbar extends GeckoRelativeLayout
}
PropertyAnimator buttonsAnimator = new PropertyAnimator(300);
mUrlDisplayLayout.prepareStopEditingAnimation(buttonsAnimator);
// Fade toolbar buttons (page actions, stop) after the entry
// is schrunk back to its original size.
buttonsAnimator.attach(mPageActionLayout,
PropertyAnimator.Property.ALPHA,
1);
buttonsAnimator.attach(mStop,
PropertyAnimator.Property.ALPHA,
1);
buttonsAnimator.start();
mAnimatingEntry = false;
@ -1197,18 +1434,17 @@ public class BrowserToolbar extends GeckoRelativeLayout
}
// We want the forward button to show immediately when switching tabs
final PropertyAnimator forwardAnim =
new PropertyAnimator(mSwitchingTabs ? 10 : FORWARD_ANIMATION_DURATION);
mForwardAnim = new PropertyAnimator(mSwitchingTabs ? 10 : FORWARD_ANIMATION_DURATION);
final int width = mForward.getWidth() / 2;
forwardAnim.addPropertyAnimationListener(new PropertyAnimator.PropertyAnimationListener() {
mForwardAnim.addPropertyAnimationListener(new PropertyAnimator.PropertyAnimationListener() {
@Override
public void onPropertyAnimationStart() {
if (!showing) {
// Set the margin before the transition when hiding the forward button. We
// have to do this so that the favicon isn't clipped during the transition
MarginLayoutParams layoutParams =
(MarginLayoutParams) mUrlDisplayLayout.getLayoutParams();
(MarginLayoutParams) mUrlDisplayContainer.getLayoutParams();
layoutParams.leftMargin = 0;
// Do the same on the URL edit container
@ -1226,25 +1462,28 @@ public class BrowserToolbar extends GeckoRelativeLayout
public void onPropertyAnimationEnd() {
if (showing) {
MarginLayoutParams layoutParams =
(MarginLayoutParams) mUrlDisplayLayout.getLayoutParams();
(MarginLayoutParams) mUrlDisplayContainer.getLayoutParams();
layoutParams.leftMargin = mUrlBarViewOffset;
layoutParams = (MarginLayoutParams) mUrlEditLayout.getLayoutParams();
layoutParams.leftMargin = mUrlBarViewOffset;
}
mUrlDisplayLayout.finishForwardAnimation();
ViewHelper.setTranslationX(mTitle, 0);
ViewHelper.setTranslationX(mFavicon, 0);
ViewHelper.setTranslationX(mSiteSecurity, 0);
}
MarginLayoutParams layoutParams = (MarginLayoutParams) mForward.getLayoutParams();
layoutParams.leftMargin = mDefaultForwardMargin + (showing ? width : 0);
ViewHelper.setTranslationX(mForward, 0);
requestLayout();
mForwardAnim = null;
}
});
prepareForwardAnimation(forwardAnim, animation, width);
forwardAnim.start();
prepareForwardAnimation(mForwardAnim, animation, width);
mForwardAnim.start();
}
public void updateForwardButton(Tab tab) {
@ -1266,7 +1505,22 @@ public class BrowserToolbar extends GeckoRelativeLayout
anim.attach(mForward,
PropertyAnimator.Property.ALPHA,
0);
anim.attach(mTitle,
PropertyAnimator.Property.TRANSLATION_X,
0);
anim.attach(mFavicon,
PropertyAnimator.Property.TRANSLATION_X,
0);
anim.attach(mSiteSecurity,
PropertyAnimator.Property.TRANSLATION_X,
0);
// We're hiding the forward button. We're going to reset the margin before
// the animation starts, so we shift these items to the right so that they don't
// appear to move initially.
ViewHelper.setTranslationX(mTitle, mUrlBarViewOffset);
ViewHelper.setTranslationX(mFavicon, mUrlBarViewOffset);
ViewHelper.setTranslationX(mSiteSecurity, mUrlBarViewOffset);
} else {
anim.attach(mForward,
PropertyAnimator.Property.TRANSLATION_X,
@ -1274,9 +1528,16 @@ public class BrowserToolbar extends GeckoRelativeLayout
anim.attach(mForward,
PropertyAnimator.Property.ALPHA,
1);
anim.attach(mTitle,
PropertyAnimator.Property.TRANSLATION_X,
mUrlBarViewOffset);
anim.attach(mFavicon,
PropertyAnimator.Property.TRANSLATION_X,
mUrlBarViewOffset);
anim.attach(mSiteSecurity,
PropertyAnimator.Property.TRANSLATION_X,
mUrlBarViewOffset);
}
mUrlDisplayLayout.prepareForwardAnimation(anim, animation, width);
}
@Override
@ -1304,16 +1565,16 @@ public class BrowserToolbar extends GeckoRelativeLayout
setFavicon(tab.getFavicon());
setProgressVisibility(tab.getState() == Tab.STATE_LOADING);
setSecurityMode(tab.getSecurityMode());
setPageActionVisibility(mUrlDisplayLayout.isShowingProgress());
setPageActionVisibility(mStop.getVisibility() == View.VISIBLE);
updateBackButton(tab);
updateForwardButton(tab);
final boolean isPrivate = tab.isPrivate();
setPrivateMode(isPrivate);
mTabs.setPrivateMode(isPrivate);
mTitle.setPrivateMode(isPrivate);
mMenu.setPrivateMode(isPrivate);
mMenuIcon.setPrivateMode(isPrivate);
mUrlDisplayLayout.setPrivateMode(isPrivate);
mUrlEditLayout.setPrivateMode(isPrivate);
if (mBack instanceof BackButton)
@ -1325,7 +1586,7 @@ public class BrowserToolbar extends GeckoRelativeLayout
}
public View getDoorHangerAnchor() {
return mUrlDisplayLayout.getDoorHangerAnchor();
return mFavicon;
}
public void onDestroy() {

View File

@ -1,400 +0,0 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.toolbar;
import org.mozilla.gecko.animation.PropertyAnimator;
import org.mozilla.gecko.animation.ViewHelper;
import org.mozilla.gecko.BrowserApp;
import org.mozilla.gecko.R;
import org.mozilla.gecko.SiteIdentity;
import org.mozilla.gecko.SiteIdentity.SecurityMode;
import org.mozilla.gecko.Tab;
import org.mozilla.gecko.Tabs;
import org.mozilla.gecko.toolbar.BrowserToolbar.ForwardButtonAnimation;
import org.mozilla.gecko.widget.GeckoLinearLayout;
import org.mozilla.gecko.widget.GeckoTextView;
import org.json.JSONObject;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.AlphaAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.LinearLayout.LayoutParams;
import java.util.Arrays;
import java.util.List;
public class ToolbarDisplayLayout extends GeckoLinearLayout
implements Animation.AnimationListener {
private static final String LOGTAG = "GeckoToolbarDisplayLayout";
final private BrowserApp mActivity;
private GeckoTextView mTitle;
private int mTitlePadding;
private ImageButton mSiteSecurity;
private boolean mSiteSecurityVisible;
private boolean mShowSiteSecurity;
// To de-bounce sets.
private Bitmap mLastFavicon;
private ImageButton mFavicon;
private int mFaviconSize;
private ImageButton mStop;
private PageActionLayout mPageActionLayout;
private Animation mProgressSpinner;
private boolean mSpinnerVisible;
private AlphaAnimation mLockFadeIn;
private TranslateAnimation mTitleSlideLeft;
private TranslateAnimation mTitleSlideRight;
private SiteIdentityPopup mSiteIdentityPopup;
private PropertyAnimator mForwardAnim;
public ToolbarDisplayLayout(Context context, AttributeSet attrs) {
super(context, attrs);
setOrientation(HORIZONTAL);
mActivity = (BrowserApp) context;
LayoutInflater.from(context).inflate(R.layout.toolbar_display_layout, this);
mTitle = (GeckoTextView) findViewById(R.id.url_bar_title);
mTitlePadding = mTitle.getPaddingRight();
Resources res = getResources();
mFavicon = (ImageButton) findViewById(R.id.favicon);
if (Build.VERSION.SDK_INT >= 11) {
if (Build.VERSION.SDK_INT >= 16) {
mFavicon.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
}
mFavicon.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
mFaviconSize = Math.round(res.getDimension(R.dimen.browser_toolbar_favicon_size));
mShowSiteSecurity = false;
mSiteSecurity = (ImageButton) findViewById(R.id.site_security);
mSiteSecurityVisible = (mSiteSecurity.getVisibility() == View.VISIBLE);
mSiteIdentityPopup = new SiteIdentityPopup(mActivity);
mSiteIdentityPopup.setAnchor(mSiteSecurity);
mProgressSpinner = AnimationUtils.loadAnimation(mActivity, R.anim.progress_spinner);
mStop = (ImageButton) findViewById(R.id.stop);
mPageActionLayout = (PageActionLayout) findViewById(R.id.page_action_layout);
}
@Override
public void onAttachedToWindow() {
Button.OnClickListener faviconListener = new Button.OnClickListener() {
@Override
public void onClick(View view) {
if (mSiteSecurity.getVisibility() != View.VISIBLE)
return;
final Tab tab = Tabs.getInstance().getSelectedTab();
final SiteIdentity siteIdentity = tab.getSiteIdentity();
if (siteIdentity.getSecurityMode() == SecurityMode.UNKNOWN) {
Log.e(LOGTAG, "Selected tab has no identity data");
return;
}
mSiteIdentityPopup.updateIdentity(siteIdentity);
mSiteIdentityPopup.show();
}
};
mFavicon.setOnClickListener(faviconListener);
mSiteSecurity.setOnClickListener(faviconListener);
mStop.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
Tab tab = Tabs.getInstance().getSelectedTab();
if (tab != null)
tab.doStop();
setProgressVisibility(false);
}
});
float slideWidth = getResources().getDimension(R.dimen.browser_toolbar_lock_width);
LayoutParams siteSecParams = (LayoutParams) mSiteSecurity.getLayoutParams();
final float scale = getResources().getDisplayMetrics().density;
slideWidth += (siteSecParams.leftMargin + siteSecParams.rightMargin) * scale + 0.5f;
mLockFadeIn = new AlphaAnimation(0.0f, 1.0f);
mLockFadeIn.setAnimationListener(this);
mTitleSlideLeft = new TranslateAnimation(slideWidth, 0, 0, 0);
mTitleSlideLeft.setAnimationListener(this);
mTitleSlideRight = new TranslateAnimation(-slideWidth, 0, 0, 0);
mTitleSlideRight.setAnimationListener(this);
final int lockAnimDuration = 300;
mLockFadeIn.setDuration(lockAnimDuration);
mTitleSlideLeft.setDuration(lockAnimDuration);
mTitleSlideRight.setDuration(lockAnimDuration);
}
@Override
public void setPrivateMode(boolean isPrivate) {
super.setPrivateMode(isPrivate);
mTitle.setPrivateMode(isPrivate);
}
@Override
public void onAnimationStart(Animation animation) {
if (animation.equals(mLockFadeIn)) {
if (mSiteSecurityVisible)
mSiteSecurity.setVisibility(View.VISIBLE);
} else if (animation.equals(mTitleSlideLeft)) {
// These two animations may be scheduled to start while the forward
// animation is occurring. If we're showing the site security icon, make
// sure it doesn't take any space during the forward transition.
mSiteSecurity.setVisibility(View.GONE);
} else if (animation.equals(mTitleSlideRight)) {
// If we're hiding the icon, make sure that we keep its padding
// in place during the forward transition
mSiteSecurity.setVisibility(View.INVISIBLE);
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
if (animation.equals(mTitleSlideRight)) {
mSiteSecurity.startAnimation(mLockFadeIn);
}
}
@Override
public void setNextFocusDownId(int nextId) {
mFavicon.setNextFocusDownId(nextId);
mStop.setNextFocusDownId(nextId);
mSiteSecurity.setNextFocusDownId(nextId);
mPageActionLayout.setNextFocusDownId(nextId);
}
void updateFromTab(Tab tab) {
}
List<View> getFocusOrder() {
return Arrays.asList(mSiteSecurity, mPageActionLayout, mStop);
}
void setTitle(CharSequence title) {
mTitle.setText(title);
}
void setProgressVisibility(boolean visible) {
Log.d(LOGTAG, "setProgressVisibility: " + visible);
// The "Throbber start" and "Throbber stop" log messages in this method
// are needed by S1/S2 tests (http://mrcote.info/phonedash/#).
// See discussion in Bug 804457. Bug 805124 tracks paring these down.
if (visible) {
mFavicon.setImageResource(R.drawable.progress_spinner);
mLastFavicon = null;
//To stop the glitch caused by mutiple start() calls.
if (!mSpinnerVisible) {
setPageActionVisibility(true);
mFavicon.setAnimation(mProgressSpinner);
mProgressSpinner.start();
mSpinnerVisible = true;
}
Log.i(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - Throbber start");
} else {
Tab selectedTab = Tabs.getInstance().getSelectedTab();
if (selectedTab != null)
setFavicon(selectedTab.getFavicon());
if (mSpinnerVisible) {
setPageActionVisibility(false);
mFavicon.setAnimation(null);
mProgressSpinner.cancel();
mSpinnerVisible = false;
}
Log.i(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - Throbber stop");
}
}
void setFavicon(Bitmap image) {
if (image == mLastFavicon) {
Log.d(LOGTAG, "Ignoring favicon set: new favicon is identical to previous favicon.");
return;
}
mLastFavicon = image; // Cache the original so we can debounce without scaling.
if (image != null) {
image = Bitmap.createScaledBitmap(image, mFaviconSize, mFaviconSize, false);
mFavicon.setImageBitmap(image);
} else {
mFavicon.setImageDrawable(null);
}
}
private void setSiteSecurityVisibility(final boolean visible, boolean animate) {
if (visible == mSiteSecurityVisible)
return;
mSiteSecurityVisible = visible;
if (animate) {
mSiteSecurity.setVisibility(visible ? View.VISIBLE : View.GONE);
return;
}
mTitle.clearAnimation();
mSiteSecurity.clearAnimation();
// If any of these animations were cancelled as a result of the
// clearAnimation() calls above, we need to reset them.
mLockFadeIn.reset();
mTitleSlideLeft.reset();
mTitleSlideRight.reset();
if (mForwardAnim != null) {
long delay = mForwardAnim.getRemainingTime();
mTitleSlideRight.setStartOffset(delay);
mTitleSlideLeft.setStartOffset(delay);
} else {
mTitleSlideRight.setStartOffset(0);
mTitleSlideLeft.setStartOffset(0);
}
mTitle.startAnimation(visible ? mTitleSlideRight : mTitleSlideLeft);
}
void setPageActionVisibility(boolean isLoading) {
setPageActionVisibility(isLoading, true);
}
void setPageActionVisibility(boolean isLoading, boolean animate) {
// Handle the loading mode page actions
mStop.setVisibility(isLoading ? View.VISIBLE : View.GONE);
// Handle the viewing mode page actions
setSiteSecurityVisibility(mShowSiteSecurity && !isLoading, animate);
mPageActionLayout.setVisibility(!isLoading ? View.VISIBLE : View.GONE);
// We want title to fill the whole space available for it when there are icons
// being shown on the right side of the toolbar as the icons already have some
// padding in them. This is just to avoid wasting space when icons are shown.
mTitle.setPadding(0, 0, (!isLoading ? mTitlePadding : 0), 0);
}
void setSecurityMode(SecurityMode mode) {
mSiteSecurity.setImageLevel(mode.ordinal());
mShowSiteSecurity = (mode != SecurityMode.UNKNOWN);
setPageActionVisibility(mStop.getVisibility() == View.VISIBLE);
}
boolean isShowingProgress() {
return mSpinnerVisible;
}
View getDoorHangerAnchor() {
return mFavicon;
}
void prepareForwardAnimation(PropertyAnimator anim, ForwardButtonAnimation animation, int width) {
mForwardAnim = anim;
if (animation == ForwardButtonAnimation.HIDE) {
anim.attach(mTitle,
PropertyAnimator.Property.TRANSLATION_X,
0);
anim.attach(mFavicon,
PropertyAnimator.Property.TRANSLATION_X,
0);
anim.attach(mSiteSecurity,
PropertyAnimator.Property.TRANSLATION_X,
0);
// We're hiding the forward button. We're going to reset the margin before
// the animation starts, so we shift these items to the right so that they don't
// appear to move initially.
ViewHelper.setTranslationX(mTitle, width);
ViewHelper.setTranslationX(mFavicon, width);
ViewHelper.setTranslationX(mSiteSecurity, width);
} else {
anim.attach(mTitle,
PropertyAnimator.Property.TRANSLATION_X,
width);
anim.attach(mFavicon,
PropertyAnimator.Property.TRANSLATION_X,
width);
anim.attach(mSiteSecurity,
PropertyAnimator.Property.TRANSLATION_X,
width);
}
}
void finishForwardAnimation() {
ViewHelper.setTranslationX(mTitle, 0);
ViewHelper.setTranslationX(mFavicon, 0);
ViewHelper.setTranslationX(mSiteSecurity, 0);
mForwardAnim = null;
}
void prepareStartEditingAnimation() {
// Hide page actions/stop buttons immediately
ViewHelper.setAlpha(mPageActionLayout, 0);
ViewHelper.setAlpha(mStop, 0);
}
void prepareStopEditingAnimation(PropertyAnimator anim) {
// Fade toolbar buttons (page actions, stop) after the entry
// is schrunk back to its original size.
anim.attach(mPageActionLayout,
PropertyAnimator.Property.ALPHA,
1);
anim.attach(mStop,
PropertyAnimator.Property.ALPHA,
1);
}
boolean dismissSiteIdentityPopup() {
if (mSiteIdentityPopup != null && mSiteIdentityPopup.isShowing()) {
mSiteIdentityPopup.dismiss();
return true;
}
return false;
}
}

View File

@ -1,158 +0,0 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.widget;
import org.mozilla.gecko.menu.MenuItemActionView;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.view.ActionProvider;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.SubMenu;
import android.view.View;
import android.view.View.OnClickListener;
public class GeckoActionProvider extends ActionProvider {
/**
* A listener to know when a target was selected.
* When setting a provider, the activity can listen to this,
* to close the menu.
*/
public interface OnTargetSelectedListener {
public void onTargetSelected();
}
private final Context mContext;
public static final String DEFAULT_HISTORY_FILE_NAME = "history.xml";
// History file.
private String mHistoryFileName = DEFAULT_HISTORY_FILE_NAME;
private OnTargetSelectedListener mOnTargetListener;
private final Callbacks mCallbacks = new Callbacks();
public GeckoActionProvider(Context context) {
super(context);
mContext = context;
}
@Override
public View onCreateActionView() {
// Create the view and set its data model.
ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mHistoryFileName);
MenuItemActionView view = new MenuItemActionView(mContext, null);
view.setActionButtonClickListener(mCallbacks);
final PackageManager packageManager = mContext.getPackageManager();
int historySize = dataModel.getDistinctActivityCountInHistory();
if (historySize > 2) {
historySize = 2;
}
// Historical data is dependent on past selection of activities.
// Activity count is determined by the number of activities that can handle
// the particular intent. When no intent is set, the activity count is 0,
// while the history count can be a valid number.
if (historySize > dataModel.getActivityCount()) {
return view;
}
for (int i = 0; i < historySize; i++) {
view.addActionButton(dataModel.getActivity(i).loadIcon(packageManager));
}
return view;
}
public View getView() {
return onCreateActionView();
}
@Override
public boolean hasSubMenu() {
return true;
}
@Override
public void onPrepareSubMenu(SubMenu subMenu) {
// Clear since the order of items may change.
subMenu.clear();
ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mHistoryFileName);
PackageManager packageManager = mContext.getPackageManager();
// Populate the sub-menu with a sub set of the activities.
final int count = dataModel.getActivityCount();
for (int i = 0; i < count; i++) {
ResolveInfo activity = dataModel.getActivity(i);
subMenu.add(0, i, i, activity.loadLabel(packageManager))
.setIcon(activity.loadIcon(packageManager))
.setOnMenuItemClickListener(mCallbacks);
}
}
public void setHistoryFileName(String historyFile) {
mHistoryFileName = historyFile;
}
public Intent getIntent() {
ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mHistoryFileName);
return dataModel.getIntent();
}
public void setIntent(Intent intent) {
ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mHistoryFileName);
dataModel.setIntent(intent);
// Inform the target listener to refresh it's UI, if needed.
if (mOnTargetListener != null) {
mOnTargetListener.onTargetSelected();
}
}
public void setOnTargetSelectedListener(OnTargetSelectedListener listener) {
mOnTargetListener = listener;
}
/**
* Listener for handling default activity / menu item clicks.
*/
private class Callbacks implements OnMenuItemClickListener,
OnClickListener {
private void chooseActivity(int index) {
ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mHistoryFileName);
Intent launchIntent = dataModel.chooseActivity(index);
if (launchIntent != null) {
launchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
mContext.startActivity(launchIntent);
}
if (mOnTargetListener != null) {
mOnTargetListener.onTargetSelected();
}
}
@Override
public boolean onMenuItemClick(MenuItem item) {
chooseActivity(item.getItemId());
return true;
}
@Override
public void onClick(View view) {
Integer index = (Integer) view.getTag();
ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mHistoryFileName);
chooseActivity(index);
}
}
}