Improve copy/paste handling, minor instant result fixes

Bug: 20764417
Bug: 20838790

Finish the action mode when we do almost anything else.
We should probably be even more aggressive about terminating it,
and we may eventually want to use a different approach.
But this avoids the crashes, and greatly improves the behavior.

Display copy menu only when there is something to copy.

Fix a couple of bugs introduced by recent instant display overhaul
(one line each):

- Instant display disappeared on rotation.

- It was sometimes still possible to scroll the previous result after
CLR.

Change-Id: I1a91d312358898add1e281aaba116d709b4c92a7
diff --git a/src/com/android/calculator2/CalculatorResult.java b/src/com/android/calculator2/CalculatorResult.java
index 72c3b54..c569d4c 100644
--- a/src/com/android/calculator2/CalculatorResult.java
+++ b/src/com/android/calculator2/CalculatorResult.java
@@ -28,8 +28,8 @@
 import android.widget.TextView;
 import android.widget.OverScroller;
 import android.text.Editable;
-import android.text.Spanned;
 import android.text.SpannableString;
+import android.text.Spanned;
 import android.text.style.ForegroundColorSpan;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -90,6 +90,8 @@
                             // the difference is not noticeable.
     private static final int MAX_WIDTH = 100;
                             // Maximum number of digits displayed
+    private ActionMode mActionMode;
+    private final ForegroundColorSpan mExponentColorSpan;
 
     public CalculatorResult(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -107,6 +109,7 @@
                         mCurrentPos = mScroller.getFinalX();
                     }
                     mScroller.forceFinished(true);
+                    stopActionMode();
                     CalculatorResult.this.cancelLongPress();
                     // Ignore scrolls of error string, etc.
                     if (!mScrollable) return true;
@@ -124,6 +127,7 @@
                         mCurrentPos = mScroller.getFinalX();
                     }
                     mScroller.forceFinished(true);
+                    stopActionMode();
                     CalculatorResult.this.cancelLongPress();
                     if (!mScrollable) return true;
                     int duration = (int)(e2.getEventTime() - e1.getEventTime());
@@ -135,13 +139,17 @@
                 }
                 @Override
                 public void onLongPress(MotionEvent e) {
-                    startActionMode(mCopyActionModeCallback,
-                                    ActionMode.TYPE_FLOATING);
+                    if (mValid) {
+                        mActionMode = startActionMode(mCopyActionModeCallback,
+                                ActionMode.TYPE_FLOATING);
+                    }
                 }
             });
         setOnTouchListener(mTouchListener);
         setHorizontallyScrolling(false);  // do it ourselves
         setCursorVisible(false);
+        mExponentColorSpan = new ForegroundColorSpan(
+                context.getColor(R.color.display_result_exponent_text_color));
 
         // Copy ActionMode is triggered explicitly, not through
         // setCustomSelectionActionModeCallback.
@@ -364,6 +372,7 @@
 
     void clear() {
         mValid = false;
+        mScrollable = false;
         setText("");
     }
 
@@ -376,8 +385,7 @@
         if (epos > 0 && result.indexOf('.') == -1) {
           // Gray out exponent if used as position indicator
             SpannableString formattedResult = new SpannableString(result);
-            formattedResult.setSpan(new ForegroundColorSpan(Color.LTGRAY),
-                                    epos, result.length(),
+            formattedResult.setSpan(mExponentColorSpan, epos, result.length(),
                                     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
             setText(formattedResult);
         } else {
@@ -432,9 +440,18 @@
 
         @Override
         public void onDestroyActionMode(ActionMode mode) {
+            mActionMode = null;
         }
     };
 
+    public boolean stopActionMode() {
+        if (mActionMode != null) {
+            mActionMode.finish();
+            return true;
+        }
+        return false;
+    }
+
     private void setPrimaryClip(ClipData clip) {
         ClipboardManager clipboard = (ClipboardManager) getContext().
                 getSystemService(Context.CLIPBOARD_SERVICE);