Bug 1291366 - Part 2: Add o.m.geckoview.BuildConfig. r=sebastian draft
authorNick Alexander <nalexander@mozilla.com>
Wed, 14 Dec 2016 20:26:03 -0800
changeset 450561 8b0991fb6ab47bc02ca2b55be8fbaf397740e453
parent 450560 54164d685b9c2b1342b1acba2913ce07b906a7d6
child 450562 107febdd97899f29fa493925c70252738fb666b9
push id38898
push usernalexander@mozilla.com
push dateFri, 16 Dec 2016 23:58:40 +0000
reviewerssebastian
bugs1291366
milestone53.0a1
Bug 1291366 - Part 2: Add o.m.geckoview.BuildConfig. r=sebastian This is the first, mostly mechanical, introduction of a GeckoView specific BuildConfig. We have a few "debug logging" like checks. I introduced a MOZILLA_OFFICIAL abstraction and removed some of the checks as I saw fit. Subsequent patches will remove more of these checks. With this change applied, Gradle is broken, because there will be duplicate BuildConfig files included in the build. That will be fixed in subsequent patches. MozReview-Commit-ID: KHhV32o5j5A
mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
mobile/android/base/moz.build
mobile/android/geckoview/BuildConfig.java.in
mobile/android/geckoview/src/main/java/org/mozilla/gecko/AndroidGamepadManager.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/BaseGeckoInterface.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAccessibility.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoEditable.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoInputConnection.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoProfile.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoThread.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/InputMethods.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/SysInfo.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/DynamicToolbarAnimator.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/LayerRenderer.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/LayerView.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/OverscrollEdgeEffect.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/GeckoLoader.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/sqlite/MatrixBlobCursor.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/ActivityUtils.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/Clipboard.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/GeckoJarReader.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/HardwareCodecCapabilityUtils.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/HardwareUtils.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/PrefUtils.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/StringUtils.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/WindowUtils.java
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
@@ -2872,9 +2872,14 @@ public abstract class GeckoApp
         // We want to support the Screen Orientation API, and it always makes sense to lock the
         // orientation of a browser Activity, so we support locking.
         if (getRequestedOrientation() == requestedActivityInfoOrientation) {
             return false;
         }
         setRequestedOrientation(requestedActivityInfoOrientation);
         return true;
     }
+
+    @Override
+    public boolean isOfficial() {
+        return AppConstants.MOZILLA_OFFICIAL;
+    }
 }
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -2,19 +2,23 @@
 # vim: set filetype=python:
 # 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/.
 
 DIRS += ['locales']
 
 GENERATED_FILES += [
+    '../geckoview/generated/preprocessed/org/mozilla/geckoview/BuildConfig.java',
     'generated/preprocessed/org/mozilla/gecko/AdjustConstants.java',
     'generated/preprocessed/org/mozilla/gecko/AppConstants.java',
 ]
+w = GENERATED_FILES['../geckoview/generated/preprocessed/org/mozilla/geckoview/BuildConfig.java']
+w.script = 'generate_build_config.py'
+w.inputs += ['../geckoview/BuildConfig.java.in']
 x = GENERATED_FILES['generated/preprocessed/org/mozilla/gecko/AdjustConstants.java']
 x.script = 'generate_build_config.py'
 x.inputs += ['AdjustConstants.java.in']
 y = GENERATED_FILES['generated/preprocessed/org/mozilla/gecko/AppConstants.java']
 y.script = 'generate_build_config.py'
 y.inputs += ['AppConstants.java.in']
 
 include('android-services.mozbuild')
@@ -35,16 +39,17 @@ constants_jar.sources += [geckoview_sour
 constants_jar.sources += ['java/org/mozilla/gecko/' + x for x in [
     'adjust/AdjustHelperInterface.java',
     'adjust/AttributionHelperListener.java',
     'db/BrowserContract.java',
     'LocaleManager.java',
     'Locales.java',
 ]]
 constants_jar.generated_sources = [
+    '../geckoview/generated/preprocessed/org/mozilla/geckoview/BuildConfig.java',
     'generated/preprocessed/org/mozilla/gecko/AdjustConstants.java',
     'generated/preprocessed/org/mozilla/gecko/AppConstants.java',
 ]
 constants_jar.extra_jars = [
     CONFIG['ANDROID_SUPPORT_ANNOTATIONS_JAR_LIB'],
     CONFIG['ANDROID_SUPPORT_V4_AAR_LIB'],
     CONFIG['ANDROID_SUPPORT_V4_AAR_INTERNAL_LIB'],
     CONFIG['ANDROID_APPCOMPAT_V7_AAR_LIB'],
new file mode 100644
--- /dev/null
+++ b/mobile/android/geckoview/BuildConfig.java.in
@@ -0,0 +1,57 @@
+//#filter substitution
+/* -*- 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.geckoview;
+
+import android.os.Build;
+
+/**
+ * A collection of constants that pertain to the build state of the GeckoView
+ * library, sourced from build-time definitions.  This is a partial Java-side
+ * substitute for nsIXULAppInfo, amongst other things.
+ *
+ * See also SysInfo.java, which includes some of the values available from
+ * nsSystemInfo inside Gecko.
+ */
+public class BuildConfig {
+    public static final String GRE_MILESTONE = "@GRE_MILESTONE@";
+
+    public static final String MOZ_APP_ABI = "@MOZ_APP_ABI@";
+    public static final String MOZ_APP_BASENAME = "@MOZ_APP_BASENAME@";
+
+    // For the benefit of future archaeologists:
+    // GRE_BUILDID is exactly the same as MOZ_APP_BUILDID unless you're running
+    // on XULRunner, which is never the case on Android.
+    public static final String MOZ_APP_BUILDID = "@MOZ_BUILDID@";
+    public static final String MOZ_APP_ID = "@MOZ_APP_ID@";
+    public static final String MOZ_APP_NAME = "@MOZ_APP_NAME@";
+    public static final String MOZ_APP_VENDOR = "@MOZ_APP_VENDOR@";
+    public static final String MOZ_APP_VERSION = "@MOZ_APP_VERSION@";
+    public static final String MOZ_APP_DISPLAYNAME = "@MOZ_APP_DISPLAYNAME@";
+    public static final String MOZ_APP_UA_NAME = "@MOZ_APP_UA_NAME@";
+
+    // MOZILLA_VERSION is already quoted when it gets substituted in. If we
+    // add additional quotes we end up with ""x.y"", which is a syntax error.
+    public static final String MOZILLA_VERSION = @MOZILLA_VERSION@;
+    public static final String OMNIJAR_NAME = "@OMNIJAR_NAME@";
+
+    public static final String USER_AGENT_GECKOVIEW_MOBILE = "Mozilla/5.0 (Android " +
+        Build.VERSION.RELEASE + "; Mobile; rv:" +
+        MOZ_APP_VERSION + ") Gecko/" +
+        MOZ_APP_VERSION + " GeckoView/" +
+        MOZ_APP_VERSION;
+
+    public static final String USER_AGENT_GECKOVIEW_TABLET = "Mozilla/5.0 (Android " +
+        Build.VERSION.RELEASE + "; Tablet; rv:" +
+        MOZ_APP_VERSION + ") Gecko/" +
+        MOZ_APP_VERSION + " GeckoView/" +
+        MOZ_APP_VERSION;
+
+    /**
+     * Target CPU architecture: "armeabi-v7a", "x86, "mips", ..
+     */
+    public static final String ANDROID_CPU_ARCH = "@ANDROID_CPU_ARCH@";
+}
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/AndroidGamepadManager.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/AndroidGamepadManager.java
@@ -5,17 +5,16 @@
 
 package org.mozilla.gecko;
 
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Timer;
 import java.util.TimerTask;
 
-import org.mozilla.gecko.AppConstants.Versions;
 import org.mozilla.gecko.annotation.WrapForJNI;
 import org.mozilla.gecko.util.GamepadUtils;
 import org.mozilla.gecko.util.ThreadUtils;
 
 import android.content.Context;
 import android.hardware.input.InputManager;
 import android.os.Build;
 import android.util.SparseArray;
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/BaseGeckoInterface.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/BaseGeckoInterface.java
@@ -1,16 +1,17 @@
 /* -*- 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.mozilla.gecko.util.HardwareUtils;
+import org.mozilla.geckoview.BuildConfig;
 
 import android.app.Activity;
 import android.content.Context;
 import android.view.View;
 import android.widget.AbsoluteLayout;
 
 public class BaseGeckoInterface implements GeckoAppShell.GeckoInterface {
     // Bug 908744: Implement GeckoEventListener
@@ -45,18 +46,18 @@ public class BaseGeckoInterface implemen
     @Override
     public Activity getActivity() {
         // By default, GeckoView consumers do not have a distinguished current foreground Activity.
         return null;
     }
 
     @Override
     public String getDefaultUAString() {
-        return HardwareUtils.isTablet() ? AppConstants.USER_AGENT_FENNEC_TABLET :
-                                          AppConstants.USER_AGENT_FENNEC_MOBILE;
+        return HardwareUtils.isTablet() ? BuildConfig.USER_AGENT_GECKOVIEW_TABLET :
+                                          BuildConfig.USER_AGENT_GECKOVIEW_MOBILE;
     }
 
     // Bug 908775: Implement this
     @Override
     public void doRestart() {}
 
     @Override
     public void setFullScreen(final boolean fullscreen) {
@@ -157,9 +158,15 @@ public class BaseGeckoInterface implemen
         // By default, use the GeckoView-specific chrome URI.
         return "chrome://browser/content/geckoview.xul";
     }
 
     @Override
     public boolean isForegrounded() {
         return false;
     }
+
+    @Override
+    public boolean isOfficial() {
+        // By default, GeckoView consumers are not official Mozilla applications.
+        return false;
+    }
 }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAccessibility.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAccessibility.java
@@ -2,17 +2,16 @@
  * 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.JSONException;
 import org.json.JSONObject;
-import org.mozilla.gecko.AppConstants.Versions;
 import org.mozilla.gecko.util.GeckoBundle;
 import org.mozilla.gecko.util.ThreadUtils;
 import org.mozilla.gecko.util.UIAsyncTask;
 
 import android.content.Context;
 import android.graphics.Rect;
 import android.os.Build;
 import android.os.Bundle;
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java
@@ -1819,16 +1819,23 @@ public class GeckoAppShell
         /**
          * URI of the underlying chrome window to be opened, or null to use the default GeckoView
          * XUL container <tt>chrome://browser/content/geckoview.xul</tt>.  See
          * <a href="https://developer.mozilla.org/en/docs/toolkit.defaultChromeURI">https://developer.mozilla.org/en/docs/toolkit.defaultChromeURI</a>
          *
          * @return URI or null.
          */
         String getDefaultChromeURI();
+
+        /**
+         * Is this an official Mozilla application, like Firefox or Thunderbird?
+         *
+         * @return true if MOZILLA_OFFICIAL.
+         */
+        boolean isOfficial();
     };
 
     private static GeckoInterface sGeckoInterface;
 
     public static GeckoInterface getGeckoInterface() {
         return sGeckoInterface;
     }
 
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoEditable.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoEditable.java
@@ -9,17 +9,16 @@ import java.lang.reflect.Array;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.util.concurrent.ConcurrentLinkedQueue;
 
 import org.json.JSONObject;
-import org.mozilla.gecko.AppConstants.Versions;
 import org.mozilla.gecko.annotation.WrapForJNI;
 import org.mozilla.gecko.gfx.LayerView;
 import org.mozilla.gecko.mozglue.JNIObject;
 import org.mozilla.gecko.util.ThreadUtils;
 import org.mozilla.gecko.util.ThreadUtils.AssertBehavior;
 
 import android.graphics.RectF;
 import android.os.Handler;
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoInputConnection.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoInputConnection.java
@@ -5,17 +5,16 @@
 
 package org.mozilla.gecko;
 
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.util.concurrent.SynchronousQueue;
 
-import org.mozilla.gecko.AppConstants.Versions;
 import org.mozilla.gecko.gfx.DynamicToolbarAnimator;
 import org.mozilla.gecko.util.Clipboard;
 import org.mozilla.gecko.util.GamepadUtils;
 import org.mozilla.gecko.util.ThreadUtils;
 import org.mozilla.gecko.util.ThreadUtils.AssertBehavior;
 
 import android.annotation.SuppressLint;
 import android.annotation.TargetApi;
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoProfile.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoProfile.java
@@ -46,18 +46,18 @@ public final class GeckoProfile {
     private static final String CLIENT_ID_FILE_PATH = "datareporting/state.json";
     private static final String FHR_CLIENT_ID_FILE_PATH = "healthreport/state.json";
     // In the client ID file, the attribute title in the JSON object containing the client ID value.
     private static final String CLIENT_ID_JSON_ATTR = "clientID";
 
     private static final String TIMES_PATH = "times.json";
     private static final String PROFILE_CREATION_DATE_JSON_ATTR = "created";
 
-    // Only tests should need to do this.
-    // We can default this to AppConstants.RELEASE_OR_BETA once we fix Bug 1069687.
+    // Only tests should need to do this.  We can remove this entirely once we
+    // fix Bug 1069687.
     private static volatile boolean sAcceptDirectoryChanges = true;
 
     @RobocopTarget
     public static void enableDirectoryChanges() {
         Log.w(LOGTAG, "Directory changes should only be enabled for tests. And even then it's a bad idea.");
         sAcceptDirectoryChanges = true;
     }
 
@@ -222,19 +222,16 @@ public final class GeckoProfile {
                 args = null;
             }
 
             return GeckoProfile.initFromArgs(context, args);
 
         } else if (profileName == null) {
             // If only profile dir was passed in, use custom (anonymous) profile.
             profileName = CUSTOM_PROFILE;
-
-        } else if (AppConstants.DEBUG_BUILD) {
-            Log.v(LOGTAG, "Fetching profile: '" + profileName + "', '" + profileDir + "'");
         }
 
         // We require the profile dir to exist if specified, so create it here if needed.
         final boolean init = profileDir != null && profileDir.mkdirs();
 
         // Actually try to look up the profile.
         GeckoProfile profile = sProfileCache.get(profileName);
         GeckoProfile newProfile = null;
@@ -262,21 +259,16 @@ public final class GeckoProfile {
             } catch (final IOException e) {
             }
 
             if (!consistent) {
                 if (!sAcceptDirectoryChanges || !profileDir.isDirectory()) {
                     throw new IllegalStateException(
                             "Refusing to reuse profile with a different directory.");
                 }
-
-                if (AppConstants.RELEASE_OR_BETA) {
-                    Log.e(LOGTAG, "Release build trying to switch out profile dir. " +
-                                  "This is an error, but let's do what we can.");
-                }
                 profile.setDir(profileDir);
             }
         }
 
         if (init) {
             // Initialize the profile directory if we had to create it.
             profile.enqueueInitialization(profileDir);
         }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoThread.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoThread.java
@@ -461,17 +461,18 @@ public class GeckoThread extends Thread 
         args.add(apkPath);
 
         addCustomProfileArg(mArgs, args);
 
         // In un-official builds, we want to load Javascript resources fresh
         // with each build.  In official builds, the startup cache is purged by
         // the buildid mechanism, but most un-official builds don't bump the
         // buildid, so we purge here instead.
-        if (!AppConstants.MOZILLA_OFFICIAL) {
+        final GeckoAppShell.GeckoInterface gi = GeckoAppShell.getGeckoInterface();
+        if (gi == null || !gi.isOfficial()) {
             Log.w(LOGTAG, "STARTUP PERFORMANCE WARNING: un-official build: purging the " +
                           "startup (JavaScript) caches.");
             args.add("-purgecaches");
         }
 
         return args.toArray(new String[args.size()]);
     }
 
@@ -535,19 +536,19 @@ public class GeckoThread extends Thread 
         ThreadUtils.postToUiThread(new Runnable() {
             @Override public void run() {
                 registerUiThread();
             }
         });
 
         Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - runGecko");
 
-        if (!AppConstants.MOZILLA_OFFICIAL) {
-            String msg = new String("RunGecko - args =" + TextUtils.join(" ", args));
-            Log.i(LOGTAG, msg);
+        final GeckoAppShell.GeckoInterface gi = GeckoAppShell.getGeckoInterface();
+        if (gi == null || !gi.isOfficial()) {
+            Log.i(LOGTAG, "RunGecko - args = " + args);
         }
 
         // And go.
         GeckoLoader.nativeRun(args, mCrashFileDescriptor, mIPCFileDescriptor);
 
         // And... we're done.
         setState(State.EXITED);
 
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/InputMethods.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/InputMethods.java
@@ -2,18 +2,16 @@
  * 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 java.util.Collection;
 
-import org.mozilla.gecko.AppConstants.Versions;
-
 import android.content.Context;
 import android.os.Build;
 import android.provider.Settings.Secure;
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodManager;
 
 final public class InputMethods {
     public static final String METHOD_ANDROID_LATINIME = "com.android.inputmethod.latin/.LatinIME";
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/SysInfo.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/SysInfo.java
@@ -13,18 +13,18 @@ import java.io.FileFilter;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 
 import java.util.regex.Pattern;
 
 /**
  * A collection of system info values, broadly mirroring a subset of
- * nsSystemInfo. See also the constants in AppConstants, which reflect
- * much of nsIXULAppInfo.
+ * nsSystemInfo. See also the constants in org.mozilla.geckoview.BuildConfig,
+ * which reflect much of nsIXULAppInfo.
  */
 // Normally, we'd annotate with @RobocopTarget.  Since SysInfo is compiled
 // before RobocopTarget, we instead add o.m.g.SysInfo directly to the Proguard
 // configuration.
 public final class SysInfo {
     private static final String LOG_TAG = "GeckoSysInfo";
 
     // Number of bytes of /proc/meminfo to read in one go.
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/DynamicToolbarAnimator.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/DynamicToolbarAnimator.java
@@ -1,16 +1,15 @@
 /* -*- 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.gfx;
 
-import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.PrefsHelper;
 import org.mozilla.gecko.util.FloatUtils;
 import org.mozilla.gecko.util.ThreadUtils;
 
 import android.graphics.PointF;
 import android.support.v4.view.ViewCompat;
 import android.util.Log;
 import android.view.MotionEvent;
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
@@ -5,17 +5,16 @@
 
 package org.mozilla.gecko.gfx;
 
 import org.mozilla.gecko.annotation.RobocopTarget;
 import org.mozilla.gecko.annotation.WrapForJNI;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.gfx.LayerView.DrawListener;
 import org.mozilla.gecko.util.FloatUtils;
-import org.mozilla.gecko.AppConstants;
 
 import android.content.Context;
 import android.graphics.Color;
 import android.graphics.Matrix;
 import android.graphics.PointF;
 import android.graphics.RectF;
 import android.os.SystemClock;
 import android.util.DisplayMetrics;
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/LayerRenderer.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/LayerRenderer.java
@@ -1,16 +1,15 @@
 /* -*- 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.gfx;
 
-import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.mozglue.DirectBufferAllocator;
 
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Matrix;
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/LayerView.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/LayerView.java
@@ -6,18 +6,16 @@
 package org.mozilla.gecko.gfx;
 
 import java.nio.ByteBuffer;
 import java.nio.IntBuffer;
 
 import org.mozilla.gecko.AndroidGamepadManager;
 import org.mozilla.gecko.annotation.RobocopTarget;
 import org.mozilla.gecko.annotation.WrapForJNI;
-import org.mozilla.gecko.AppConstants;
-import org.mozilla.gecko.AppConstants.Versions;
 import org.mozilla.gecko.GeckoAccessibility;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.GeckoThread;
 import org.mozilla.gecko.mozglue.JNIObject;
 import org.mozilla.gecko.util.ThreadUtils;
 
 import android.content.Context;
 import android.graphics.Canvas;
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/OverscrollEdgeEffect.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/OverscrollEdgeEffect.java
@@ -1,17 +1,15 @@
 /* -*- 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.gfx;
 
-import org.mozilla.gecko.AppConstants.Versions;
-
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.PointF;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffXfermode;
 import android.os.Build;
 import android.widget.EdgeEffect;
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/GeckoLoader.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/GeckoLoader.java
@@ -19,17 +19,17 @@ import android.content.Context;
 import android.content.Intent;
 import android.os.Build;
 import android.os.Environment;
 import java.util.ArrayList;
 import android.util.Log;
 
 import org.mozilla.gecko.annotation.JNITarget;
 import org.mozilla.gecko.annotation.RobocopTarget;
-import org.mozilla.gecko.AppConstants;
+import org.mozilla.geckoview.BuildConfig;
 
 public final class GeckoLoader {
     private static final String LOGTAG = "GeckoLoader";
 
     private static volatile SafeIntent sIntent;
     private static File sCacheFile;
     private static File sGREDir;
 
@@ -352,17 +352,17 @@ public final class GeckoLoader {
 
     private static String getLoadDiagnostics(final Context context, final String lib) {
         final String androidPackageName = context.getPackageName();
 
         final StringBuilder message = new StringBuilder("LOAD ");
         message.append(lib);
 
         // These might differ. If so, we know why the library won't load!
-        message.append(": ABI: " + AppConstants.MOZ_APP_ABI + ", " + getCPUABI());
+        message.append(": ABI: " + BuildConfig.MOZ_APP_ABI + ", " + getCPUABI());
         message.append(": Data: " + context.getApplicationInfo().dataDir);
         try {
             final boolean appLibExists = new File("/data/app-lib/" + androidPackageName + "/lib" + lib + ".so").exists();
             final boolean dataDataExists = new File("/data/data/" + androidPackageName + "/lib/lib" + lib + ".so").exists();
             message.append(", ax=" + appLibExists);
             message.append(", ddx=" + dataDataExists);
         } catch (Throwable e) {
             message.append(": ax/ddx fail, ");
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/sqlite/MatrixBlobCursor.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/sqlite/MatrixBlobCursor.java
@@ -16,17 +16,16 @@
  */
 
 package org.mozilla.gecko.sqlite;
 
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 
 import org.mozilla.gecko.annotation.JNITarget;
-import org.mozilla.gecko.AppConstants;
 
 import android.database.AbstractCursor;
 import android.database.CursorIndexOutOfBoundsException;
 import android.util.Log;
 
 /**
  * A mutable cursor implementation backed by an array of {@code Object}s. Use
  * {@link #newRow()} to add rows. Automatically expands internal capacity
@@ -61,19 +60,17 @@ public class MatrixBlobCursor extends Ab
         this.columnNames = columnNames;
         this.columnCount = columnNames.length;
 
         if (initialCapacity < 1) {
             initialCapacity = 1;
         }
 
         this.data = new Object[columnCount * initialCapacity];
-        if (AppConstants.DEBUG_BUILD) {
-            this.allocationStack = new Throwable("allocationStack");
-        }
+        this.allocationStack = new Throwable("allocationStack");
     }
 
     /**
      * Constructs a new cursor.
      *
      * @param columnNames names of the columns, the ordering of which
      *  determines column ordering elsewhere in this cursor
      */
@@ -350,17 +347,15 @@ public class MatrixBlobCursor extends Ab
 
     @Override
     public boolean isNull(int column) {
         return get(column) == null;
     }
 
     @Override
     protected void finalize() {
-        if (AppConstants.DEBUG_BUILD) {
-            if (!isClosed()) {
-                Log.e(LOGTAG, "Cursor finalized without being closed", this.allocationStack);
-            }
+        if (!isClosed()) {
+            Log.e(LOGTAG, "Cursor finalized without being closed", this.allocationStack);
         }
 
         super.finalize();
     }
 }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/ActivityUtils.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/ActivityUtils.java
@@ -7,18 +7,16 @@ package org.mozilla.gecko.util;
 
 import android.app.Activity;
 import android.content.Intent;
 import android.os.Build;
 import android.view.View;
 import android.view.Window;
 import android.view.WindowManager;
 
-import org.mozilla.gecko.AppConstants.Versions;
-
 public class ActivityUtils {
     private ActivityUtils() {
     }
 
     public static void setFullScreen(Activity activity, boolean fullscreen) {
         // Hide/show the system notification bar
         Window window = activity.getWindow();
 
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/Clipboard.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/Clipboard.java
@@ -2,17 +2,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/. */
 
 package org.mozilla.gecko.util;
 
 import java.util.concurrent.SynchronousQueue;
 
 import org.mozilla.gecko.annotation.WrapForJNI;
-import org.mozilla.gecko.AppConstants.Versions;
 
 import android.content.ClipData;
 import android.content.Context;
 import android.util.Log;
 
 public final class Clipboard {
     // Volatile but not synchronized: we don't care about the race condition in
     // init, because both app contexts will be the same, but we do care about a
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/GeckoJarReader.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/GeckoJarReader.java
@@ -4,20 +4,21 @@
 
 package org.mozilla.gecko.util;
 
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.drawable.BitmapDrawable;
 import android.util.Log;
+
 import org.mozilla.gecko.annotation.RobocopTarget;
-import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.mozglue.GeckoLoader;
 import org.mozilla.gecko.mozglue.NativeZip;
+import org.mozilla.geckoview.BuildConfig;
 
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
@@ -251,11 +252,11 @@ public final class GeckoJarReader {
     /**
      * Encodes its resource path correctly.
      */
     @RobocopTarget
     public static String computeJarURI(String resourcePath, String pathInsideJAR) {
         final String resURI = new File(resourcePath).toURI().toString();
 
         // TODO: do we need to encode the file path, too?
-        return "jar:jar:" + resURI + "!/" + AppConstants.OMNIJAR_NAME + "!/" + pathInsideJAR;
+        return "jar:jar:" + resURI + "!/" + BuildConfig.OMNIJAR_NAME + "!/" + pathInsideJAR;
     }
 }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/HardwareCodecCapabilityUtils.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/HardwareCodecCapabilityUtils.java
@@ -2,17 +2,16 @@
  *  * 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.util;
 
 import org.mozilla.gecko.annotation.WrapForJNI;
-import org.mozilla.gecko.AppConstants.Versions;
 
 import android.media.MediaCodec;
 import android.media.MediaCodecInfo;
 import android.media.MediaCodecInfo.CodecCapabilities;
 import android.media.MediaCodecList;
 import android.os.Build;
 import android.util.Log;
 
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/HardwareUtils.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/HardwareUtils.java
@@ -1,24 +1,25 @@
 /* -*- 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.util;
 
-import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.SysInfo;
 
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.os.Build;
 import android.util.Log;
-import android.view.ViewConfiguration;
+
+import org.mozilla.gecko.SysInfo;
+import org.mozilla.geckoview.BuildConfig;
 
 public final class HardwareUtils {
     private static final String LOGTAG = "GeckoHardwareUtils";
 
     private static final boolean IS_AMAZON_DEVICE = Build.MANUFACTURER.equalsIgnoreCase("Amazon");
     public static final boolean IS_KINDLE_DEVICE = IS_AMAZON_DEVICE &&
                                                    (Build.MODEL.equals("Kindle Fire") ||
                                                     Build.MODEL.startsWith("KF"));
@@ -81,24 +82,24 @@ public final class HardwareUtils {
     /**
      * @return false if the current system is not supported (e.g. APK/system ABI mismatch).
      */
     public static boolean isSupportedSystem() {
         // See http://developer.android.com/ndk/guides/abis.html
         boolean isSystemARM = Build.CPU_ABI != null && Build.CPU_ABI.startsWith("arm");
         boolean isSystemX86 = Build.CPU_ABI != null && Build.CPU_ABI.startsWith("x86");
 
-        boolean isAppARM = AppConstants.ANDROID_CPU_ARCH.startsWith("arm");
-        boolean isAppX86 = AppConstants.ANDROID_CPU_ARCH.startsWith("x86");
+        boolean isAppARM = BuildConfig.ANDROID_CPU_ARCH.startsWith("arm");
+        boolean isAppX86 = BuildConfig.ANDROID_CPU_ARCH.startsWith("x86");
 
         // Only reject known incompatible ABIs. Better safe than sorry.
         if ((isSystemX86 && isAppARM) || (isSystemARM && isAppX86)) {
             return false;
         }
 
         if ((isSystemX86 && isAppX86) || (isSystemARM && isAppARM)) {
             return true;
         }
 
-        Log.w(LOGTAG, "Unknown app/system ABI combination: " + AppConstants.MOZ_APP_ABI + " / " + Build.CPU_ABI);
+        Log.w(LOGTAG, "Unknown app/system ABI combination: " + BuildConfig.MOZ_APP_ABI + " / " + Build.CPU_ABI);
         return true;
     }
 }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/PrefUtils.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/PrefUtils.java
@@ -5,17 +5,16 @@
 
 package org.mozilla.gecko.util;
 
 import java.util.HashSet;
 import java.util.Set;
 
 import org.json.JSONArray;
 import org.json.JSONException;
-import org.mozilla.gecko.AppConstants.Versions;
 
 import android.content.SharedPreferences;
 import android.util.Log;
 
 
 public class PrefUtils {
     private static final String LOGTAG = "GeckoPrefUtils";
 
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/StringUtils.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/StringUtils.java
@@ -4,18 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.util;
 
 import android.net.Uri;
 import android.support.annotation.NonNull;
 import android.text.TextUtils;
 
-import org.mozilla.gecko.AppConstants.Versions;
-
 import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
 
 public class StringUtils {
     private static final String LOGTAG = "GeckoStringUtils";
 
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/WindowUtils.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/WindowUtils.java
@@ -1,17 +1,15 @@
 /* -*- 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.util;
 
-import org.mozilla.gecko.AppConstants.Versions;
-
 import android.content.Context;
 import android.os.Build;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.Display;
 import android.view.WindowManager;
 
 import java.lang.reflect.Method;