diff --git a/mobile/android/base/locales/en-US/android_strings.dtd b/mobile/android/base/locales/en-US/android_strings.dtd
index c39f8e0d2c8..d2f2f8e1b46 100644
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -476,6 +476,13 @@ just addresses the organization to follow, e.g. "This site is run by " -->
+
+
+
+
+
+
+
diff --git a/mobile/android/base/strings.xml.in b/mobile/android/base/strings.xml.in
index fae0885a700..3928145f429 100644
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -412,6 +412,9 @@
&loaded_mixed_content_message;
&blocked_mixed_content_message_top;
&blocked_mixed_content_message_bottom;
+ &loaded_tracking_content_message;
+ &blocked_tracking_content_message_top;
+ &blocked_tracking_content_message_bottom;
&learn_more;
&enable_protection;
&disable_protection;
diff --git a/mobile/android/base/toolbar/SiteIdentityPopup.java b/mobile/android/base/toolbar/SiteIdentityPopup.java
index 58355438157..74328473305 100644
--- a/mobile/android/base/toolbar/SiteIdentityPopup.java
+++ b/mobile/android/base/toolbar/SiteIdentityPopup.java
@@ -9,6 +9,8 @@ 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.widget.ArrowPopup;
import org.mozilla.gecko.widget.DoorHanger;
import org.mozilla.gecko.widget.DoorHanger.OnButtonClickListener;
@@ -34,6 +36,9 @@ public class SiteIdentityPopup extends ArrowPopup {
private static final String MIXED_CONTENT_SUPPORT_URL =
"https://support.mozilla.org/kb/how-does-insecure-content-affect-safety-android";
+ private static final String TRACKING_CONTENT_SUPPORT_URL =
+ "https://support.mozilla.org/kb/how-does-insecure-content-affect-safety-android";
+
private SiteIdentity mSiteIdentity;
private LinearLayout mIdentity;
@@ -42,6 +47,7 @@ public class SiteIdentityPopup extends ArrowPopup {
private TextView mVerifier;
private DoorHanger mMixedContentNotification;
+ private DoorHanger mTrackingContentNotification;
private final OnButtonClickListener mButtonClickListener;
@@ -68,13 +74,14 @@ public class SiteIdentityPopup extends ArrowPopup {
mVerifier = (TextView) mIdentity.findViewById(R.id.verifier);
}
- private void updateUi() {
+ private void updateIdentity() {
if (!mInflated) {
init();
}
- if (mSiteIdentity.getSecurityMode() == SecurityMode.MIXED_CONTENT_LOADED ||
- mSiteIdentity.getSecurityMode() == SecurityMode.MIXED_CONTENT_BLOCKED) {
+ final MixedMode mixedMode = mSiteIdentity.getMixedMode();
+ final TrackingMode trackingMode = mSiteIdentity.getTrackingMode();
+ if (mixedMode != MixedMode.UNKNOWN || trackingMode != TrackingMode.UNKNOWN) {
// Hide the identity data if there isn't valid site identity data.
// Set some top padding on the popup content to create a of light blue
// between the popup arrow and the mixed content notification.
@@ -106,27 +113,22 @@ public class SiteIdentityPopup extends ArrowPopup {
removeMixedContentNotification();
mMixedContentNotification = new DoorHanger(mContext, DoorHanger.Theme.DARK);
+ int icon;
String message;
if (blocked) {
+ icon = R.drawable.shield_doorhanger;
message = mContext.getString(R.string.blocked_mixed_content_message_top) + "\n\n" +
mContext.getString(R.string.blocked_mixed_content_message_bottom);
} else {
+ icon = R.drawable.warning_doorhanger;
message = mContext.getString(R.string.loaded_mixed_content_message);
}
+
+ mMixedContentNotification.setIcon(icon);
mMixedContentNotification.setMessage(message);
mMixedContentNotification.addLink(mContext.getString(R.string.learn_more), MIXED_CONTENT_SUPPORT_URL, "\n\n");
- if (blocked) {
- mMixedContentNotification.setIcon(R.drawable.shield_doorhanger);
- mMixedContentNotification.addButton(mContext.getString(R.string.disable_protection),
- "disable", mButtonClickListener);
- mMixedContentNotification.addButton(mContext.getString(R.string.keep_blocking),
- "keepBlocking", mButtonClickListener);
- } else {
- mMixedContentNotification.setIcon(R.drawable.warning_doorhanger);
- mMixedContentNotification.addButton(mContext.getString(R.string.enable_protection),
- "enable", mButtonClickListener);
- }
+ addNotificationButtons(mMixedContentNotification, blocked);
mContent.addView(mMixedContentNotification);
}
@@ -138,6 +140,47 @@ public class SiteIdentityPopup extends ArrowPopup {
}
}
+ private void addTrackingContentNotification(boolean blocked) {
+ // Remove any existing tracking content notification.
+ removeTrackingContentNotification();
+ mTrackingContentNotification = new DoorHanger(mContext, DoorHanger.Theme.DARK);
+
+ int icon;
+ String message;
+ if (blocked) {
+ icon = R.drawable.shield_doorhanger;
+ message = mContext.getString(R.string.blocked_tracking_content_message_top) + "\n\n" +
+ mContext.getString(R.string.blocked_tracking_content_message_bottom);
+ } else {
+ icon = R.drawable.warning_doorhanger;
+ message = mContext.getString(R.string.loaded_tracking_content_message);
+ }
+
+ mTrackingContentNotification.setIcon(icon);
+ mTrackingContentNotification.setMessage(message);
+ mTrackingContentNotification.addLink(mContext.getString(R.string.learn_more), TRACKING_CONTENT_SUPPORT_URL, "\n\n");
+
+ addNotificationButtons(mTrackingContentNotification, blocked);
+
+ mContent.addView(mTrackingContentNotification);
+ }
+
+ private void removeTrackingContentNotification() {
+ if (mTrackingContentNotification != null) {
+ mContent.removeView(mTrackingContentNotification);
+ mTrackingContentNotification = null;
+ }
+ }
+
+ private void addNotificationButtons(DoorHanger dh, boolean blocked) {
+ if (blocked) {
+ dh.addButton(mContext.getString(R.string.disable_protection), "disable", mButtonClickListener);
+ dh.addButton(mContext.getString(R.string.keep_blocking), "keepBlocking", mButtonClickListener);
+ } else {
+ dh.addButton(mContext.getString(R.string.enable_protection), "enable", mButtonClickListener);
+ }
+ }
+
/*
* @param identityData A JSONObject that holds the current tab's identity data.
*/
@@ -152,26 +195,58 @@ public class SiteIdentityPopup extends ArrowPopup {
return;
}
- final SecurityMode mode = mSiteIdentity.getSecurityMode();
- if (mode == SecurityMode.UNKNOWN) {
- Log.e(LOGTAG, "Can't show site identity popup in non-identified state");
+ final SecurityMode identityMode = mSiteIdentity.getSecurityMode();
+ final MixedMode mixedMode = mSiteIdentity.getMixedMode();
+ final TrackingMode trackingMode = mSiteIdentity.getTrackingMode();
+ if (identityMode == SecurityMode.UNKNOWN && mixedMode == MixedMode.UNKNOWN && trackingMode == TrackingMode.UNKNOWN) {
+ Log.e(LOGTAG, "Can't show site identity popup in a completely unknown state");
return;
}
- updateUi();
+ updateIdentity();
- if (mode == SecurityMode.MIXED_CONTENT_LOADED ||
- mode == SecurityMode.MIXED_CONTENT_BLOCKED) {
- addMixedContentNotification(mode == SecurityMode.MIXED_CONTENT_BLOCKED);
+ if (mixedMode != MixedMode.UNKNOWN) {
+ addMixedContentNotification(mixedMode == MixedMode.MIXED_CONTENT_BLOCKED);
}
+ if (trackingMode != TrackingMode.UNKNOWN) {
+ addTrackingContentNotification(trackingMode == TrackingMode.TRACKING_CONTENT_BLOCKED);
+ }
+
+ showDividers();
+
super.show();
}
+ // Show the right dividers
+ private void showDividers() {
+ final int count = mContent.getChildCount();
+ DoorHanger lastVisibleDoorHanger = null;
+
+ for (int i = 0; i < count; i++) {
+ final View child = mContent.getChildAt(i);
+
+ if (!(child instanceof DoorHanger)) {
+ continue;
+ }
+
+ DoorHanger dh = (DoorHanger) child;
+ dh.showDivider();
+ if (dh.getVisibility() == View.VISIBLE) {
+ lastVisibleDoorHanger = dh;
+ }
+ }
+
+ if (lastVisibleDoorHanger != null) {
+ lastVisibleDoorHanger.hideDivider();
+ }
+ }
+
@Override
public void dismiss() {
super.dismiss();
removeMixedContentNotification();
+ removeTrackingContentNotification();
}
private class PopupButtonListener implements OnButtonClickListener {
@@ -179,11 +254,13 @@ public class SiteIdentityPopup extends ArrowPopup {
public void onButtonClick(DoorHanger dh, String tag) {
try {
JSONObject data = new JSONObject();
- data.put("allowMixedContent", tag.equals("disable"));
+ String allowType = (dh == mMixedContentNotification ? "allowMixedContent" : "allowTrackingContent");
+ data.put(allowType, tag.equals("disable"));
+
GeckoEvent e = GeckoEvent.createBroadcastEvent("Session:Reload", data.toString());
GeckoAppShell.sendEventToGecko(e);
} catch (JSONException e) {
- Log.e(LOGTAG, "Exception creating message to enable/disable mixed content blocking", e);
+ Log.e(LOGTAG, "Exception creating message to enable/disable content blocking", e);
}
dismiss();