Bug 1512274 - [geckoview] Don't change value of method arguments. r=geckoview-reviewers,snorp
☠☠ backed out by 1f911d12fd07 ☠ ☠
authorAgi Sferro <agi@mozilla.com>
Fri, 15 Mar 2019 18:08:34 +0000
changeset 522084 3812d67603799766ab89a8ee5d4fdfd1c376d0ce
parent 522083 b063e2b487b6691582a935b3a407abcd5bc26782
child 522085 58642fa9c95b0aad2f6adae8b8005f17e41541fc
push id10871
push usercbrindusan@mozilla.com
push dateMon, 18 Mar 2019 15:49:32 +0000
treeherdermozilla-beta@018abdd16060 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgeckoview-reviewers, snorp
bugs1512274
milestone67.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 1512274 - [geckoview] Don't change value of method arguments. r=geckoview-reviewers,snorp Differential Revision: https://phabricator.services.mozilla.com/D23682
mobile/android/geckoview/src/main/java/org/mozilla/gecko/CrashHandler.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoProfile.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoScreenOrientation.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/PrefsHelper.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/SysInfo.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoSurfaceTexture.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/StackScroller.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/ByteBufferInputStream.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/FileUtils.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/GamepadUtils.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/GeckoJarReader.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/IOUtils.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/StringUtils.java
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoEditable.java
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoInputConnection.java
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/PanZoomController.java
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/CrashHandler.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/CrashHandler.java
@@ -51,21 +51,21 @@ public class CrashHandler implements Thr
     protected final Class<? extends Service> handlerService;
 
     /**
      * Get the root exception from the 'cause' chain of an exception.
      *
      * @param exc An exception
      * @return The root exception
      */
-    public static Throwable getRootException(Throwable exc) {
-        for (Throwable cause = exc; cause != null; cause = cause.getCause()) {
-            exc = cause;
-        }
-        return exc;
+    public static Throwable getRootException(final Throwable exc) {
+        Throwable cause;
+        for (cause = exc; cause != null; cause = cause.getCause()) {}
+
+        return cause;
     }
 
     /**
      * Get the standard stack trace string of an exception.
      *
      * @param exc An exception
      * @return The exception stack trace.
      */
@@ -448,38 +448,40 @@ public class CrashHandler implements Thr
      */
     @Override
     public void uncaughtException(Thread thread, Throwable exc) {
         if (this.crashing) {
             // Prevent possible infinite recusions.
             return;
         }
 
-        if (thread == null) {
+        Thread resolvedThread = thread;
+        if (resolvedThread == null) {
             // Gecko may pass in null for thread to denote the current thread.
-            thread = Thread.currentThread();
+            resolvedThread = Thread.currentThread();
         }
 
         try {
+            Throwable rootException = exc;
             if (!this.unregistered) {
                 // Only process crash ourselves if we have not been unregistered.
 
                 this.crashing = true;
-                exc = getRootException(exc);
-                logException(thread, exc);
+                rootException = getRootException(exc);
+                logException(resolvedThread, rootException);
 
-                if (reportException(thread, exc)) {
+                if (reportException(resolvedThread, rootException)) {
                     // Reporting succeeded; we can terminate our process now.
                     return;
                 }
             }
 
             if (systemUncaughtHandler != null) {
                 // Follow the chain of uncaught handlers.
-                systemUncaughtHandler.uncaughtException(thread, exc);
+                systemUncaughtHandler.uncaughtException(resolvedThread, rootException);
             }
         } finally {
             terminateProcess();
         }
     }
 
     public static CrashHandler createDefaultCrashHandler(final Context context) {
         return new CrashHandler(context, null) {
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java
@@ -1416,34 +1416,38 @@ public class GeckoAppShell
                 process.destroy();
             }
         }
     }
 
     @WrapForJNI(calledFrom = "gecko")
     private static byte[] getIconForExtension(String aExt, int iconSize) {
         try {
-            if (iconSize <= 0)
-                iconSize = 16;
+            int resolvedIconSize = iconSize;
+            if (iconSize <= 0) {
+                resolvedIconSize = 16;
+            }
 
-            if (aExt != null && aExt.length() > 1 && aExt.charAt(0) == '.')
-                aExt = aExt.substring(1);
+            String resolvedExt = aExt;
+            if (aExt != null && aExt.length() > 1 && aExt.charAt(0) == '.') {
+                resolvedExt = aExt.substring(1);
+            }
 
             PackageManager pm = getApplicationContext().getPackageManager();
-            Drawable icon = getDrawableForExtension(pm, aExt);
+            Drawable icon = getDrawableForExtension(pm, resolvedExt);
             if (icon == null) {
                 // Use a generic icon
                 icon = pm.getDefaultActivityIcon();
             }
 
             Bitmap bitmap = ((BitmapDrawable)icon).getBitmap();
-            if (bitmap.getWidth() != iconSize || bitmap.getHeight() != iconSize)
-                bitmap = Bitmap.createScaledBitmap(bitmap, iconSize, iconSize, true);
+            if (bitmap.getWidth() != resolvedIconSize || bitmap.getHeight() != resolvedIconSize)
+                bitmap = Bitmap.createScaledBitmap(bitmap, resolvedIconSize, resolvedIconSize, true);
 
-            ByteBuffer buf = ByteBuffer.allocate(iconSize * iconSize * 4);
+            ByteBuffer buf = ByteBuffer.allocate(resolvedIconSize * resolvedIconSize * 4);
             bitmap.copyPixelsToBuffer(buf);
 
             return buf.array();
         }
         catch (Exception e) {
             Log.w(LOGTAG, "getIconForExtension failed.",  e);
             return null;
         }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoProfile.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoProfile.java
@@ -213,47 +213,48 @@ public final class GeckoProfile {
         //     No     |    Yes    | Profile with specified name at default dir.
         //     Yes    |    No     | Custom (anonymous) profile with specified dir.
         //     No     |    No     | Profile with specified name at specified dir.
         //
         // Empty name?| Null dir? | Returned profile
         // ------------------------------------------
         //     Yes    |    Yes    | Active profile or default profile
 
+        String resolvedProfileName = profileName;
         if (TextUtils.isEmpty(profileName) && profileDir == null) {
             // If no profile info was passed in, look for the active profile or a default profile.
             final GeckoProfile profile = GeckoThread.getActiveProfile();
             if (profile != null) {
                 informIfCustomProfileIsUnavailable(profileName, true);
                 return profile;
             }
 
             informIfCustomProfileIsUnavailable(profileName, false);
             return GeckoProfile.initFromArgs(context, sIntentArgs);
         } else if (profileName == null) {
             // If only profile dir was passed in, use custom (anonymous) profile.
-            profileName = CUSTOM_PROFILE;
+            resolvedProfileName = CUSTOM_PROFILE;
         }
 
         // 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 profile = sProfileCache.get(resolvedProfileName);
         GeckoProfile newProfile = null;
 
         if (profile == null) {
             try {
-                newProfile = new GeckoProfile(context, profileName, profileDir);
+                newProfile = new GeckoProfile(context, resolvedProfileName, profileDir);
             } catch (NoMozillaDirectoryException e) {
                 // We're unable to do anything sane here.
                 throw new RuntimeException(e);
             }
 
-            profile = sProfileCache.putIfAbsent(profileName, newProfile);
+            profile = sProfileCache.putIfAbsent(resolvedProfileName, newProfile);
         }
 
         if (profile == null) {
             profile = newProfile;
 
         } else if (profileDir != null) {
             // We have an existing profile but was given an alternate directory.
             boolean consistent = false;
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoScreenOrientation.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoScreenOrientation.java
@@ -159,31 +159,32 @@ public class GeckoScreenOrientation {
             return false;
         }
         mScreenOrientation = aScreenOrientation;
         Log.d(LOGTAG, "updating to new orientation " + mScreenOrientation);
         notifyListeners(mScreenOrientation);
         if (mShouldNotify) {
             // Gecko expects a definite screen orientation, so we default to the
             // primary orientations.
+            ScreenOrientation primaryOrientation = aScreenOrientation;
             if (aScreenOrientation == ScreenOrientation.PORTRAIT) {
-                aScreenOrientation = ScreenOrientation.PORTRAIT_PRIMARY;
+                primaryOrientation = ScreenOrientation.PORTRAIT_PRIMARY;
             } else if (aScreenOrientation == ScreenOrientation.LANDSCAPE) {
-                aScreenOrientation = ScreenOrientation.LANDSCAPE_PRIMARY;
+                primaryOrientation = ScreenOrientation.LANDSCAPE_PRIMARY;
             } else if (aScreenOrientation == ScreenOrientation.DEFAULT) {
-                aScreenOrientation = ScreenOrientation.PORTRAIT_PRIMARY;
+                primaryOrientation = ScreenOrientation.PORTRAIT_PRIMARY;
             } else if (aScreenOrientation == ScreenOrientation.NONE) {
                 return false;
             }
 
             if (GeckoThread.isRunning()) {
-                onOrientationChange(aScreenOrientation.value, getAngle());
+                onOrientationChange(primaryOrientation.value, getAngle());
             } else {
                 GeckoThread.queueNativeCall(GeckoScreenOrientation.class, "onOrientationChange",
-                                            aScreenOrientation.value, getAngle());
+                                            primaryOrientation.value, getAngle());
             }
         }
         ScreenManagerHelper.refreshScreenInfo();
         return true;
     }
 
     private void notifyListeners(final ScreenOrientation newOrientation) {
         final Runnable notifier = new Runnable() {
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/PrefsHelper.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/PrefsHelper.java
@@ -204,23 +204,28 @@ public final class PrefsHelper {
         } else {
             GeckoThread.queueNativeCallUntil(
                     GeckoThread.State.PROFILE_READY, PrefsHelper.class, "nativeRemoveObserver",
                     String[].class, namesToUnobserve);
         }
     }
 
     @WrapForJNI(calledFrom = "gecko")
-    private static void callPrefHandler(final PrefHandler handler, int type, final String pref,
-                                        boolean boolVal, int intVal, String strVal) {
+    private static void callPrefHandler(final PrefHandler handler, final int originalType,
+                                        final String pref, final boolean originalBoolVal,
+                                        final int intVal, final String originalStrVal) {
 
         // Some Gecko preferences use integers or strings to reference state instead of
         // directly representing the value.  Since the Java UI uses the type to determine
         // which ui elements to show and how to handle them, we need to normalize these
         // preferences to the correct type.
+        int type = originalType;
+        String strVal = originalStrVal;
+        boolean boolVal = originalBoolVal;
+
         if (INT_TO_STRING_PREFS.contains(pref)) {
             type = PREF_STRING;
             strVal = String.valueOf(intVal);
         } else if (INT_TO_BOOL_PREFS.contains(pref)) {
             type = PREF_BOOL;
             boolVal = intVal == 1;
         }
 
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/SysInfo.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/SysInfo.java
@@ -104,27 +104,26 @@ public final class SysInfo {
      * @return the first uninterrupted sequence of digits following the
      *         specified index, parsed as an integer value in KB.
      */
     private static int extractMemValue(byte[] buffer, int offset, int length) {
         if (offset >= length) {
             return 0;
         }
 
-        while (offset < length && buffer[offset] != '\n') {
-            if (buffer[offset] >= '0' && buffer[offset] <= '9') {
-                int start = offset++;
-                while (offset < length &&
-                       buffer[offset] >= '0' &&
-                       buffer[offset] <= '9') {
-                    ++offset;
+        int i = offset;
+        while (i < length && buffer[i] != '\n') {
+            if (buffer[i] >= '0' && buffer[i] <= '9') {
+                int start = i++;
+                while (i < length && buffer[i] >= '0' && buffer[i] <= '9') {
+                    ++i;
                 }
-                return Integer.parseInt(new String(buffer, start, offset - start), 10);
+                return Integer.parseInt(new String(buffer, start, i - start), 10);
             }
-            ++offset;
+            ++i;
         }
         return 0;
     }
 
     /**
      * Fetch the total memory of the device in MB by parsing /proc/meminfo.
      *
      * Of course, Android doesn't have a neat and tidy way to find total
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoSurfaceTexture.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoSurfaceTexture.java
@@ -256,34 +256,35 @@ import org.mozilla.gecko.mozglue.JNIObje
         synchronized (sSurfaceTextures) {
             // We want to limit the maximum number of SurfaceTextures at any one time.
             // This is because they use a large number of fds, and once the process' limit
             // is reached bad things happen. See bug 1421586.
             if (sSurfaceTextures.size() >= MAX_SURFACE_TEXTURES) {
                 return null;
             }
 
-            if (handle == 0) {
+            int resolvedHandle = handle;
+            if (resolvedHandle == 0) {
                 // Generate new handle value when none specified.
-                handle = sNextHandle++;
+                resolvedHandle = sNextHandle++;
             }
 
             final GeckoSurfaceTexture gst;
             if (isSingleBufferSupported()) {
-                gst = new GeckoSurfaceTexture(handle, singleBufferMode);
+                gst = new GeckoSurfaceTexture(resolvedHandle, singleBufferMode);
             } else {
-                gst = new GeckoSurfaceTexture(handle);
+                gst = new GeckoSurfaceTexture(resolvedHandle);
             }
 
-            if (sSurfaceTextures.containsKey(handle)) {
+            if (sSurfaceTextures.containsKey(resolvedHandle)) {
                 gst.release();
                 throw new IllegalArgumentException("Already have a GeckoSurfaceTexture with that handle");
             }
 
-            sSurfaceTextures.put(handle, gst);
+            sSurfaceTextures.put(resolvedHandle, gst);
             return gst;
         }
     }
 
     @WrapForJNI
     public static GeckoSurfaceTexture lookup(int handle) {
         synchronized (sSurfaceTextures) {
             return sSurfaceTextures.get(handle);
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/StackScroller.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/StackScroller.java
@@ -119,27 +119,27 @@ import org.mozilla.gecko.annotation.Wrap
      * Sets where the scroll will end.  Valid only for "fling" scrolls.
      *
      * @param x The final X offset as an absolute distance from the origin.
      */
     public final void setFinalX(int x) {
         mScrollerX.setFinalPosition(x);
     }
 
-    private static float viscousFluid(float x) {
-        x *= sViscousFluidScale;
-        if (x < 1.0f) {
-            x -= (1.0f - (float) Math.exp(-x));
+    private static float viscousFluid(final float x) {
+        float y = x * sViscousFluidScale;
+        if (y < 1.0f) {
+            y -= (1.0f - (float) Math.exp(-y));
         } else {
             float start = 0.36787944117f; // 1/e == exp(-1)
-            x = 1.0f - (float) Math.exp(1.0f - x);
-            x = start + x * (1.0f - start);
+            y = 1.0f - (float) Math.exp(1.0f - y);
+            y = start + y * (1.0f - start);
         }
-        x *= sViscousFluidNormalize;
-        return x;
+        y *= sViscousFluidNormalize;
+        return y;
     }
 
     /**
      * Call this when you want to know the new location. If it returns true, the
      * animation is not yet finished.
      */
     public boolean computeScrollOffset(long time) {
         if (isFinished()) {
@@ -250,37 +250,41 @@ import org.mozilla.gecko.annotation.Wrap
      * @param maxY Maximum Y value. The scroller will not scroll past this point
      *            unless overY > 0. If overfling is allowed, it will use maxY as
      *            a springback boundary.
      * @param overX Overfling range. If > 0, horizontal overfling in either
      *            direction will be possible.
      * @param overY Overfling range. If > 0, vertical overfling in either
      *            direction will be possible.
      */
-    public void fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX,
-            int minY, int maxY, int overX, int overY, long time) {
+    public void fling(final int startX, final int startY, final int velocityX, final int velocityY,
+                      final int minX, final int maxX, final int minY, final int maxY,
+                      final int overX, final int overY, final long time) {
+        int newVelocityX = velocityX;
+        int newVelocityY = velocityY;
+
         // Continue a scroll or fling in progress
         if (mFlywheel && !isFinished()) {
             float oldVelocityX = mScrollerX.mCurrVelocity;
             float oldVelocityY = mScrollerY.mCurrVelocity;
-            boolean sameXDirection = (velocityX == 0) || (oldVelocityX == 0) ||
-                ((velocityX < 0) == (oldVelocityX < 0));
-            boolean sameYDirection = (velocityY == 0) || (oldVelocityY == 0) ||
-                ((velocityY < 0) == (oldVelocityY < 0));
+            boolean sameXDirection = (newVelocityX == 0) || (oldVelocityX == 0) ||
+                ((newVelocityX < 0) == (oldVelocityX < 0));
+            boolean sameYDirection = (newVelocityY == 0) || (oldVelocityY == 0) ||
+                ((newVelocityY < 0) == (oldVelocityY < 0));
             if (sameXDirection) {
-                velocityX += oldVelocityX;
+                newVelocityX += + oldVelocityX;
             }
             if (sameYDirection) {
-                velocityY += oldVelocityY;
+                newVelocityY += oldVelocityY;
             }
         }
 
         mMode = FLING_MODE;
-        mScrollerX.fling(startX, velocityX, minX, maxX, overX, time);
-        mScrollerY.fling(startY, velocityY, minY, maxY, overY, time);
+        mScrollerX.fling(startX, newVelocityX, minX, maxX, overX, time);
+        mScrollerY.fling(startY, newVelocityY, minY, maxY, overY, time);
     }
 
     /**
      * Stops the animation. Contrary to {@link #forceFinished(boolean)},
      * aborting the animating causes the scroller to move to the final x and y
      * positions.
      *
      * @see #forceFinished(boolean)
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/ByteBufferInputStream.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/ByteBufferInputStream.java
@@ -40,25 +40,25 @@ class ByteBufferInputStream extends Inpu
     }
 
     @Override
     public int read(byte[] buffer, int offset, int length) {
         if (!mBuf.hasRemaining() || mNativeRef.isReleased()) {
             return -1;
         }
 
-        length = Math.min(length, mBuf.remaining());
-        mBuf.get(buffer, offset, length);
+        int remainingLength = Math.min(length, mBuf.remaining());
+        mBuf.get(buffer, offset, remainingLength);
         return length;
     }
 
     @Override
     public long skip(long byteCount) {
         if (byteCount < 0 || mNativeRef.isReleased()) {
             return 0;
         }
 
-        byteCount = Math.min(byteCount, mBuf.remaining());
-        mBuf.position(mBuf.position() + (int)byteCount);
-        return byteCount;
+        long remainingByteCount = Math.min(byteCount, mBuf.remaining());
+        mBuf.position(mBuf.position() + (int) remainingByteCount);
+        return remainingByteCount;
     }
 
 }
--- 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
@@ -55,21 +55,22 @@ public class MatrixBlobCursor extends Ab
      *  determines column ordering elsewhere in this cursor
      * @param initialCapacity in rows
      */
     @JNITarget
     public MatrixBlobCursor(String[] columnNames, int initialCapacity) {
         this.columnNames = columnNames;
         this.columnCount = columnNames.length;
 
-        if (initialCapacity < 1) {
-            initialCapacity = 1;
+        int capacity = initialCapacity;
+        if (capacity < 1) {
+            capacity = 1;
         }
 
-        this.data = new Object[columnCount * initialCapacity];
+        this.data = new Object[columnCount * capacity];
         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
--- 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
@@ -68,17 +68,16 @@ public class ActivityUtils {
         context.startActivity(intent);
     }
 
     public static Activity getActivityFromContext(Context context) {
         while (context instanceof ContextWrapper) {
             if (context instanceof Activity) {
                 return (Activity) context;
             }
-            context = ((ContextWrapper) context).getBaseContext();
         }
         return null;
     }
 
     public static void preventDisplayStatusbar(final Activity activity, boolean registering) {
         final View decorView = activity.getWindow().getDecorView();
         if (registering) {
             decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/FileUtils.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/FileUtils.java
@@ -281,24 +281,25 @@ public class FileUtils {
         }
     }
 
     public static File createTempDir(File directory, String prefix) {
         // Force a prefix null check first
         if (prefix.length() < 3) {
             throw new IllegalArgumentException("prefix must be at least 3 characters");
         }
-        if (directory == null) {
+        File tempDirectory = directory;
+        if (tempDirectory == null) {
             String tmpDir = System.getProperty("java.io.tmpdir", ".");
-            directory = new File(tmpDir);
+            tempDirectory = new File(tmpDir);
         }
         File result;
         Random random = new Random();
         do {
-            result = new File(directory, prefix + random.nextInt());
+            result = new File(tempDirectory, prefix + random.nextInt());
         } while (!result.mkdirs());
         return result;
     }
 
     public static String resolveContentUri(final Context context, final Uri uri) {
         String path = getOriginalFilePathFromUri(context, uri);
         if (TextUtils.isEmpty(path)) {
             // We cannot always successfully guess the original path of the file behind the
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/GamepadUtils.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/GamepadUtils.java
@@ -83,32 +83,35 @@ public final class GamepadUtils {
         return sClickDispatcher;
     }
 
     public static KeyEvent translateSonyXperiaGamepadKeys(int keyCode, KeyEvent event) {
         // The cross and circle button mappings may be swapped in the different regions so
         // determine if they are swapped so the proper key codes can be mapped to the keys
         boolean areKeysSwapped = areSonyXperiaGamepadKeysSwapped();
 
+        int translatedKeyCode = keyCode;
         // If a Sony Xperia, remap the cross and circle buttons to buttons
         // A and B for the gamepad API
         switch (keyCode) {
             case KeyEvent.KEYCODE_BACK:
-                keyCode = (areKeysSwapped ? KeyEvent.KEYCODE_BUTTON_A : KeyEvent.KEYCODE_BUTTON_B);
+                translatedKeyCode = (areKeysSwapped ? KeyEvent.KEYCODE_BUTTON_A
+                                                    : KeyEvent.KEYCODE_BUTTON_B);
                 break;
 
             case KeyEvent.KEYCODE_DPAD_CENTER:
-                keyCode = (areKeysSwapped ? KeyEvent.KEYCODE_BUTTON_B : KeyEvent.KEYCODE_BUTTON_A);
+                translatedKeyCode = (areKeysSwapped ? KeyEvent.KEYCODE_BUTTON_B
+                                                    : KeyEvent.KEYCODE_BUTTON_A);
                 break;
 
             default:
                 return event;
         }
 
-        return new KeyEvent(event.getAction(), keyCode);
+        return new KeyEvent(event.getAction(), translatedKeyCode);
     }
 
     public static boolean isSonyXperiaGamepadKeyEvent(KeyEvent event) {
         return (event.getDeviceId() == SONY_XPERIA_GAMEPAD_DEVICE_ID &&
                 "Sony Ericsson".equals(Build.MANUFACTURER) &&
                 ("R800".equals(Build.MODEL) || "R800i".equals(Build.MODEL)));
     }
 
--- 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
@@ -182,32 +182,33 @@ public final class GeckoJarReader {
             Log.e(LOGTAG, "Exception getting input stream from jar URL: " + url, ex);
             return null;
         }
     }
 
     private static InputStream getStream(NativeZip zip, Stack<String> jarUrls, String origUrl) {
         InputStream inputStream = null;
 
+        NativeZip currentZip = zip;
         // loop through children jar files until we reach the innermost one
         while (!jarUrls.empty()) {
             String fileName = jarUrls.pop();
 
             if (inputStream != null) {
                 // intermediate NativeZips and InputStreams will be garbage collected.
                 try {
-                    zip = new NativeZip(inputStream);
+                    currentZip = new NativeZip(inputStream);
                 } catch (IllegalArgumentException e) {
                     String description = "!!! BUG 849589 !!! origUrl=" + origUrl;
                     Log.e(LOGTAG, description, e);
                     throw new IllegalArgumentException(description);
                 }
             }
 
-            inputStream = zip.getInputStream(fileName);
+            inputStream = currentZip.getInputStream(fileName);
             if (inputStream == null) {
                 Log.d(LOGTAG, "No Entry for " + fileName);
                 return null;
             }
         }
 
         return inputStream;
     }
@@ -216,25 +217,21 @@ public final class GeckoJarReader {
      * is assumed to point to a jar file except for the final one. Callers should
      * pass in the url to parse, and null for the parent parameter (used for recursion)
      * For example, jar:jar:file:///data/app/org.mozilla.fennec.apk!/omni.ja!/chrome/chrome/content/branding/favicon32.png
      * will return:
      *    file:///data/app/org.mozilla.fennec.apk
      *    omni.ja
      *    chrome/chrome/content/branding/favicon32.png
      */
-    private static Stack<String> parseUrl(String url) {
-        return parseUrl(url, null);
+    private static Stack<String> parseUrl(final String url) {
+        return parseUrl(url, new Stack<>());
     }
 
-    private static Stack<String> parseUrl(String url, Stack<String> results) {
-        if (results == null) {
-            results = new Stack<String>();
-        }
-
+    private static Stack<String> parseUrl(final String url, final Stack<String> results) {
         if (url.startsWith("jar:")) {
             int jarEnd = url.lastIndexOf("!");
             String subStr = url.substring(4, jarEnd);
             results.push(url.substring(jarEnd + 2)); // remove the !/ characters
             return parseUrl(subStr, results);
         } else {
             results.push(url);
             return results;
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/IOUtils.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/IOUtils.java
@@ -72,18 +72,18 @@ public class IOUtils {
             // Fully read the data into the buffer.
             while (lastRead != -1) {
                 // Read as many bytes as are currently available into the buffer.
                 lastRead = iStream.read(buffer, bPointer, buffer.length - bPointer);
                 bPointer += lastRead;
 
                 // If buffer has overflowed, double its size and carry on.
                 if (bPointer == buffer.length) {
-                    bufferSize *= 2;
-                    byte[] newBuffer = new byte[bufferSize];
+                    int newBufferSize = bufferSize * 2;
+                    byte[] newBuffer = new byte[newBufferSize];
 
                     // Copy the contents of the old buffer into the new buffer.
                     System.arraycopy(buffer, 0, newBuffer, 0, buffer.length);
                     buffer = newBuffer;
                 }
             }
 
             return new ConsumedInputStream(bPointer + 1, buffer);
--- 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
@@ -45,23 +45,23 @@ public class StringUtils {
      *  http://foo.com bar
      *
      * wasSearchQuery specifies whether text was a search query before the latest change
      * in text. In ambiguous cases where the new text can be either a search or a URL,
      * wasSearchQuery is returned
     */
     public static boolean isSearchQuery(String text, boolean wasSearchQuery) {
         // We remove leading and trailing white spaces when decoding URLs
-        text = text.trim();
-        if (text.length() == 0) {
+        String trimmedText = text.trim();
+        if (trimmedText.length() == 0) {
             return wasSearchQuery;
         }
-        int colon = text.indexOf(':');
-        int dot = text.indexOf('.');
-        int space = text.indexOf(' ');
+        int colon = trimmedText.indexOf(':');
+        int dot = trimmedText.indexOf('.');
+        int space = trimmedText.indexOf(' ');
 
         // If a space is found in a trimmed string, we assume this is a search query(Bug 1278245)
         if (space > -1) {
             return true;
         }
         // Otherwise, if a dot or a colon is found, we assume this is a URL
         if (dot > -1 || colon > -1) {
             return false;
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoEditable.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoEditable.java
@@ -892,36 +892,36 @@ import android.view.inputmethod.EditorIn
             }
         } while (rangeStart < composingEnd);
     }
 
     @Override // SessionTextInput.EditableClient
     public void sendKeyEvent(final @Nullable View view, final int action, @NonNull KeyEvent event) {
         final Editable editable = mProxy;
         final KeyListener keyListener = TextKeyListener.getInstance();
-        event = translateKey(event.getKeyCode(), event);
+        KeyEvent translatedEvent = translateKey(event.getKeyCode(), event);
 
         // We only let TextKeyListener do UI things on the UI thread.
         final View v = ThreadUtils.isOnUiThread() ? view : null;
-        final int keyCode = event.getKeyCode();
+        final int keyCode = translatedEvent.getKeyCode();
         final boolean handled;
 
-        if (shouldSkipKeyListener(keyCode, event)) {
+        if (shouldSkipKeyListener(keyCode, translatedEvent)) {
             handled = false;
         } else if (action == KeyEvent.ACTION_DOWN) {
             setSuppressKeyUp(true);
-            handled = keyListener.onKeyDown(v, editable, keyCode, event);
+            handled = keyListener.onKeyDown(v, editable, keyCode, translatedEvent);
         } else if (action == KeyEvent.ACTION_UP) {
-            handled = keyListener.onKeyUp(v, editable, keyCode, event);
+            handled = keyListener.onKeyUp(v, editable, keyCode, translatedEvent);
         } else {
-            handled = keyListener.onKeyOther(v, editable, event);
+            handled = keyListener.onKeyOther(v, editable, translatedEvent);
         }
 
         if (!handled) {
-            sendKeyEvent(event, action, TextKeyListener.getMetaState(editable));
+            sendKeyEvent(translatedEvent, action, TextKeyListener.getMetaState(editable));
         }
 
         if (action == KeyEvent.ACTION_DOWN) {
             if (!handled) {
                 // Usually, the down key listener call above adjusts meta states for us.
                 // However, if the call didn't handle the event, we have to manually
                 // adjust meta states so the meta states remain consistent.
                 TextKeyListener.adjustMetaAfterKeypress(editable);
@@ -1379,32 +1379,35 @@ import android.view.inputmethod.EditorIn
         mIcPostHandler.post(new Runnable() {
             @Override
             public void run() {
                 icNotifyIMEContext(state, typeHint, modeHint, actionHint, flags);
             }
         });
     }
 
-    /* package */ void icNotifyIMEContext(int state, final String typeHint,
+    /* package */ void icNotifyIMEContext(final int originalState, final String typeHint,
                                           final String modeHint, final String actionHint,
                                           final int flags) {
         if (DEBUG) {
             assertOnIcThread();
         }
 
         // For some input type we will use a widget to display the ui, for those we must not
         // display the ime. We can display a widget for date and time types and, if the sdk version
         // is 11 or greater, for datetime/month/week as well.
+        int state;
         if (typeHint != null && (typeHint.equalsIgnoreCase("date") ||
                                  typeHint.equalsIgnoreCase("time") ||
                                  typeHint.equalsIgnoreCase("month") ||
                                  typeHint.equalsIgnoreCase("week") ||
                                  typeHint.equalsIgnoreCase("datetime-local"))) {
             state = SessionTextInput.EditableListener.IME_STATE_DISABLED;
+        } else {
+            state = originalState;
         }
 
         final int oldState = mIMEState;
         mIMEState = state;
         mIMETypeHint = (typeHint == null) ? "" : typeHint;
         mIMEModeHint = (modeHint == null) ? "" : modeHint;
         mIMEActionHint = (actionHint == null) ? "" : actionHint;
         mIMEFlags = flags;
@@ -2085,22 +2088,23 @@ import android.view.inputmethod.EditorIn
                     !processKey(view, KeyEvent.ACTION_UP,
                                 KeyEvent.KEYCODE_UNKNOWN, charEvent)) {
                     return false;
                 }
             }
             return true;
         }
 
-        while ((repeatCount--) > 0) {
+        for (int i = 0; i < repeatCount; i++) {
             if (!processKey(view, KeyEvent.ACTION_DOWN, keyCode, event) ||
                 !processKey(view, KeyEvent.ACTION_UP, keyCode, event)) {
                 return false;
             }
         }
+
         return true;
     }
 
     public boolean onKeyLongPress(final @Nullable View view, final int keyCode,
                                   final @NonNull KeyEvent event) {
         return false;
     }
 
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoInputConnection.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoInputConnection.java
@@ -586,19 +586,19 @@ import java.lang.reflect.Proxy;
             // negative offsets. In that case we ignore the call, similar to how
             // BaseInputConnection.setSelection ignores offsets that go past the length.
             return true;
         }
         return super.setSelection(start, end);
     }
 
     @Override
-    public boolean sendKeyEvent(@NonNull KeyEvent event) {
-        event = translateKey(event.getKeyCode(), event);
-        mEditableClient.sendKeyEvent(getView(), event.getAction(), event);
+    public boolean sendKeyEvent(final @NonNull KeyEvent event) {
+        KeyEvent translatedEvent = translateKey(event.getKeyCode(), event);
+        mEditableClient.sendKeyEvent(getView(), event.getAction(), translatedEvent);
         return false; // seems to always return false
     }
 
     private KeyEvent translateKey(final int keyCode, final @NonNull KeyEvent event) {
         switch (keyCode) {
             case KeyEvent.KEYCODE_ENTER:
                 if ((event.getFlags() & KeyEvent.FLAG_EDITOR_ACTION) != 0 &&
                         mIMEActionHint.equalsIgnoreCase("next")) {
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/PanZoomController.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/PanZoomController.java
@@ -423,29 +423,30 @@ public class PanZoomController extends J
                 if (pointers.get(i).source == source) {
                     coords[index++] = pointers.get(i).getCoords();
                 }
             }
             return coords;
         }
     }
 
-    private void synthesizeNativePointer(int source, int pointerId, int eventType,
-                                         int clientX, int clientY, double pressure,
-                                         int orientation)
-    {
+    private void synthesizeNativePointer(final int source, final int pointerId,
+                                         final int originalEventType,
+                                         final int clientX, final int clientY,
+                                         final double pressure, final int orientation) {
         if (mPointerState == null) {
             mPointerState = new SynthesizedEventState();
         }
 
         // Find the pointer if it already exists
         int pointerIndex = mPointerState.getPointerIndex(pointerId);
 
         // Event-specific handling
-        switch (eventType) {
+        int eventType = originalEventType;
+        switch (originalEventType) {
             case MotionEvent.ACTION_POINTER_UP:
                 if (pointerIndex < 0) {
                     Log.w(LOGTAG, "Pointer-up for invalid pointer");
                     return;
                 }
                 if (mPointerState.pointers.size() == 1) {
                     // Last pointer is going up
                     eventType = MotionEvent.ACTION_UP;