Get the log of exceptions. And delete the gradient background.

- Add a logger of Exception
- Catch RuntimeException where bug reported.
- Delete gradient background.

Change-Id: I98b5fbc4a51163de7e56bee4f8312585d8e98eb7
diff --git a/java/res/drawable/background_gradient.xml b/java/res/drawable/background_gradient.xml
deleted file mode 100644
index 52e2b16..0000000
--- a/java/res/drawable/background_gradient.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
-    <gradient
-        android:startColor="#FF000000"
-        android:endColor="#FF383838"
-        android:angle="90"/>
-</shape>
diff --git a/java/res/layout/input7.xml b/java/res/layout/input7.xml
index 91697b6..6279f5d 100755
--- a/java/res/layout/input7.xml
+++ b/java/res/layout/input7.xml
@@ -24,10 +24,10 @@
         android:layout_alignParentBottom="true"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:background="@drawable/keyboard_background"
         android:keyBackground="@drawable/btn_keyboard_key_ginger"
-        android:background="@drawable/background_gradient"
+        android:keyTextSize="22dip"
         android:keyTextColor="@color/latinkeyboard_key_color_black"
         android:shadowColor="@color/latinkeyboard_key_color_white"
-        android:keyTextSize="22dip"
         android:popupLayout="@layout/input7_popup"
-    />
+        />
diff --git a/java/res/layout/input7_popup.xml b/java/res/layout/input7_popup.xml
index 56e2fbd..d1261b8 100755
--- a/java/res/layout/input7_popup.xml
+++ b/java/res/layout/input7_popup.xml
@@ -32,7 +32,7 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:keyBackground="@drawable/btn_keyboard_key_ginger"
-            android:background="@drawable/background_gradient"
+            android:background="@drawable/keyboard_background"
             android:keyTextColor="@color/latinkeyboard_key_color_black"
             android:shadowColor="@color/latinkeyboard_key_color_white"
             android:keyTextSize="22dip"
diff --git a/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java b/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
index fefe1cc..3eb135e 100644
--- a/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
@@ -212,8 +212,12 @@
 
         mInputView.setPreviewEnabled(true);
         KeyboardId id = getKeyboardId(mode, imeOptions, isSymbols);
-
-        LatinKeyboard keyboard = getKeyboard(id);
+        LatinKeyboard keyboard = null;
+        try {
+            keyboard = getKeyboard(id);
+        } catch (RuntimeException e) {
+            LatinImeLogger.logOnException(mode + "," + imeOptions + "," + isSymbols, e);
+        }
 
         if (mode == MODE_PHONE) {
             mInputView.setPhoneKeyboard(keyboard);
@@ -271,12 +275,11 @@
         }
         switch (mode) {
             case MODE_TEXT:
-                if (mTextMode == MODE_TEXT_QWERTY) {
-                    return new KeyboardId(keyboardRowsResId, KEYBOARDMODE_NORMAL, true, hasVoice);
-                } else if (mTextMode == MODE_TEXT_ALPHA) {
+                if (mTextMode == MODE_TEXT_ALPHA) {
                     return new KeyboardId(R.xml.kbd_alpha, KEYBOARDMODE_NORMAL, true, hasVoice);
                 }
-                break;
+                // Normally mTextMode should be MODE_TEXT_QWERTY.
+                return new KeyboardId(keyboardRowsResId, KEYBOARDMODE_NORMAL, true, hasVoice);
             case MODE_SYMBOLS:
                 return makeSymbolsId(hasVoice);
             case MODE_PHONE:
@@ -301,19 +304,6 @@
         return mMode == MODE_TEXT;
     }
     
-    int getTextMode() {
-        return mTextMode;
-    }
-    
-    void setTextMode(int position) {
-        if (position < MODE_TEXT_COUNT && position >= 0) {
-            mTextMode = position;
-        }
-        if (isTextMode()) {
-            setKeyboardMode(MODE_TEXT, mImeOptions, mHasVoice);
-        }
-    }
-
     int getTextModeCount() {
         return MODE_TEXT_COUNT;
     }
@@ -387,11 +377,18 @@
 
     private void changeLatinKeyboardView(int newLayout, boolean forceReset) {
         if (mLayoutId != newLayout || mInputView == null || forceReset) {
+            if (mInputView != null) {
+                mInputView.closing();
+            }
             if (LAYOUTS.length <= newLayout) {
                 newLayout = Integer.valueOf(DEFAULT_LAYOUT_ID);
             }
-            mInputView = (LatinKeyboardView) mInputMethodService.getLayoutInflater().inflate(
-                    LAYOUTS[newLayout], null);
+            try {
+                mInputView = (LatinKeyboardView) mInputMethodService.getLayoutInflater().inflate(
+                        LAYOUTS[newLayout], null);
+            } catch (RuntimeException e) {
+                LatinImeLogger.logOnException(mLayoutId + "," + newLayout, e);
+            }
             mInputView.setExtentionLayoutResId(LAYOUTS[newLayout]);
             mInputView.setOnKeyboardActionListener(mInputMethodService);
             mLayoutId = newLayout;
diff --git a/java/src/com/android/inputmethod/latin/LatinImeLogger.java b/java/src/com/android/inputmethod/latin/LatinImeLogger.java
index a871b4a..b497c0c 100644
--- a/java/src/com/android/inputmethod/latin/LatinImeLogger.java
+++ b/java/src/com/android/inputmethod/latin/LatinImeLogger.java
@@ -26,12 +26,16 @@
 import android.text.format.DateUtils;
 import android.util.Log;
 
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
 import java.util.ArrayList;
 import java.util.Collections;
 
 public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChangeListener {
     private static final String TAG = "LatinIMELogs";
     private static boolean sDBG = false;
+    // SUPPRESS_EXCEPTION should be true when released to public.
+    private static final boolean SUPPRESS_EXCEPTION = false;
     // DEFAULT_LOG_ENABLED should be false when released to public.
     private static final boolean DEFAULT_LOG_ENABLED = true;
 
@@ -49,6 +53,7 @@
     private static final int ID_THEME_ID = 7;
     private static final int ID_SETTING_AUTO_COMPLETE = 8;
     private static final int ID_VERSION = 9;
+    private static final int ID_EXCEPTION = 10;
 
     private static final String PREF_ENABLE_LOG = "enable_logging";
     private static final String PREF_DEBUG_MODE = "debug_mode";
@@ -197,6 +202,13 @@
         }
     }
 
+    private void addExceptionEntry(long time, String[] data) {
+        if (sDBG) {
+            Log.d(TAG, "Log Exception. (1)");
+        }
+        mLogBuffer.add(new LogEntry(time, ID_EXCEPTION, data));
+    }
+
     private void flushPrivacyLogSafely() {
         if (sDBG) {
             Log.d(TAG, "Log theme Id. (" + mPrivacyLogBuffer.size() + ")");
@@ -270,6 +282,16 @@
                     }
                 }
                 break;
+            case ID_EXCEPTION:
+                dataStrings = (String[]) data;
+                if (dataStrings.length < 2) {
+                    if (sDBG) {
+                        Log.e(TAG, "The length of logged string array is invalid.");
+                    }
+                    break;
+                }
+                addExceptionEntry(System.currentTimeMillis(), dataStrings);
+                break;
             default:
                 if (sDBG) {
                     Log.e(TAG, "Log Tag is not entried.");
@@ -299,6 +321,12 @@
         mLastTimeSend = now;
     }
 
+    private void commitInternalAndStopSelf() {
+        Log.e(TAG, "Exception was caused and let's die.");
+        commitInternal();
+        ((LatinIME) mContext).stopSelf();
+    }
+
     private synchronized void sendLogToDropBox(int tag, Object s) {
         long now = System.currentTimeMillis();
         if (sDBG) {
@@ -405,6 +433,23 @@
         }
     }
 
+    public static void logOnException(String metaData, RuntimeException e) {
+        if (sLogEnabled) {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            PrintStream ps = new PrintStream(baos);
+            e.printStackTrace(ps);
+            String exceptionString = new String(baos.toByteArray());
+            sLatinImeLogger.sendLogToDropBox(
+                    ID_EXCEPTION, new String[] {metaData, exceptionString});
+            Log.e(TAG, "Exception: " + exceptionString);
+            if (SUPPRESS_EXCEPTION) {
+                sLatinImeLogger.commitInternalAndStopSelf();
+            } else {
+                throw e;
+            }
+        }
+    }
+
     private static class LogSerializer {
         private static void appendWithLength(StringBuffer sb, String data) {
             sb.append(data.length());
diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboardView.java b/java/src/com/android/inputmethod/latin/LatinKeyboardView.java
index 6e3226a..46f04b8 100644
--- a/java/src/com/android/inputmethod/latin/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/latin/LatinKeyboardView.java
@@ -472,7 +472,11 @@
 
     @Override
     public void draw(Canvas c) {
-        super.draw(c);
+        try {
+            super.draw(c);
+        } catch (RuntimeException e) {
+            LatinImeLogger.logOnException("draw in LatinKeybaordView", e);
+        }
         if (DEBUG_AUTO_PLAY) {
             if (mPlaying) {
                 mHandler2.removeMessages(MSG_TOUCH_DOWN);