Bug 1381536 - Replace GeckoBundle passed to ProgressListener.onSecurityChanged with a class. r=jchen
authorDylan Roeh <droeh@mozilla.com>
Fri, 28 Jul 2017 17:14:01 -0500
changeset 420582 526b29eb6c64929ace38535153a7e4f9b11d4d6c
parent 420581 b0b3cced9169bbf36dd0834218bca511982ef40d
child 420583 731889ddbd52a3abde5ebcc766e09e9f536434e5
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjchen
bugs1381536
milestone56.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 1381536 - Replace GeckoBundle passed to ProgressListener.onSecurityChanged with a class. r=jchen This adds a new class, GeckoView.ProgressListener.SecurityInformation, which provides an API for accessing the information passed to GeckoView in GeckoView:SecurityChange messages. GeckoView then passes this object to ProgressListener in onSecurityChanged() calls. Also updates CustomTabsActivity and GeckoViewActivity to reflect the new API and removes the old integer security status param from onSecurityChanged.
mobile/android/base/java/org/mozilla/gecko/customtabs/ActionBarPresenter.java
mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoView.java
mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java
mobile/android/modules/geckoview/GeckoViewProgress.jsm
--- a/mobile/android/base/java/org/mozilla/gecko/customtabs/ActionBarPresenter.java
+++ b/mobile/android/base/java/org/mozilla/gecko/customtabs/ActionBarPresenter.java
@@ -102,34 +102,34 @@ public class ActionBarPresenter {
     }
 
     /**
      * To display Url in CustomView only and immediately.
      *
      * @param url Url String to display
      */
     public void displayUrlOnly(@NonNull final String url) {
-        updateCustomView(null, url, GeckoView.ProgressListener.STATE_IS_INSECURE);
+        updateCustomView(null, url, /* isSecure */ false);
     }
 
     /**
      * Update appearance of CustomView of ActionBar
      *
      * @param title          Title for current website. Could be null if don't want to show title.
      * @param url            URL for current website. At least Custom will show this url.
-     * @param securityStatus Security status, possible values given in GeckoView.ProgressListener
+     * @param isSecure       A boolean representing whether or not the site is secure.
      */
-    public void update(final String title, final String url, final int securityStatus) {
+    public void update(final String title, final String url, final boolean isSecure) {
         // Do not update CustomView immediately. If this method be invoked rapidly several times,
         // only apply last one.
         mHandler.removeCallbacks(mUpdateAction);
         mUpdateAction = new Runnable() {
             @Override
             public void run() {
-                updateCustomView(title, url, securityStatus);
+                updateCustomView(title, url, isSecure);
             }
         };
         mHandler.postDelayed(mUpdateAction, CUSTOM_VIEW_UPDATE_DELAY);
     }
 
     /**
      * To add a always-show-as-action button to menu, and manually create a view to insert.
      *
@@ -208,23 +208,23 @@ public class ActionBarPresenter {
         Drawable wrapped = DrawableCompat.wrap(icon);
         DrawableCompat.setTint(wrapped, mTextPrimaryColor);
         mActionBar.setHomeAsUpIndicator(wrapped);
     }
 
     /**
      * To update appearance of CustomView of ActionBar, includes its icon, title and url text.
      *
-     * @param identity SiteIdentity for current website. Could be null if don't want to show icon.
      * @param title    Title for current website. Could be null if don't want to show title.
      * @param url      URL for current website. At least Custom will show this url.
+     * @param isSecure A boolean representing whether or not the site is secure.
      */
     @UiThread
-    private void updateCustomView(final String title, final String url, final int securityStatus) {
-        if (securityStatus == GeckoView.ProgressListener.STATE_IS_SECURE) {
+    private void updateCustomView(final String title, final String url, final boolean isSecure) {
+        if (isSecure) {
             mIconView.setVisibility(View.VISIBLE);
             mIconView.setImageLevel(SecurityModeUtil.getImageLevel(SecurityModeUtil.IconType.LOCK_SECURE));
             // Lock-Secure is special case. Keep its original green color.
             DrawableCompat.setTintList(mIconView.getDrawable(), null);
         } else {
             mIconView.setVisibility(View.INVISIBLE);
             DrawableCompat.setTint(mIconView.getDrawable(), mTextPrimaryColor);
         }
--- a/mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java
+++ b/mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java
@@ -71,17 +71,17 @@ public class CustomTabsActivity extends 
     private GeckoView mGeckoView;
     private PromptService mPromptService;
 
     private boolean mCanGoBack = false;
     private boolean mCanGoForward = false;
     private boolean mCanStop = false;
     private String mCurrentUrl;
     private String mCurrentTitle;
-    private int mSecurityStatus = GeckoView.ProgressListener.STATE_IS_INSECURE;
+    private boolean mIsSecure = false;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
         setContentView(R.layout.customtabs_activity);
 
         final SafeIntent intent = new SafeIntent(getIntent());
@@ -418,17 +418,17 @@ public class CustomTabsActivity extends 
             }
         }
     }
 
     /**
      * Update the state of the action bar
      */
     private void updateActionBar() {
-        actionBarPresenter.update(mCurrentTitle, mCurrentUrl, mSecurityStatus);
+        actionBarPresenter.update(mCurrentTitle, mCurrentUrl, mIsSecure);
     }
 
     /**
      * Call this method to reload page, or stop page loading if progress not complete yet.
      */
     private void onLoadingControlClicked() {
         if (mCanStop) {
             mGeckoView.stop();
@@ -542,24 +542,18 @@ public class CustomTabsActivity extends 
     @Override
     public void onPageStop(GeckoView view, boolean success) {
         mCanStop = false;
         updateCanStop();
         updateProgress(100);
     }
 
     @Override
-    public void onSecurityChange(GeckoView view, int status, GeckoBundle identity) {
-        if ((status & STATE_IS_INSECURE) != 0) {
-            mSecurityStatus = STATE_IS_INSECURE;
-        } else if ((status & STATE_IS_BROKEN) != 0) {
-            mSecurityStatus = STATE_IS_BROKEN;
-        } else if ((status & STATE_IS_SECURE) != 0) {
-            mSecurityStatus = STATE_IS_SECURE;
-        }
+    public void onSecurityChange(GeckoView view, SecurityInformation securityInfo) {
+        mIsSecure = securityInfo.isSecure;
         updateActionBar();
     }
 
     /* GeckoView.ContentListener */
     @Override
     public void onTitleChange(GeckoView view, String title) {
         mCurrentTitle = title;
         updateActionBar();
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoView.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoView.java
@@ -163,19 +163,18 @@ public class GeckoView extends LayerView
                                       final EventCallback callback) {
                 if ("GeckoView:PageStart".equals(event)) {
                     listener.onPageStart(GeckoView.this,
                                          message.getString("uri"));
                 } else if ("GeckoView:PageStop".equals(event)) {
                     listener.onPageStop(GeckoView.this,
                                         message.getBoolean("success"));
                 } else if ("GeckoView:SecurityChanged".equals(event)) {
-                    final int state = message.getInt("status") & ProgressListener.STATE_ALL;
                     final GeckoBundle identity = message.getBundle("identity");
-                    listener.onSecurityChange(GeckoView.this, state, identity);
+                    listener.onSecurityChange(GeckoView.this, new ProgressListener.SecurityInformation(identity));
                 }
             }
         };
 
     private final GeckoViewHandler<ScrollListener> mScrollHandler =
         new GeckoViewHandler<ScrollListener>(
             "GeckoViewScroll", this,
             new String[]{ "GeckoView:ScrollChanged" }
@@ -1217,20 +1216,93 @@ public class GeckoView extends LayerView
         }
     }
 
     public EventDispatcher getEventDispatcher() {
         return mEventDispatcher;
     }
 
     public interface ProgressListener {
-        static final int STATE_IS_BROKEN = 1;
-        static final int STATE_IS_SECURE = 2;
-        static final int STATE_IS_INSECURE = 4;
-        /* package */ final int STATE_ALL = STATE_IS_BROKEN | STATE_IS_SECURE | STATE_IS_INSECURE;
+        /**
+         * Class representing security information for a site.
+         */
+        public class SecurityInformation {
+            /**
+             * Indicates whether or not the site is secure.
+             */
+            public final boolean isSecure;
+            /**
+             * Indicates whether or not the site is a security exception.
+             */
+            public final boolean isException;
+            /**
+             * Contains the origin of the certificate.
+             */
+            public final String origin;
+            /**
+             * Contains the host associated with the certificate.
+             */
+            public final String host;
+            /**
+             * Contains the human-readable name of the certificate subject.
+             */
+            public final String organization;
+            /**
+             * Contains the full name of the certificate subject, including location.
+             */
+            public final String subjectName;
+            /**
+             * Contains the common name of the issuing authority.
+             */
+            public final String issuerCommonName;
+            /**
+             * Contains the full/proper name of the issuing authority.
+             */
+            public final String issuerOrganization;
+            /**
+             * Indicates the security level of the site; possible values are "unknown",
+             * "identified", and "verified". "identified" indicates domain validation only,
+             * while "verified" indicates extended validation.
+             */
+            public final String securityMode;
+            /**
+             * Indicates the presence of passive mixed content; possible values are
+             * "unknown", "blocked", and "loaded".
+             */
+            public final String mixedModePassive;
+            /**
+             * Indicates the presence of active mixed content; possible values are
+             * "unknown", "blocked", and "loaded".
+             */
+            public final String mixedModeActive;
+            /**
+             * Indicates the status of tracking protection; possible values are
+             * "unknown", "blocked", and "loaded".
+             */
+            public final String trackingMode;
+
+            /* package */ SecurityInformation(GeckoBundle identityData) {
+                final GeckoBundle mode = identityData.getBundle("mode");
+
+                mixedModePassive = mode.getString("mixed_display");
+                mixedModeActive = mode.getString("mixed_active");
+                trackingMode = mode.getString("tracking");
+
+                securityMode = mode.getString("identity");
+
+                isSecure = identityData.getBoolean("secure");
+                isException = identityData.getBoolean("securityException");
+                origin = identityData.getString("origin");
+                host = identityData.getString("host");
+                organization = identityData.getString("organization");
+                subjectName = identityData.getString("subjectName");
+                issuerCommonName = identityData.getString("issuerCommonName");
+                issuerOrganization = identityData.getString("issuerOrganization");
+            }
+        }
 
         /**
         * A View has started loading content from the network.
         * @param view The GeckoView that initiated the callback.
         * @param url The resource being loaded.
         */
         void onPageStart(GeckoView view, String url);
 
@@ -1239,37 +1311,19 @@ public class GeckoView extends LayerView
         * @param view The GeckoView that initiated the callback.
         * @param success Whether the page loaded successfully or an error occurred.
         */
         void onPageStop(GeckoView view, boolean success);
 
         /**
         * The security status has been updated.
         * @param view The GeckoView that initiated the callback.
-        * @param status The new security status.
-        * @param identity A bundle containing the most up-to-date security information, with keys:
-        *          "origin": A string containing the origin of the cert, should always be present
-        *          "secure": A boolean indicating whether or not the site is secure
-        *          "host": A string containing the host associated with the certificate
-        *          "security_exception": A boolean indicating if the site is a security exception
-        *          "organization": A string containing the human readable name of the subject
-        *          "subjectName": A string containing the full subject name (including location data)
-        *          "issuerCommonName": A string containing the common name of the issuing authority
-        *          "issuerOrganization": A string containing the proper name of the issuing authority
-        *          "mode": A GeckoBundle containing information about the security mode, with keys:
-        *            "identity": A string indicating the security level of the site, should always be
-        *                        present. Possible values are "unknown", "identified", and "verified"
-        *            "mixed_display": A string indicating if passive mixed content is present, possible
-        *                             values are: "unknown", "blocked", "loaded"
-        *            "mixed_active": A string indicating if active mixed content is present, possible
-        *                            values are: "unknown", "blocked", "loaded"
-        *            "tracking": A string indicating the status of tracking protection, possible values
-        *                        are: "unknown", "blocked", "loaded"
+        * @param securityInfo The new security information.
         */
-        void onSecurityChange(GeckoView view, int status, GeckoBundle identity);
+        void onSecurityChange(GeckoView view, SecurityInformation securityInfo);
     }
 
     public interface ContentListener {
         /**
         * A page title was discovered in the content or updated after the content
         * loaded.
         * @param view The GeckoView that initiated the callback.
         * @param title The title sent from the content.
--- a/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java
+++ b/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java
@@ -154,28 +154,18 @@ public class GeckoViewActivity extends A
         @Override
         public void onPageStop(GeckoView view, boolean success) {
             Log.i(LOGTAG, "Stopping page load " + (success ? "successfully" : "unsuccessfully"));
             Log.i(LOGTAG, "zerdatime " + SystemClock.elapsedRealtime() +
                   " - page load stop");
         }
 
         @Override
-        public void onSecurityChange(GeckoView view, int status, GeckoBundle identity) {
-            String statusString;
-            if ((status & STATE_IS_BROKEN) != 0) {
-                statusString = "broken";
-            } else if ((status & STATE_IS_SECURE) != 0) {
-                statusString = "secure";
-            } else if ((status & STATE_IS_INSECURE) != 0) {
-                statusString = "insecure";
-            } else {
-                statusString = "unknown";
-            }
-            Log.i(LOGTAG, "Security status changed to " + statusString);
+        public void onSecurityChange(GeckoView view, SecurityInformation securityInfo) {
+            Log.i(LOGTAG, "Security status changed to " + securityInfo.securityMode);
         }
     }
 
     private class MyGeckoViewPermission implements GeckoView.PermissionDelegate {
 
         public int androidPermissionRequestCode = 1;
         private Callback mCallback;
 
--- a/mobile/android/modules/geckoview/GeckoViewProgress.jsm
+++ b/mobile/android/modules/geckoview/GeckoViewProgress.jsm
@@ -195,17 +195,17 @@ var IdentityHandler = {
     // .hostname can return an empty string in some exceptional cases -
     // hasMatchingOverride does not handle that, so avoid calling it.
     // Updating the tooltip value in those cases isn't critical.
     // FIXME: Fixing bug 646690 would probably makes this check unnecessary
     if (lastLocation.hostname &&
         this._overrideService.hasMatchingOverride(lastLocation.hostname,
                                                   (lastLocation.port || 443),
                                                   cert, {}, {})) {
-      result.security_exception = true;
+      result.securityException = true;
     }
     return result;
   },
 
   /**
    * Attempt to provide proper IDN treatment for host names
    */
   getEffectiveHost: function getEffectiveHost(aLastLocation, aUri) {
@@ -292,17 +292,16 @@ class GeckoViewProgress extends GeckoVie
 
     this._state = aState;
     this._hostChanged = false;
 
     let identity = IdentityHandler.checkIdentity(aState, this.browser);
 
     let message = {
       type: "GeckoView:SecurityChanged",
-      status: aState,
       identity: identity
     };
 
     this.eventDispatcher.sendRequest(message);
   }
 
   onLocationChange(aWebProgress, aRequest, aLocationURI, aFlags) {
     this._hostChanged = true;