Deal with small displays and a cancellation race

Bug: 34824406
Bug: 34949414

Check for unreasonably small display sizes and avoid crashing.

Incomplete fix for a cancellation race in which we write the expression
value back after the evaluation has been cancelled, and possibly
replaced.

Test: Some experiments with manually setting maxChars in redisplay().
Normal unit tests.

Change-Id: I7e11043eb5999bf373d66cc827de83024ef217f0
diff --git a/src/com/android/calculator2/CalculatorResult.java b/src/com/android/calculator2/CalculatorResult.java
index a8ab291..6934d39 100644
--- a/src/com/android/calculator2/CalculatorResult.java
+++ b/src/com/android/calculator2/CalculatorResult.java
@@ -745,6 +745,10 @@
                         ++exponent;
                     }
                 }
+                if (dropDigits >= result.length() - 1) {
+                    // Display too small to show meaningful result.
+                    return KeyMaps.ELLIPSIS + "E" + KeyMaps.ELLIPSIS;
+                }
                 result = result.substring(0, result.length() - dropDigits);
                 if (lastDisplayedOffset != null) {
                     lastDisplayedOffset[0] -= dropDigits;
@@ -919,11 +923,15 @@
     }
 
     public void redisplay() {
+        int maxChars = getMaxChars();
+        if (maxChars < 4) {
+            // Display currently too small to display a reasonable result. Punt to avoid crash.
+            return;
+        }
         if (mScroller.isFinished() && length() > 0) {
             setAccessibilityLiveRegion(ACCESSIBILITY_LIVE_REGION_POLITE);
         }
         int currentCharOffset = getCharOffset(mCurrentPos);
-        int maxChars = getMaxChars();
         int lastDisplayedOffset[] = new int[1];
         String result = getFormattedResult(currentCharOffset, maxChars, lastDisplayedOffset,
                 mAppendExponent /* forcePrecision; preserve entire result */,