Clean up Calculator state, evaluation and cancellation logic

Bug: 33216049
Bug: 33219408
Bug: 33107696

Add INIT_FOR_RESULT state to represent INIT state, when we know that
computation has previously ended in RESULT state.

Stubbornly refuse to display the history view if we are currently
in EVALUATE or INIT state. Both of these are very temporary.

Break up Calculator.onCreate() to make it a bit more manageable.

Add a number of assertion checks to detect unexpected states, etc.

Add HISTORY_MAIN_INDEX to ensure that we only have one evaluation
listener per expression being evaluated.

Add cancelNonMain to better target cancellation requests.

Remove evaluateInstantIfNecessary() hack in HistoryFragment.
We should no longer be randomly cancelling evaluations we don't
own.

Be a little more aggressive about avoid redundant evaluations.

Change-Id: I5eaf6390b597926f9255c635fb44d50b47cbd1e1
diff --git a/src/com/android/calculator2/HistoryFragment.java b/src/com/android/calculator2/HistoryFragment.java
index 3692a0f..bfc7273 100644
--- a/src/com/android/calculator2/HistoryFragment.java
+++ b/src/com/android/calculator2/HistoryFragment.java
@@ -49,8 +49,7 @@
 
                 @Override
                 public void onClosed() {
-                    // TODO: only cancel historical evaluations
-                    mEvaluator.cancelAll(true);
+                    mEvaluator.cancelNonMain();
                 }
 
                 @Override
@@ -152,8 +151,9 @@
                 // recyclerview).
                 // If we are in the result state, the result will animate to the last history
                 // element in the list and there will be no "Current Expression."
-                newDataSet.add(new HistoryItem(Evaluator.MAIN_INDEX, System.currentTimeMillis(),
-                        mEvaluator.getExprAsSpannable(0)));
+                mEvaluator.copyMainToHistory();
+                newDataSet.add(new HistoryItem(Evaluator.HISTORY_MAIN_INDEX,
+                        System.currentTimeMillis(), mEvaluator.getExprAsSpannable(0)));
             }
             for (long i = 0; i < maxIndex; ++i) {
                 newDataSet.add(null);
@@ -200,11 +200,8 @@
             dragLayout.removeDragCallback(mDragCallback);
         }
 
-        mEvaluator.cancelAll(true);
+        mEvaluator.cancelNonMain();
         super.onDestroy();
-        // FIXME: There are probably better ways to do this. But we can end up cancelling
-        // an in-progress evaluation for the main expression that we have to restart.
-        ((Calculator)(getActivity())).evaluateInstantIfNecessary();
     }
 
     private void initializeController(boolean isResult) {