Bug 1173887 - Only display one title + favicon for the first doorhanger in a popup. r=ally, a=Kwierso
authorChenxia Liu <liuche@mozilla.com>
Tue, 16 Jun 2015 14:03:09 -0700
changeset 249943 2137ce8f916f5ca486e5b69a4a14e8b1cceddb1d
parent 249942 8c6f31ca0635206c4473a9812401dc428dc49190
child 249944 95dc0052f4102c241163005987b8616964941a4c
push id61393
push usercbook@mozilla.com
push dateMon, 22 Jun 2015 12:44:45 +0000
treeherdermozilla-inbound@4b47c3f074a3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersally, Kwierso
bugs1173887
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1173887 - Only display one title + favicon for the first doorhanger in a popup. r=ally, a=Kwierso
mobile/android/base/DoorHangerPopup.java
mobile/android/base/resources/layout/doorhanger.xml
mobile/android/base/resources/layout/login_doorhanger.xml
mobile/android/base/resources/layout/login_edit_dialog.xml
mobile/android/base/resources/layout/site_identity.xml
mobile/android/base/resources/values/dimens.xml
mobile/android/base/toolbar/SiteIdentityPopup.java
mobile/android/base/widget/DefaultDoorHanger.java
mobile/android/base/widget/DoorHanger.java
mobile/android/base/widget/LoginDoorHanger.java
mobile/android/base/widget/SiteLogins.java
mobile/android/chrome/content/browser.js
mobile/android/components/LoginManagerPrompter.js
--- a/mobile/android/base/DoorHangerPopup.java
+++ b/mobile/android/base/DoorHangerPopup.java
@@ -272,37 +272,45 @@ public class DoorHangerPopup extends Anc
         if (tab == null || mDoorHangers.size() == 0 || !mInflated || mDisabled) {
             dismiss();
             return;
         }
 
         // Show doorhangers for the selected tab
         int tabId = tab.getId();
         boolean shouldShowPopup = false;
+        DoorHanger firstDoorhanger = null;
         for (DoorHanger dh : mDoorHangers) {
             if (dh.getTabId() == tabId) {
                 dh.setVisibility(View.VISIBLE);
                 shouldShowPopup = true;
+                if (firstDoorhanger == null) {
+                    firstDoorhanger = dh;
+                } else {
+                    dh.hideTitle();
+                }
             } else {
                 dh.setVisibility(View.GONE);
             }
         }
- 
+
         // Dismiss the popup if there are no doorhangers to show for this tab
         if (!shouldShowPopup) {
             dismiss();
             return;
         }
 
         showDividers();
         if (isShowing()) {
             show();
             return;
         }
 
+        firstDoorhanger.showTitle(tab.getFavicon(), tab.getBaseDomain());
+
         // Make the popup focusable for accessibility. This gets done here
         // so the node can be accessibility focused, but on pre-ICS devices this
         // causes crashes, so it is done after the popup is shown.
         if (Versions.feature14Plus) {
             setFocusable(true);
         }
 
         show();
--- a/mobile/android/base/resources/layout/doorhanger.xml
+++ b/mobile/android/base/resources/layout/doorhanger.xml
@@ -3,28 +3,41 @@
    - 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">
 
     <LinearLayout android:layout_width="match_parent"
                   android:layout_height="wrap_content"
                   android:orientation="horizontal"
-                  android:padding="@dimen/doorhanger_padding">
+                  android:padding="@dimen/doorhanger_section_padding_small">
 
         <ImageView android:id="@+id/doorhanger_icon"
                    android:layout_width="@dimen/doorhanger_icon_size"
                    android:layout_height="@dimen/doorhanger_icon_size"
                    android:layout_gravity="center_horizontal"
                    android:paddingRight="@dimen/doorhanger_section_padding_small"
                    android:visibility="gone"/>
 
-        <ViewStub android:id="@+id/content"
-                  android:layout_width="match_parent"
-                  android:layout_height="wrap_content"/>
+        <LinearLayout android:layout_width="match_parent"
+                      android:layout_height="wrap_content"
+                      android:orientation="vertical">
+
+            <TextView android:id="@+id/doorhanger_title"
+                      android:layout_width="match_parent"
+                      android:layout_height="wrap_content"
+                      android:layout_marginBottom="@dimen/doorhanger_section_padding_small"
+                      android:textAppearance="@style/TextAppearance.DoorHanger.Medium.Light"
+                      android:visibility="gone"/>
+
+            <ViewStub android:id="@+id/content"
+                      android:layout_width="match_parent"
+                      android:layout_height="wrap_content"/>
+
+        </LinearLayout>
 
     </LinearLayout>
 
     <LinearLayout android:layout_width="match_parent"
                   android:layout_height="wrap_content"
                   android:orientation="horizontal">
 
         <Button android:id="@+id/doorhanger_button_negative"
--- a/mobile/android/base/resources/layout/login_doorhanger.xml
+++ b/mobile/android/base/resources/layout/login_doorhanger.xml
@@ -3,22 +3,16 @@
    - 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/. -->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:orientation="vertical">
 
-    <TextView android:id="@+id/doorhanger_title"
-              android:layout_width="match_parent"
-              android:layout_height="wrap_content"
-              android:layout_marginBottom="@dimen/doorhanger_section_padding_small"
-              android:textAppearance="@style/TextAppearance.DoorHanger.Medium.Light"/>
-
     <TextView android:id="@+id/doorhanger_message"
               android:focusable="true"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:layout_marginBottom="@dimen/doorhanger_section_padding_large"
               android:textAppearance="@style/TextAppearance.DoorHanger.Medium"/>
 
     <TextView android:id="@+id/doorhanger_link"
--- a/mobile/android/base/resources/layout/login_edit_dialog.xml
+++ b/mobile/android/base/resources/layout/login_edit_dialog.xml
@@ -1,17 +1,17 @@
 <?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/. -->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
-              android:padding="@dimen/doorhanger_padding"
+              android:padding="@dimen/doorhanger_section_padding_small"
               android:orientation="vertical">
 
     <EditText android:id="@+id/username_edit"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:inputType="textNoSuggestions"
               android:hint="@string/doorhanger_login_edit_username_hint"/>
 
@@ -20,11 +20,11 @@
               android:layout_height="wrap_content"
               android:inputType="textPassword"
               android:hint="@string/doorhanger_login_edit_password_hint"/>
 
     <CheckBox android:id="@+id/checkbox_toggle_password"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:text="@string/doorhanger_login_edit_toggle"
-              android:layout_marginTop="@dimen/doorhanger_padding"/>
+              android:layout_marginTop="@dimen/doorhanger_subsection_padding"/>
 
 </LinearLayout>
--- a/mobile/android/base/resources/layout/site_identity.xml
+++ b/mobile/android/base/resources/layout/site_identity.xml
@@ -6,23 +6,23 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:orientation="vertical">
 
     <LinearLayout android:layout_width="match_parent"
                   android:layout_height="wrap_content"
                   android:orientation="horizontal"
-                  android:padding="@dimen/doorhanger_padding">
+                  android:padding="@dimen/doorhanger_section_padding_small">
 
         <ImageView android:id="@+id/larry"
                    android:layout_width="@dimen/doorhanger_icon_size"
                    android:layout_height="@dimen/doorhanger_icon_size"
                    android:src="@drawable/larry"
-                   android:paddingRight="@dimen/doorhanger_padding"/>
+                   android:paddingRight="@dimen/doorhanger_section_padding_small"/>
 
         <LinearLayout android:layout_width="0dp"
                      android:layout_height="wrap_content"
                      android:orientation="vertical"
                      android:layout_weight="1.0">
 
             <include layout="@layout/site_identity_unknown" />
 
@@ -30,17 +30,17 @@
                           android:layout_width="match_parent"
                           android:layout_height="wrap_content"
                           android:visibility="gone"
                           android:orientation="vertical">
 
                 <TextView android:id="@+id/site_identity_title"
                           android:layout_width="match_parent"
                           android:layout_height="wrap_content"
-                          android:layout_marginBottom="@dimen/doorhanger_section_padding_small"
+                          android:layout_marginBottom="@dimen/doorhanger_subsection_padding"
                           android:textAppearance="@style/TextAppearance.DoorHanger.Medium.Light"/>
 
                 <TextView android:id="@+id/site_identity_encrypted"
                           android:layout_width="match_parent"
                           android:layout_height="wrap_content"
                           android:layout_marginBottom="@dimen/doorhanger_section_padding_small"
                           android:textAppearance="@style/TextAppearance.DoorHanger.Medium.Bold"
                           android:textColor="@color/affirmative_green"
@@ -78,17 +78,17 @@
 
             </LinearLayout>
             <TextView android:id="@+id/site_settings_link"
                       android:layout_width="match_parent"
                       android:layout_height="wrap_content"
                       android:textAppearance="@style/TextAppearance.DoorHanger.Medium"
                       android:textColor="@color/link_blue"
                       android:layout_marginTop="@dimen/doorhanger_section_padding_large"
-                      android:layout_marginBottom="@dimen/doorhanger_padding"
+                      android:layout_marginBottom="@dimen/doorhanger_section_padding_small"
                       android:text="@string/contextmenu_site_settings"
                       android:visibility="gone"/>
          </LinearLayout>
     </LinearLayout>
 
     <View android:id="@+id/divider_doorhanger"
           android:layout_width="match_parent"
           android:layout_height="1dp"
--- a/mobile/android/base/resources/values/dimens.xml
+++ b/mobile/android/base/resources/values/dimens.xml
@@ -97,21 +97,21 @@
     <dimen name="search_row_height">48dp</dimen>
 
     <!-- Padding at the top of the site identity popup, when no identity data is available. -->
     <dimen name="identity_padding_top">5dp</dimen>
 
     <dimen name="doorhanger_width">300dp</dimen>
     <dimen name="doorhanger_input_width">250dp</dimen>
     <dimen name="doorhanger_spinner_textsize">9sp</dimen>
-    <dimen name="doorhanger_padding">15dp</dimen>
     <dimen name="doorhanger_offsetX">12dp</dimen>
     <dimen name="doorhanger_offsetY">67dp</dimen>
     <dimen name="doorhanger_GB_offsetY">7dp</dimen>
     <dimen name="doorhanger_drawable_padding">5dp</dimen>
+    <dimen name="doorhanger_subsection_padding">8dp</dimen>
     <dimen name="doorhanger_section_padding_small">20dp</dimen>
     <dimen name="doorhanger_section_padding_large">30dp</dimen>
     <dimen name="doorhanger_icon_size">60dp</dimen>
 
     <dimen name="context_menu_item_horizontal_padding">10dp</dimen>
 
     <dimen name="flow_layout_spacing">6dp</dimen>
     <dimen name="menu_item_icon">21dp</dimen>
--- a/mobile/android/base/toolbar/SiteIdentityPopup.java
+++ b/mobile/android/base/toolbar/SiteIdentityPopup.java
@@ -3,33 +3,33 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.toolbar;
 
 import android.content.ClipData;
 import android.content.ClipboardManager;
 import android.graphics.Bitmap;
 import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.widget.ImageView;
 import android.widget.Toast;
 import org.json.JSONException;
 import org.json.JSONArray;
 import org.mozilla.gecko.AboutPages;
 import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.EventDispatcher;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.GeckoEvent;
 import org.mozilla.gecko.SiteIdentity;
 import org.mozilla.gecko.SiteIdentity.SecurityMode;
 import org.mozilla.gecko.SiteIdentity.MixedMode;
 import org.mozilla.gecko.SiteIdentity.TrackingMode;
 import org.mozilla.gecko.Tab;
 import org.mozilla.gecko.Tabs;
-import org.mozilla.gecko.favicons.Favicons;
-import org.mozilla.gecko.favicons.OnFaviconLoadedListener;
 import org.mozilla.gecko.util.GeckoEventListener;
 import org.mozilla.gecko.util.ThreadUtils;
 import org.mozilla.gecko.widget.AnchoredPopup;
 import org.mozilla.gecko.widget.DoorHanger;
 import org.mozilla.gecko.widget.DoorHanger.OnButtonClickListener;
 import org.json.JSONObject;
 
 import android.content.Context;
@@ -169,20 +169,19 @@ public class SiteIdentityPopup extends A
                 public void run() {
                     mSiteSettingsLink.setVisibility(hasPermissions ? View.VISIBLE : View.GONE);
                 }
             });
         }
     }
 
     private void addLoginsToTab(JSONObject data) throws JSONException {
-        final JSONObject titleObj = data.getJSONObject("title");
         final JSONArray logins = data.getJSONArray("logins");
 
-        final SiteLogins siteLogins = new SiteLogins(titleObj, logins);
+        final SiteLogins siteLogins = new SiteLogins(logins);
         Tabs.getInstance().getSelectedTab().setSiteLogins(siteLogins);
     }
 
     private void addSelectLoginDoorhanger(Tab tab) throws JSONException {
         final SiteLogins siteLogins = tab.getSiteLogins();
         if (siteLogins == null) {
             return;
         }
@@ -236,18 +235,16 @@ public class SiteIdentityPopup extends A
             username = mContext.getString(R.string.doorhanger_login_no_username);
         }
 
         final String message = mContext.getString(R.string.doorhanger_login_select_message).replace(FORMAT_S, username);
         config.setMessage(message);
 
         // Set options.
         final JSONObject options = new JSONObject();
-        final JSONObject titleObj = siteLogins.getTitle();
-        options.put("title", titleObj);
 
         // Add action text only if there are other logins to select.
         if (logins.length() > 1) {
 
             final JSONObject actionText = new JSONObject();
             actionText.put("type", "SELECT");
 
             final JSONObject bundle = new JSONObject();
@@ -288,33 +285,16 @@ public class SiteIdentityPopup extends A
             mIdentityUnknownContainer.setVisibility(View.GONE);
         } else {
             mIdentityKnownContainer.setVisibility(View.GONE);
             mIdentityUnknownContainer.setVisibility(View.VISIBLE);
         }
     }
 
     private void updateIdentityInformation(final SiteIdentity siteIdentity) {
-        final String host = siteIdentity.getHost();
-        mTitle.setText(host);
-
-        final String hostUrl = siteIdentity.getOrigin();
-        Favicons.getSizedFaviconForPageFromLocal(mContext, hostUrl, 32, new OnFaviconLoadedListener() {
-            @Override
-            public void onFaviconLoaded(String url, String faviconURL, Bitmap favicon) {
-                if (favicon == null) {
-                    // If there is no favicon, clear the compound drawable.
-                    mTitle.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
-                } else {
-                    mTitle.setCompoundDrawablesWithIntrinsicBounds(new BitmapDrawable(mContext.getResources(), favicon), null, null, null);
-                    mTitle.setCompoundDrawablePadding((int) mContext.getResources().getDimension(R.dimen.doorhanger_drawable_padding));
-                }
-            }
-        });
-
         mEncrypted.setVisibility(siteIdentity.getEncrypted() ? View.VISIBLE : View.GONE);
 
         mHost.setText(siteIdentity.getHost());
 
         String owner = siteIdentity.getOwner();
         if (owner == null) {
             mOwnerLabel.setVisibility(View.GONE);
             mOwner.setVisibility(View.GONE);
@@ -446,16 +426,23 @@ public class SiteIdentityPopup extends A
         }
 
         try {
             addSelectLoginDoorhanger(selectedTab);
         } catch (JSONException e) {
             Log.e(LOGTAG, "Error adding selectLogin doorhanger", e);
         }
 
+        mTitle.setText(selectedTab.getBaseDomain());
+        final Bitmap favicon = selectedTab.getFavicon();
+        if (favicon != null) {
+            mTitle.setCompoundDrawablesWithIntrinsicBounds(new BitmapDrawable(mContext.getResources(), favicon), null, null, null);
+            mTitle.setCompoundDrawablePadding((int) mContext.getResources().getDimension(R.dimen.doorhanger_drawable_padding));
+        }
+
         showDividers();
 
         super.show();
     }
 
     // Show the right dividers
     private void showDividers() {
         final int count = mContent.getChildCount();
@@ -486,16 +473,17 @@ public class SiteIdentityPopup extends A
     }
 
     @Override
     public void dismiss() {
         super.dismiss();
         removeMixedContentNotification();
         removeTrackingContentNotification();
         removeSelectLoginDoorhanger();
+        mTitle.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
         mDivider.setVisibility(View.GONE);
     }
 
     private class ContentNotificationButtonListener implements OnButtonClickListener {
         @Override
         public void onButtonClick(JSONObject response, DoorHanger doorhanger) {
             GeckoEvent e = GeckoEvent.createBroadcastEvent("Session:Reload", response.toString());
             GeckoAppShell.sendEventToGecko(e);
--- a/mobile/android/base/widget/DefaultDoorHanger.java
+++ b/mobile/android/base/widget/DefaultDoorHanger.java
@@ -104,17 +104,17 @@ public class DefaultDoorHanger extends D
             final ViewGroup group = (ViewGroup) findViewById(R.id.doorhanger_inputs);
             group.setVisibility(VISIBLE);
 
             for (int i = 0; i < inputs.length(); i++) {
                 try {
                     PromptInput input = PromptInput.getInput(inputs.getJSONObject(i));
                     mInputs.add(input);
 
-                    final int padding = mResources.getDimensionPixelSize(R.dimen.doorhanger_padding);
+                    final int padding = mResources.getDimensionPixelSize(R.dimen.doorhanger_section_padding_small);
                     View v = input.getView(getContext());
                     styleInput(input, v);
                     v.setPadding(0, 0, 0, padding);
                     group.addView(v);
                 } catch(JSONException ex) { }
             }
         }
 
@@ -193,17 +193,17 @@ public class DefaultDoorHanger extends D
         mMessage.setText(titleWithLink);
         mMessage.setMovementMethod(LinkMovementMethod.getInstance());
     }
 
     private void styleInput(PromptInput input, View view) {
         if (input instanceof PromptInput.MenulistInput) {
             styleDropdownInputs(input, view);
         }
-        view.setPadding(0, 0, 0, mResources.getDimensionPixelSize(R.dimen.doorhanger_padding));
+        view.setPadding(0, 0, 0, mResources.getDimensionPixelSize(R.dimen.doorhanger_subsection_padding));
     }
 
     private void styleDropdownInputs(PromptInput input, View view) {
         PromptInput.MenulistInput spinInput = (PromptInput.MenulistInput) input;
 
         if (spinInput.textView != null) {
             spinInput.textView.setTextColor(sSpinnerTextColor);
         }
--- a/mobile/android/base/widget/DoorHanger.java
+++ b/mobile/android/base/widget/DoorHanger.java
@@ -2,24 +2,29 @@
  * 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 android.content.Context;
 import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewStub;
 import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
+import android.widget.TextView;
 import org.json.JSONObject;
 import org.mozilla.gecko.R;
+import org.mozilla.gecko.Tabs;
 
 public abstract class DoorHanger extends LinearLayout {
 
     public static DoorHanger Get(Context context, DoorhangerConfig config) {
         final Type type = config.getType();
         switch (type) {
             case LOGIN:
                 return new LoginDoorHanger(context, config);
@@ -49,16 +54,17 @@ public abstract class DoorHanger extends
     private final int mTabId;
 
     // DoorHanger identifier.
     private final String mIdentifier;
 
     protected final Type mType;
 
     protected final ImageView mIcon;
+    protected final TextView mDoorhangerTitle;
 
     protected final Context mContext;
     protected final Resources mResources;
 
     protected int mDividerColor;
 
     protected boolean mPersistWhileVisible;
     protected int mPersistenceCount;
@@ -73,16 +79,17 @@ public abstract class DoorHanger extends
         mIdentifier = config.getId();
         mType = type;
 
         LayoutInflater.from(context).inflate(R.layout.doorhanger, this);
         setOrientation(VERTICAL);
 
         mDivider = findViewById(R.id.divider_doorhanger);
         mIcon = (ImageView) findViewById(R.id.doorhanger_icon);
+        mDoorhangerTitle = (TextView) findViewById(R.id.doorhanger_title);
 
         mNegativeButton = (Button) findViewById(R.id.doorhanger_button_negative);
         mPositiveButton = (Button) findViewById(R.id.doorhanger_button_positive);
         mOnButtonClickListener = config.getButtonClickListener();
 
         mDividerColor = mResources.getColor(R.color.divider_light);
 
         final ViewStub contentStub = (ViewStub) findViewById(R.id.content);
@@ -170,9 +177,22 @@ public abstract class DoorHanger extends
         }
 
         if (System.currentTimeMillis() <= mTimeout) {
             return false;
         }
 
         return true;
     }
+
+    public void showTitle(Bitmap favicon, String title) {
+        mDoorhangerTitle.setText(title);
+        mDoorhangerTitle.setCompoundDrawablesWithIntrinsicBounds(new BitmapDrawable(getResources(), favicon), null, null, null);
+        if (favicon != null) {
+            mDoorhangerTitle.setCompoundDrawablePadding((int) mContext.getResources().getDimension(R.dimen.doorhanger_drawable_padding));
+        }
+        mDoorhangerTitle.setVisibility(VISIBLE);
+    }
+
+    public void hideTitle() {
+        mDoorhangerTitle.setVisibility(GONE);
+    }
 }
--- a/mobile/android/base/widget/LoginDoorHanger.java
+++ b/mobile/android/base/widget/LoginDoorHanger.java
@@ -30,25 +30,23 @@ import org.json.JSONArray;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.favicons.Favicons;
 import org.mozilla.gecko.favicons.OnFaviconLoadedListener;
 
 public class LoginDoorHanger extends DoorHanger {
     private static final String LOGTAG = "LoginDoorHanger";
     private enum ActionType { EDIT, SELECT }
 
-    private final TextView mTitle;
     private final TextView mMessage;
     private final TextView mLink;
     private final DoorhangerConfig.ButtonConfig mButtonConfig;
 
     public LoginDoorHanger(Context context, DoorhangerConfig config) {
         super(context, config, Type.LOGIN);
 
-        mTitle = (TextView) findViewById(R.id.doorhanger_title);
         mMessage = (TextView) findViewById(R.id.doorhanger_message);
         mLink = (TextView) findViewById(R.id.doorhanger_link);
         mIcon.setImageResource(R.drawable.icon_key);
         mIcon.setVisibility(View.VISIBLE);
 
         mButtonConfig = config.getPositiveButtonConfig();
 
         loadConfig(config);
@@ -71,40 +69,16 @@ public class LoginDoorHanger extends Doo
     protected int getContentResource() {
         return R.layout.login_doorhanger;
     }
 
     @Override
     protected void setOptions(final JSONObject options) {
         super.setOptions(options);
 
-        final JSONObject titleObj = options.optJSONObject("title");
-        if (titleObj != null) {
-
-            try {
-                final String text = titleObj.getString("text");
-                mTitle.setText(text);
-            } catch (JSONException e) {
-                Log.e(LOGTAG, "Error loading title from options JSON", e);
-            }
-
-            final String resource = titleObj.optString("resource");
-            if (resource != null) {
-                Favicons.getSizedFaviconForPageFromLocal(mContext, resource, 32, new OnFaviconLoadedListener() {
-                    @Override
-                    public void onFaviconLoaded(String url, String faviconURL, Bitmap favicon) {
-                        if (favicon != null) {
-                            mTitle.setCompoundDrawablesWithIntrinsicBounds(new BitmapDrawable(mResources, favicon), null, null, null);
-                            mTitle.setCompoundDrawablePadding((int) mResources.getDimension(R.dimen.doorhanger_drawable_padding));
-                        }
-                    }
-                });
-            }
-        }
-
         final JSONObject actionText = options.optJSONObject("actionText");
         addActionText(actionText);
     }
 
     @Override
     protected OnClickListener makeOnButtonClickListener(final int id) {
         return new Button.OnClickListener() {
             @Override
--- a/mobile/android/base/widget/SiteLogins.java
+++ b/mobile/android/base/widget/SiteLogins.java
@@ -1,22 +1,16 @@
 package org.mozilla.gecko.widget;
 
 import org.json.JSONArray;
 import org.json.JSONObject;
 
 public class SiteLogins {
-    private final JSONObject titleObj;
     private final JSONArray logins;
 
-    public SiteLogins(JSONObject titleObj, JSONArray logins) {
+    public SiteLogins(JSONArray logins) {
         this.logins = logins;
-        this.titleObj = titleObj;
     }
 
     public JSONArray getLogins() {
         return logins;
     }
-
-    public JSONObject getTitle() {
-        return titleObj;
-    }
 }
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -2325,24 +2325,17 @@ var NativeWindow = {
    *        persistWhileVisible:
    *                     A boolean. If true, a visible notification will always
    *                     persist across location changes.
    *        timeout:     A time in milliseconds. The notification will not
    *                     automatically dismiss before this time.
    *
    *        checkbox:    A string to appear next to a checkbox under the notification
    *                     message. The button callback functions will be called with
-   *                     the checked state as an argument.                   
-   *
-   *        title:       An object that specifies text to display as the title, and
-   *                     optionally a resource, such as a favicon cache url that can be
-   *                     used to fetch a favicon from the FaviconCache. (This can be
-   *                     generalized to other resources if the situation arises.)
-   *                     { text: <title>,
-   *                       resource: <resource_url> }
+   *                     the checked state as an argument.
    *
    *        actionText:  An object that specifies a clickable string, a type of action,
    *                     and a bundle blob for the consumer to create a click action.
    *                     { text: <text>,
    *                       type: <type>,
    *                       bundle: <blob-object> }
    *
    * @param aCategory
--- a/mobile/android/components/LoginManagerPrompter.js
+++ b/mobile/android/components/LoginManagerPrompter.js
@@ -135,28 +135,26 @@ LoginManagerPrompter.prototype = {
         Services.telemetry.getHistogramById("PWMGR_PROMPT_REMEMBER_ACTION").add(PROMPT_DISPLAYED);
     },
 
 
     /*
      * _showLoginNotification
      *
      * Displays a notification doorhanger.
-     * @param aTitle
-     *        Object with title and optional resource to display with the title, such as a favicon key
      * @param aBody
      *        String message to be displayed in the doorhanger
      * @param aButtons
      *        Buttons to display with the doorhanger
      * @param aUsername
      *        Username string used in creating a doorhanger action
      * @param aPassword
      *        Password string used in creating a doorhanger action
      */
-    _showLoginNotification : function (aTitle, aBody, aButtons, aUsername, aPassword) {
+    _showLoginNotification : function (aBody, aButtons, aUsername, aPassword) {
         let notifyWin = this._window.top;
         let chromeWin = this._getChromeWindow(notifyWin).wrappedJSObject;
         let browser = chromeWin.BrowserApp.getBrowserForWindow(notifyWin);
         let tabID = chromeWin.BrowserApp.getTabForBrowser(browser).id;
 
         let actionText = {
             text: aUsername,
             type: "EDIT",
@@ -169,17 +167,16 @@ LoginManagerPrompter.prototype = {
 
         // Sites like Gmail perform a funky redirect dance before you end up
         // at the post-authentication page. I don't see a good way to
         // heuristically determine when to ignore such location changes, so
         // we'll try ignoring location changes based on a time interval.
         let options = {
             persistWhileVisible: true,
             timeout: Date.now() + 10000,
-            title: aTitle,
             actionText: actionText
         }
 
         var nativeWindow = this._getNativeWindow();
         if (nativeWindow)
             nativeWindow.doorhanger.show(aBody, "password", aButtons, tabID, options, "LOGIN");
     },
 
@@ -191,19 +188,16 @@ LoginManagerPrompter.prototype = {
      * save the specified login. This allows the user to see the results of
      * their login, and only save a login which they know worked.
      *
      */
     _showSaveLoginNotification : function (aLogin) {
         let brandShortName = this._strBundle.brand.GetStringFromName("brandShortName");
         let notificationText  = this._getLocalizedString("saveLogin", [brandShortName]);
 
-        let displayHost = this._getShortDisplayHost(aLogin.hostname);
-        let title = { text: displayHost, resource: aLogin.hostname };
-
         let username = aLogin.username ? this._sanitizeUsername(aLogin.username) : "";
 
         // The callbacks in |buttons| have a closure to access the variables
         // in scope here; set one to |this._pwmgr| so we can get back to pwmgr
         // without a getService() call.
         var pwmgr = this._pwmgr;
         let promptHistogram = Services.telemetry.getHistogramById("PWMGR_PROMPT_REMEMBER_ACTION");
 
@@ -225,17 +219,17 @@ LoginManagerPrompter.prototype = {
                     }
                     pwmgr.addLogin(aLogin);
                     promptHistogram.add(PROMPT_ADD);
                 },
                 positive: true
             }
         ];
 
-        this._showLoginNotification(title, notificationText, buttons, aLogin.username, aLogin.password);
+        this._showLoginNotification(notificationText, buttons, aLogin.username, aLogin.password);
     },
 
     /*
      * promptToChangePassword
      *
      * Called when we think we detect a password change for an existing
      * login, when the form being submitted contains multiple password
      * fields.
@@ -256,19 +250,16 @@ LoginManagerPrompter.prototype = {
         var notificationText;
         if (aOldLogin.username) {
             let displayUser = this._sanitizeUsername(aOldLogin.username);
             notificationText  = this._getLocalizedString("updatePassword", [displayUser]);
         } else {
             notificationText  = this._getLocalizedString("updatePasswordNoUser");
         }
 
-        let displayHost = this._getShortDisplayHost(aOldLogin.hostname);
-        let title = { text: displayHost, resource: aOldLogin.hostname };
-
         // The callbacks in |buttons| have a closure to access the variables
         // in scope here; set one to |this._pwmgr| so we can get back to pwmgr
         // without a getService() call.
         var self = this;
         let promptHistogram = Services.telemetry.getHistogramById("PWMGR_PROMPT_UPDATE_ACTION");
 
         var buttons = [
             {
@@ -285,17 +276,17 @@ LoginManagerPrompter.prototype = {
                    self._updateLogin(aOldLogin, password);
 
                    promptHistogram.add(PROMPT_UPDATE);
                 },
                 positive: true
             }
         ];
 
-        this._showLoginNotification(title, notificationText, buttons, aOldLogin.username, aNewPassword);
+        this._showLoginNotification(notificationText, buttons, aOldLogin.username, aNewPassword);
     },
 
 
     /*
      * promptToChangePasswordWithUsernames
      *
      * Called when we detect a password change in a form submission, but we
      * don't know which existing login (username) it's for. Asks the user
@@ -457,43 +448,14 @@ LoginManagerPrompter.prototype = {
             var handler = Services.io.getProtocolHandler(scheme);
             if (port != handler.defaultPort)
                 hostname += ":" + port;
         }
 
         return hostname;
     },
 
-
-    /*
-     * _getShortDisplayHost
-     *
-     * Converts a login's hostname field (a URL) to a short string for
-     * prompting purposes. Eg, "http://foo.com" --> "foo.com", or
-     * "ftp://www.site.co.uk" --> "site.co.uk".
-     */
-    _getShortDisplayHost: function (aURIString) {
-        var displayHost;
-
-        var eTLDService = Cc["@mozilla.org/network/effective-tld-service;1"].
-                          getService(Ci.nsIEffectiveTLDService);
-        var idnService = Cc["@mozilla.org/network/idn-service;1"].
-                         getService(Ci.nsIIDNService);
-        try {
-            var uri = Services.io.newURI(aURIString, null, null);
-            var baseDomain = eTLDService.getBaseDomain(uri);
-            displayHost = idnService.convertToDisplayIDN(baseDomain, {});
-        } catch (e) {
-            this.log("_getShortDisplayHost couldn't process " + aURIString);
-        }
-
-        if (!displayHost)
-            displayHost = aURIString;
-
-        return displayHost;
-    },
-
 }; // end of LoginManagerPrompter implementation
 
 
 var component = [LoginManagerPrompter];
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory(component);