More correctly pronounce advanced operators in Talkback

Bug: 19190211
Bug: 19202945
Bug: 21052751
Bug: 19165054
Bug: 22594908

Add TtsSpans for operators that are otherwise misread by TalkBack.
Force correct reading for some individual characters.

This greatly improves Talkback for advanced operators in Calculator.

This is imperfect. There is no guarantee that the strings I'm
using will work in all languages.  But they're almost certainly better than
what we have now.  And it makes parentheses and factorial usable,
though perhaps a bit verbose.

We also no longer pronounce "sine" as "sin".

Removed some now obsolete TODO comments.

Change-Id: I5236f682be828699e08dca04ee6fa073269964f6
diff --git a/src/com/android/calculator2/KeyMaps.java b/src/com/android/calculator2/KeyMaps.java
index b4bfdf9..f99850b 100644
--- a/src/com/android/calculator2/KeyMaps.java
+++ b/src/com/android/calculator2/KeyMaps.java
@@ -115,6 +115,57 @@
     }
 
     /**
+     * Map key id to corresponding (internationalized) descriptive string that can be used
+     * to correctly read back a formula.
+     * Only used for operators and individual characters; not used inside constants.
+     * Returns null when we don't need a descriptive string.
+     * Pure function.
+     */
+    public static String toDescriptiveString(Context context, int id) {
+        switch(id) {
+            case R.id.op_fact:
+                return context.getString(R.string.desc_op_fact);
+            case R.id.fun_sin:
+                return context.getString(R.string.desc_fun_sin)
+                        + " " + context.getString(R.string.desc_lparen);
+            case R.id.fun_cos:
+                return context.getString(R.string.desc_fun_cos)
+                        + " " + context.getString(R.string.desc_lparen);
+            case R.id.fun_tan:
+                return context.getString(R.string.desc_fun_tan)
+                        + " " + context.getString(R.string.desc_lparen);
+            case R.id.fun_arcsin:
+                return context.getString(R.string.desc_fun_arcsin)
+                        + " " + context.getString(R.string.desc_lparen);
+            case R.id.fun_arccos:
+                return context.getString(R.string.desc_fun_arccos)
+                        + " " + context.getString(R.string.desc_lparen);
+            case R.id.fun_arctan:
+                return context.getString(R.string.desc_fun_arctan)
+                        + " " + context.getString(R.string.desc_lparen);
+            case R.id.fun_ln:
+                return context.getString(R.string.desc_fun_ln)
+                        + " " + context.getString(R.string.desc_lparen);
+            case R.id.fun_log:
+                return context.getString(R.string.desc_fun_log)
+                        + " " + context.getString(R.string.desc_lparen);
+            case R.id.fun_exp:
+                return context.getString(R.string.desc_fun_exp)
+                        + " " + context.getString(R.string.desc_lparen);
+            case R.id.lparen:
+                return context.getString(R.string.desc_lparen);
+            case R.id.rparen:
+                return context.getString(R.string.desc_rparen);
+            case R.id.op_pow:
+                return context.getString(R.string.desc_op_pow);
+            case R.id.dec_point:
+                return context.getString(R.string.desc_dec_point);
+            default:
+                return null;
+        }
+    }
+
+    /**
      * Does a button id correspond to a binary operator?
      * Pure function.
      */