зеркало из https://github.com/mozilla/gecko-dev.git
Bug 945212 - Encapsulate identity data/security mode behind a type-safe API (r=margaret)
This commit is contained in:
Родитель
fb5f4e99fe
Коммит
fc210fdac8
|
@ -0,0 +1,110 @@
|
|||
/* -*- 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;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
public class SiteIdentity {
|
||||
private SecurityMode mSecurityMode;
|
||||
private String mHost;
|
||||
private String mOwner;
|
||||
private String mSupplemental;
|
||||
private String mVerifier;
|
||||
private String mEncrypted;
|
||||
|
||||
// The order of the items here correspond to image
|
||||
// levels in site_security_level.xml
|
||||
public enum SecurityMode {
|
||||
UNKNOWN("unknown"),
|
||||
VERIFIED("verified"),
|
||||
IDENTIFIED("identified"),
|
||||
MIXED_CONTENT_BLOCKED("mixed_content_blocked"),
|
||||
MIXED_CONTENT_LOADED("mixed_content_loaded");
|
||||
|
||||
private final String mId;
|
||||
|
||||
private SecurityMode(String id) {
|
||||
mId = id;
|
||||
}
|
||||
|
||||
public static SecurityMode fromString(String id) {
|
||||
if (id == null) {
|
||||
throw new IllegalArgumentException("Can't convert null String to SiteIdentity");
|
||||
}
|
||||
|
||||
for (SecurityMode mode : SecurityMode.values()) {
|
||||
if (TextUtils.equals(mode.mId, id.toLowerCase())) {
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Could not convert String id to SiteIdentity");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return mId;
|
||||
}
|
||||
}
|
||||
|
||||
public SiteIdentity() {
|
||||
reset(SecurityMode.UNKNOWN);
|
||||
}
|
||||
|
||||
private void reset(SecurityMode securityMode) {
|
||||
mSecurityMode = securityMode;
|
||||
mHost = null;
|
||||
mOwner = null;
|
||||
mSupplemental = null;
|
||||
mVerifier = null;
|
||||
mEncrypted = null;
|
||||
}
|
||||
|
||||
void update(JSONObject identityData) {
|
||||
try {
|
||||
mSecurityMode = SecurityMode.fromString(identityData.getString("mode"));
|
||||
} catch (Exception e) {
|
||||
reset(SecurityMode.UNKNOWN);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
mHost = identityData.getString("host");
|
||||
mOwner = identityData.getString("owner");
|
||||
mSupplemental = identityData.optString("supplemental", null);
|
||||
mVerifier = identityData.getString("verifier");
|
||||
mEncrypted = identityData.getString("encrypted");
|
||||
} catch (Exception e) {
|
||||
reset(mSecurityMode);
|
||||
}
|
||||
}
|
||||
|
||||
public SecurityMode getSecurityMode() {
|
||||
return mSecurityMode;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return mHost;
|
||||
}
|
||||
|
||||
public String getOwner() {
|
||||
return mOwner;
|
||||
}
|
||||
|
||||
public String getSupplemental() {
|
||||
return mSupplemental;
|
||||
}
|
||||
|
||||
public String getVerifier() {
|
||||
return mVerifier;
|
||||
}
|
||||
|
||||
public String getEncrypted() {
|
||||
return mEncrypted;
|
||||
}
|
||||
}
|
|
@ -5,10 +5,10 @@
|
|||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import org.mozilla.gecko.SiteIdentity.SecurityMode;
|
||||
import org.mozilla.gecko.db.BrowserDB;
|
||||
import org.mozilla.gecko.gfx.Layer;
|
||||
import org.mozilla.gecko.home.HomePager;
|
||||
import org.mozilla.gecko.toolbar.SiteIdentityPopup;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import org.json.JSONException;
|
||||
|
@ -46,7 +46,7 @@ public class Tab {
|
|||
private int mFaviconSize;
|
||||
private boolean mHasFeeds;
|
||||
private boolean mHasOpenSearch;
|
||||
private JSONObject mIdentityData;
|
||||
private SiteIdentity mSiteIdentity;
|
||||
private boolean mReaderEnabled;
|
||||
private BitmapDrawable mThumbnail;
|
||||
private int mHistoryIndex;
|
||||
|
@ -102,7 +102,7 @@ public class Tab {
|
|||
mFaviconSize = 0;
|
||||
mHasFeeds = false;
|
||||
mHasOpenSearch = false;
|
||||
mIdentityData = null;
|
||||
mSiteIdentity = new SiteIdentity();
|
||||
mReaderEnabled = false;
|
||||
mEnteringReaderMode = false;
|
||||
mThumbnail = null;
|
||||
|
@ -247,17 +247,12 @@ public class Tab {
|
|||
return mHasOpenSearch;
|
||||
}
|
||||
|
||||
public String getSecurityMode() {
|
||||
try {
|
||||
return mIdentityData.getString("mode");
|
||||
} catch (Exception e) {
|
||||
// If mIdentityData is null, or we get a JSONException
|
||||
return SiteIdentityPopup.UNKNOWN;
|
||||
}
|
||||
public SecurityMode getSecurityMode() {
|
||||
return mSiteIdentity.getSecurityMode();
|
||||
}
|
||||
|
||||
public JSONObject getIdentityData() {
|
||||
return mIdentityData;
|
||||
public SiteIdentity getSiteIdentity() {
|
||||
return mSiteIdentity;
|
||||
}
|
||||
|
||||
public boolean getReaderEnabled() {
|
||||
|
@ -416,7 +411,7 @@ public class Tab {
|
|||
}
|
||||
|
||||
public void updateIdentityData(JSONObject identityData) {
|
||||
mIdentityData = identityData;
|
||||
mSiteIdentity.update(identityData);
|
||||
}
|
||||
|
||||
public void setReaderEnabled(boolean readerEnabled) {
|
||||
|
|
|
@ -278,6 +278,7 @@ gbjar.sources += [
|
|||
'ServiceNotificationClient.java',
|
||||
'SessionParser.java',
|
||||
'SharedPreferencesHelper.java',
|
||||
'SiteIdentity.java',
|
||||
'SmsManager.java',
|
||||
'sqlite/ByteBufferInputStream.java',
|
||||
'sqlite/MatrixBlobCursor.java',
|
||||
|
|
|
@ -12,6 +12,8 @@ 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;
|
||||
import org.mozilla.gecko.animation.PropertyAnimator;
|
||||
|
@ -428,13 +430,15 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
|||
if (mSiteSecurity.getVisibility() != View.VISIBLE)
|
||||
return;
|
||||
|
||||
JSONObject identityData = Tabs.getInstance().getSelectedTab().getIdentityData();
|
||||
if (identityData == null) {
|
||||
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(identityData);
|
||||
mSiteIdentityPopup.updateIdentity(siteIdentity);
|
||||
mSiteIdentityPopup.show();
|
||||
}
|
||||
};
|
||||
|
@ -978,11 +982,10 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
|||
mFavicon.setImageDrawable(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void setSecurityMode(String mode) {
|
||||
int imageLevel = SiteIdentityPopup.getSecurityImageLevel(mode);
|
||||
mSiteSecurity.setImageLevel(imageLevel);
|
||||
mShowSiteSecurity = (imageLevel != SiteIdentityPopup.LEVEL_UKNOWN);
|
||||
|
||||
private void setSecurityMode(SecurityMode mode) {
|
||||
mSiteSecurity.setImageLevel(mode.ordinal());
|
||||
mShowSiteSecurity = (mode != SecurityMode.UNKNOWN);
|
||||
|
||||
setPageActionVisibility(mStop.getVisibility() == View.VISIBLE);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@ import org.mozilla.gecko.BrowserApp;
|
|||
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.widget.ArrowPopup;
|
||||
import org.mozilla.gecko.widget.DoorHanger;
|
||||
import org.mozilla.gecko.widget.DoorHanger.OnButtonClickListener;
|
||||
|
@ -31,19 +33,6 @@ import android.widget.TextView;
|
|||
public class SiteIdentityPopup extends ArrowPopup {
|
||||
private static final String LOGTAG = "GeckoSiteIdentityPopup";
|
||||
|
||||
public static final String UNKNOWN = "unknown";
|
||||
public static final String VERIFIED = "verified";
|
||||
public static final String IDENTIFIED = "identified";
|
||||
public static final String MIXED_CONTENT_BLOCKED = "mixed_content_blocked";
|
||||
public static final String MIXED_CONTENT_LOADED = "mixed_content_loaded";
|
||||
|
||||
// Security states corresponding to image levels in site_security_level.xml
|
||||
static final int LEVEL_UKNOWN = 0;
|
||||
static final int LEVEL_IDENTIFIED = 1;
|
||||
static final int LEVEL_VERIFIED = 2;
|
||||
static final int LEVEL_MIXED_CONTENT_BLOCKED = 3;
|
||||
static final int LEVEL_MIXED_CONTENT_LOADED = 4;
|
||||
|
||||
// FIXME: Update this URL for mobile. See bug 885923.
|
||||
private static final String MIXED_CONTENT_SUPPORT_URL =
|
||||
"https://support.mozilla.org/kb/how-does-content-isnt-secure-affect-my-safety";
|
||||
|
@ -66,22 +55,6 @@ public class SiteIdentityPopup extends ArrowPopup {
|
|||
mButtonClickListener = new PopupButtonListener();
|
||||
}
|
||||
|
||||
static int getSecurityImageLevel(String mode) {
|
||||
if (IDENTIFIED.equals(mode)) {
|
||||
return LEVEL_IDENTIFIED;
|
||||
}
|
||||
if (VERIFIED.equals(mode)) {
|
||||
return LEVEL_VERIFIED;
|
||||
}
|
||||
if (MIXED_CONTENT_BLOCKED.equals(mode)) {
|
||||
return LEVEL_MIXED_CONTENT_BLOCKED;
|
||||
}
|
||||
if (MIXED_CONTENT_LOADED.equals(mode)) {
|
||||
return LEVEL_MIXED_CONTENT_LOADED;
|
||||
}
|
||||
return LEVEL_UKNOWN;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
|
@ -99,33 +72,31 @@ public class SiteIdentityPopup extends ArrowPopup {
|
|||
mVerifier = (TextView) mIdentity.findViewById(R.id.verifier);
|
||||
}
|
||||
|
||||
private void setIdentity(JSONObject identityData) {
|
||||
try {
|
||||
String host = identityData.getString("host");
|
||||
mHost.setText(host);
|
||||
|
||||
String owner = identityData.getString("owner");
|
||||
|
||||
// Supplemental data is optional.
|
||||
String supplemental = identityData.optString("supplemental");
|
||||
if (!TextUtils.isEmpty(supplemental)) {
|
||||
owner += "\n" + supplemental;
|
||||
}
|
||||
mOwner.setText(owner);
|
||||
|
||||
String verifier = identityData.getString("verifier");
|
||||
String encrypted = identityData.getString("encrypted");
|
||||
mVerifier.setText(verifier + "\n" + encrypted);
|
||||
|
||||
mContent.setPadding(0, 0, 0, 0);
|
||||
mIdentity.setVisibility(View.VISIBLE);
|
||||
|
||||
} catch (JSONException e) {
|
||||
private void setIdentity(SiteIdentity siteIdentity) {
|
||||
if (siteIdentity.getSecurityMode() == SecurityMode.MIXED_CONTENT_LOADED) {
|
||||
// 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.
|
||||
mContent.setPadding(0, (int) mResources.getDimension(R.dimen.identity_padding_top), 0, 0);
|
||||
mIdentity.setVisibility(View.GONE);
|
||||
} else {
|
||||
mHost.setText(siteIdentity.getHost());
|
||||
|
||||
String owner = siteIdentity.getOwner();
|
||||
|
||||
// Supplemental data is optional.
|
||||
final String supplemental = siteIdentity.getSupplemental();
|
||||
if (!TextUtils.isEmpty(supplemental)) {
|
||||
owner += "\n" + supplemental;
|
||||
}
|
||||
mOwner.setText(owner);
|
||||
|
||||
final String verifier = siteIdentity.getVerifier();
|
||||
final String encrypted = siteIdentity.getEncrypted();
|
||||
mVerifier.setText(verifier + "\n" + encrypted);
|
||||
|
||||
mContent.setPadding(0, 0, 0, 0);
|
||||
mIdentity.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,16 +140,9 @@ public class SiteIdentityPopup extends ArrowPopup {
|
|||
/*
|
||||
* @param identityData A JSONObject that holds the current tab's identity data.
|
||||
*/
|
||||
void updateIdentity(JSONObject identityData) {
|
||||
String mode;
|
||||
try {
|
||||
mode = identityData.getString("mode");
|
||||
} catch (JSONException e) {
|
||||
Log.e(LOGTAG, "Exception trying to get identity mode", e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (UNKNOWN.equals(mode)) {
|
||||
void updateIdentity(SiteIdentity siteIdentity) {
|
||||
final SecurityMode mode = siteIdentity.getSecurityMode();
|
||||
if (mode == SecurityMode.UNKNOWN) {
|
||||
Log.e(LOGTAG, "Can't show site identity popup in non-identified state");
|
||||
return;
|
||||
}
|
||||
|
@ -186,10 +150,11 @@ public class SiteIdentityPopup extends ArrowPopup {
|
|||
if (!mInflated)
|
||||
init();
|
||||
|
||||
setIdentity(identityData);
|
||||
setIdentity(siteIdentity);
|
||||
|
||||
if (MIXED_CONTENT_BLOCKED.equals(mode) || MIXED_CONTENT_LOADED.equals(mode)) {
|
||||
addMixedContentNotification(MIXED_CONTENT_BLOCKED.equals(mode));
|
||||
if (mode == SecurityMode.MIXED_CONTENT_LOADED ||
|
||||
mode == SecurityMode.MIXED_CONTENT_BLOCKED) {
|
||||
addMixedContentNotification(mode == SecurityMode.MIXED_CONTENT_BLOCKED);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче