Call loadKeyboard later if it can't be called right away

Since loadKeyboard relies on the input connection being
available to give it the auto-caps state, but also can't
be called twice in a row because it needs to save and
restore its state and invalidates it after the restore,
we need to wait until we know we have a valid input
connection to call it.

Bug: 11107229
Change-Id: I1c7baf3215682df6f6ceb357bd37254f9e7418c7
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
index 506dfa7..9f9fdaa 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
@@ -178,8 +178,6 @@
             if (!state.mIsAlphabetShiftLocked) {
                 setShifted(state.mShiftMode);
             }
-            // TODO: is this the right place to do this? Should we do this in setShift* instead?
-            mSwitchActions.requestUpdatingShiftState();
         } else {
             mPrevMainKeyboardWasShiftLocked = state.mIsAlphabetShiftLocked;
         }
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 851f967..0e93590 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -904,12 +904,17 @@
         // Sometimes, while rotating, for some reason the framework tells the app we are not
         // connected to it and that means we can't refresh the cache. In this case, schedule a
         // refresh later.
+        final boolean canReachInputConnection;
         if (!mConnection.resetCachesUponCursorMoveAndReturnSuccess(editorInfo.initialSelStart,
                 false /* shouldFinishComposition */)) {
             // We try resetting the caches up to 5 times before giving up.
             mHandler.postResetCaches(isDifferentTextField, 5 /* remainingTries */);
+            canReachInputConnection = false;
         } else {
-            if (isDifferentTextField) mHandler.postResumeSuggestions();
+            if (isDifferentTextField) {
+                mHandler.postResumeSuggestions();
+            }
+            canReachInputConnection = true;
         }
 
         if (isDifferentTextField) {
@@ -921,7 +926,11 @@
                 suggest.setAutoCorrectionThreshold(currentSettingsValues.mAutoCorrectionThreshold);
             }
 
-            switcher.loadKeyboard(editorInfo, currentSettingsValues);
+            if (canReachInputConnection) {
+                // If we can't reach the input connection, we don't want to call loadKeyboard yet.
+                // It will be done in #retryResetCaches.
+                switcher.loadKeyboard(editorInfo, currentSettingsValues);
+            }
         } else if (restarting) {
             // TODO: Come up with a more comprehensive way to reset the keyboard layout when
             // a keyboard layout set doesn't get reloaded in this method.
@@ -2955,11 +2964,13 @@
         if (!mConnection.resetCachesUponCursorMoveAndReturnSuccess(mLastSelectionStart, false)) {
             if (0 < remainingTries) {
                 mHandler.postResetCaches(tryResumeSuggestions, remainingTries - 1);
+                return;
             }
-            return;
+            // If remainingTries is 0, we should stop waiting for new tries, but it's still
+            // better to load the keyboard (less things will be broken).
         }
         tryFixLyingCursorPosition();
-        mKeyboardSwitcher.updateShiftState();
+        mKeyboardSwitcher.loadKeyboard(getCurrentInputEditorInfo(), mSettings.getCurrent());
         if (tryResumeSuggestions) mHandler.postResumeSuggestions();
     }