Bug 1357630 - infer: (NULL_DEREFERENCE) add null-check to getAppEventDispatcher draft
authorAndrzej Hunt <ahunt@mozilla.com>
Tue, 18 Apr 2017 20:10:44 -0700
changeset 564859 1a1ce9e5142f6f5cbc73a5ed41e727dbf44346c7
parent 564555 67f7adf75890d72d7200710c136a938b6001ee96
child 564884 0589cc87b47a619019f2c68325e53a8bd006ce6c
push id54704
push userahunt@mozilla.com
push dateWed, 19 Apr 2017 03:12:14 +0000
bugs1357630
milestone55.0a1
Bug 1357630 - infer: (NULL_DEREFERENCE) add null-check to getAppEventDispatcher Every single caller of getAppEventDispatcher() and getEventDispatcher() assumes a non-null return value, so let's make sure we're actually returning a non-null value. This commit doesn't effectively change runtime behaviour (any previously NPE crashes will now result in a crash due to IllegalStateException), however we now at least have an obvious error message in that situation. In reality, no code should run before onCreate(), so this should realistically never happen - but we should still check to ensure that is the case. (This removes 28 infer NULL_DEREFERENCE warnings.) MozReview-Commit-ID: GhzwKWfkAbD
mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
@@ -1870,24 +1870,28 @@ public abstract class GeckoApp
         }
 
         final GeckoBundle restoreData = new GeckoBundle(1);
         restoreData.putString("sessionString", sessionString);
         return restoreData;
     }
 
     @RobocopTarget
-    public static EventDispatcher getEventDispatcher() {
+    public static @NonNull EventDispatcher getEventDispatcher() {
         final GeckoApp geckoApp = (GeckoApp) GeckoAppShell.getGeckoInterface();
         return geckoApp.getAppEventDispatcher();
     }
 
     @Override
-    public EventDispatcher getAppEventDispatcher() {
-        return mLayerView != null ? mLayerView.getEventDispatcher() : null;
+    public @NonNull EventDispatcher getAppEventDispatcher() {
+        if (mLayerView == null) {
+            throw new IllegalStateException("Must not call getAppEventDispatcher() until after onCreate()");
+        }
+
+        return mLayerView.getEventDispatcher();
     }
 
     @Override
     public GeckoProfile getProfile() {
         return GeckoThread.getActiveProfile();
     }
 
     /**
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java
@@ -71,16 +71,17 @@ import android.location.LocationManager;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Looper;
 import android.os.Vibrator;
 import android.provider.Settings;
+import android.support.annotation.NonNull;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.ContextThemeWrapper;
 import android.view.Display;
 import android.view.HapticFeedbackConstants;
 import android.view.View;
 import android.view.WindowManager;
@@ -1655,17 +1656,17 @@ public class GeckoAppShell
 
     public interface AppStateListener {
         public void onPause();
         public void onResume();
         public void onOrientationChanged();
     }
 
     public interface GeckoInterface {
-        public EventDispatcher getAppEventDispatcher();
+        public @NonNull EventDispatcher getAppEventDispatcher();
         public GeckoProfile getProfile();
         public Activity getActivity();
         public String getDefaultUAString();
         public void doRestart();
 
         /**
          * This API doesn't make sense for arbitrary GeckoView consumers. In future, consider an
          * API like Android WebView's, which provides a View to the consumer to display fullscreen.