Merge "Remove unnecessary commit/uncommit"
diff --git a/java/res/layout/setup_steps_cards.xml b/java/res/layout/setup_steps_cards.xml
index 2451731..9b03a3e 100644
--- a/java/res/layout/setup_steps_cards.xml
+++ b/java/res/layout/setup_steps_cards.xml
@@ -23,7 +23,7 @@
         android:id="@+id/setup_step_bullets"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginTop="@dimen/setup_step_vertical_padding"
+        android:paddingTop="@dimen/setup_step_vertical_padding"
         android:orientation="horizontal">
         <TextView
             android:id="@+id/setup_step1_bullet"
diff --git a/java/res/layout/setup_welcome_title.xml b/java/res/layout/setup_welcome_title.xml
index 6e6d781..af7053a 100644
--- a/java/res/layout/setup_welcome_title.xml
+++ b/java/res/layout/setup_welcome_title.xml
@@ -27,6 +27,6 @@
     <TextView
         android:id="@+id/setup_welcome_description"
         android:text="@string/setup_welcome_additional_description"
-        android:layout_marginTop="12dp"
+        android:layout_marginTop="@dimen/setup_welcome_description_top_margin"
         style="@style/setupWelcomeDescritpionStyle" />
 </merge>
diff --git a/java/res/layout/setup_welcome_video.xml b/java/res/layout/setup_welcome_video.xml
index c39411e..7517732 100644
--- a/java/res/layout/setup_welcome_video.xml
+++ b/java/res/layout/setup_welcome_video.xml
@@ -23,10 +23,9 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="horizontal"
-        android:paddingTop="@dimen/setup_welcome_video_vertical_margin"
-        android:paddingBottom="@dimen/setup_welcome_video_vertical_margin">
+        android:paddingTop="@dimen/setup_welcome_video_top_padding"
+        android:paddingBottom="@dimen/setup_welcome_video_bottom_padding">
         <LinearLayout
-            android:id="@+id/setup_welcome_video_frame"
             android:layout_weight="@integer/setup_welcome_video_weight_in_screen"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
@@ -42,6 +41,7 @@
                 android:id="@+id/setup_welcome_image"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
+                android:adjustViewBounds="true"
                 android:visibility="gone" />
         </LinearLayout>
         <View
diff --git a/java/res/raw/setup_welcome_image.png b/java/res/raw/setup_welcome_image.png
index db5dc34..2445915 100644
--- a/java/res/raw/setup_welcome_image.png
+++ b/java/res/raw/setup_welcome_image.png
Binary files differ
diff --git a/java/res/values-h1200dp-port/setup-dimens-large-tablet-port.xml b/java/res/values-h1200dp-port/setup-dimens-large-tablet-port.xml
index d1df81e..bc7928d 100644
--- a/java/res/values-h1200dp-port/setup-dimens-large-tablet-port.xml
+++ b/java/res/values-h1200dp-port/setup-dimens-large-tablet-port.xml
@@ -17,7 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
     <!-- Setup wizard dimensions for large-tablet/portrait. -->
     <dimen name="setup_title_text_size">72sp</dimen>
-    <dimen name="setup_welcome_description_text_size">36sp</dimen>
+    <dimen name="setup_welcome_description_text_size">38sp</dimen>
     <dimen name="setup_step_bullet_text_size">24sp</dimen>
     <dimen name="setup_step_triangle_indicator_height">24dp</dimen>
     <dimen name="setup_step_indicator_height">24dp</dimen>
@@ -34,7 +34,9 @@
     <integer name="setup_title_weight_in_screen">40</integer>
     <integer name="setup_body_weight_in_screen">60</integer>
     <dimen name="setup_title_end_margin">24dp</dimen>
-    <dimen name="setup_welcome_video_vertical_margin">24dp</dimen>
+    <dimen name="setup_welcome_description_top_margin">12dp</dimen>
+    <dimen name="setup_welcome_video_top_padding">24dp</dimen>
+    <dimen name="setup_welcome_video_bottom_padding">24dp</dimen>
     <integer name="setup_welcome_video_weight_in_screen">70</integer>
     <integer name="setup_welcome_video_end_padding_weight_in_screen">30</integer>
 </resources>
diff --git a/java/res/values-h330dp-land/setup-dimens-large-phone-land.xml b/java/res/values-h330dp-land/setup-dimens-large-phone-land.xml
index babc05b..aebf6d2 100644
--- a/java/res/values-h330dp-land/setup-dimens-large-phone-land.xml
+++ b/java/res/values-h330dp-land/setup-dimens-large-phone-land.xml
@@ -16,13 +16,13 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
     <!-- Setup wizard dimensions for large-phone/landscape. -->
-    <dimen name="setup_title_text_size">42sp</dimen>
-    <dimen name="setup_welcome_description_text_size">24sp</dimen>
+    <dimen name="setup_title_text_size">40sp</dimen>
+    <dimen name="setup_welcome_description_text_size">22sp</dimen>
     <dimen name="setup_step_bullet_text_size">22sp</dimen>
     <dimen name="setup_step_triangle_indicator_height">24dp</dimen>
     <dimen name="setup_step_indicator_height">24dp</dimen>
-    <dimen name="setup_step_title_text_size">22sp</dimen>
-    <dimen name="setup_step_instruction_text_size">14sp</dimen>
+    <dimen name="setup_step_title_text_size">20sp</dimen>
+    <dimen name="setup_step_instruction_text_size">16sp</dimen>
     <dimen name="setup_step_action_text_size">18sp</dimen>
     <dimen name="setup_vertical_padding">16dp</dimen>
     <dimen name="setup_horizontal_padding">16dp</dimen>
@@ -34,7 +34,9 @@
     <integer name="setup_title_weight_in_screen">40</integer>
     <integer name="setup_body_weight_in_screen">60</integer>
     <dimen name="setup_title_end_margin">24dp</dimen>
-    <dimen name="setup_welcome_video_vertical_margin">24dp</dimen>
+    <dimen name="setup_welcome_description_top_margin">10dp</dimen>
+    <dimen name="setup_welcome_video_top_padding">0dp</dimen>
+    <dimen name="setup_welcome_video_bottom_padding">12dp</dimen>
     <integer name="setup_welcome_video_weight_in_screen">70</integer>
     <integer name="setup_welcome_video_end_padding_weight_in_screen">30</integer>
 </resources>
diff --git a/java/res/values-h520dp-land/setup-dimens-small-tablet-land.xml b/java/res/values-h520dp-land/setup-dimens-small-tablet-land.xml
index 7725874..aedf79f 100644
--- a/java/res/values-h520dp-land/setup-dimens-small-tablet-land.xml
+++ b/java/res/values-h520dp-land/setup-dimens-small-tablet-land.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
     <!-- Setup wizard dimensions for small-tablet/landscape. -->
-    <dimen name="setup_title_text_size">56sp</dimen>
-    <dimen name="setup_welcome_description_text_size">28sp</dimen>
+    <dimen name="setup_title_text_size">60sp</dimen>
+    <dimen name="setup_welcome_description_text_size">32sp</dimen>
     <dimen name="setup_step_bullet_text_size">24sp</dimen>
     <dimen name="setup_step_triangle_indicator_height">24dp</dimen>
     <dimen name="setup_step_indicator_height">24dp</dimen>
@@ -31,10 +31,12 @@
     <dimen name="setup_step_horizontal_padding_half">12dp</dimen>
     <dimen name="setup_step_vertical_padding">16dp</dimen>
     <dimen name="setup_step_horizontal_line_height">2dp</dimen>
-    <integer name="setup_title_weight_in_screen">40</integer>
-    <integer name="setup_body_weight_in_screen">60</integer>
+    <integer name="setup_title_weight_in_screen">50</integer>
+    <integer name="setup_body_weight_in_screen">50</integer>
     <dimen name="setup_title_end_margin">24dp</dimen>
-    <dimen name="setup_welcome_video_vertical_margin">24dp</dimen>
-    <integer name="setup_welcome_video_weight_in_screen">60</integer>
-    <integer name="setup_welcome_video_end_padding_weight_in_screen">40</integer>
+    <dimen name="setup_welcome_description_top_margin">12dp</dimen>
+    <dimen name="setup_welcome_video_top_padding">0dp</dimen>
+    <dimen name="setup_welcome_video_bottom_padding">24dp</dimen>
+    <integer name="setup_welcome_video_weight_in_screen">80</integer>
+    <integer name="setup_welcome_video_end_padding_weight_in_screen">20</integer>
 </resources>
diff --git a/java/res/values-h540dp-port/setup-dimens-large-phone-port.xml b/java/res/values-h540dp-port/setup-dimens-large-phone-port.xml
index 42d2284..6d66f46 100644
--- a/java/res/values-h540dp-port/setup-dimens-large-phone-port.xml
+++ b/java/res/values-h540dp-port/setup-dimens-large-phone-port.xml
@@ -16,15 +16,15 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
     <!-- Setup wizard dimensions for large-phone/portrait. -->
-    <dimen name="setup_title_text_size">46sp</dimen>
+    <dimen name="setup_title_text_size">48sp</dimen>
     <dimen name="setup_welcome_description_text_size">26sp</dimen>
     <dimen name="setup_step_bullet_text_size">22sp</dimen>
     <dimen name="setup_step_triangle_indicator_height">24dp</dimen>
     <dimen name="setup_step_indicator_height">24dp</dimen>
-    <dimen name="setup_step_title_text_size">22sp</dimen>
-    <dimen name="setup_step_instruction_text_size">14sp</dimen>
+    <dimen name="setup_step_title_text_size">20sp</dimen>
+    <dimen name="setup_step_instruction_text_size">16sp</dimen>
     <dimen name="setup_step_action_text_size">18sp</dimen>
-    <dimen name="setup_vertical_padding">16dp</dimen>
+    <dimen name="setup_vertical_padding">8dp</dimen>
     <dimen name="setup_horizontal_padding">16dp</dimen>
     <dimen name="setup_step_action_height">48dp</dimen>
     <dimen name="setup_step_horizontal_padding">24dp</dimen>
@@ -34,7 +34,9 @@
     <integer name="setup_title_weight_in_screen">40</integer>
     <integer name="setup_body_weight_in_screen">60</integer>
     <dimen name="setup_title_end_margin">24dp</dimen>
-    <dimen name="setup_welcome_video_vertical_margin">24dp</dimen>
+    <dimen name="setup_welcome_description_top_margin">6dp</dimen>
+    <dimen name="setup_welcome_video_top_padding">12dp</dimen>
+    <dimen name="setup_welcome_video_bottom_padding">12dp</dimen>
     <integer name="setup_welcome_video_weight_in_screen">70</integer>
     <integer name="setup_welcome_video_end_padding_weight_in_screen">30</integer>
 </resources>
diff --git a/java/res/values-h720dp-land/setup-dimens-large-tablet-land.xml b/java/res/values-h720dp-land/setup-dimens-large-tablet-land.xml
index b5f0e5c..e22b741 100644
--- a/java/res/values-h720dp-land/setup-dimens-large-tablet-land.xml
+++ b/java/res/values-h720dp-land/setup-dimens-large-tablet-land.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
     <!-- Setup wizard dimensions for large-tablet/landscape. -->
-    <dimen name="setup_title_text_size">58sp</dimen>
-    <dimen name="setup_welcome_description_text_size">28sp</dimen>
+    <dimen name="setup_title_text_size">72sp</dimen>
+    <dimen name="setup_welcome_description_text_size">38sp</dimen>
     <dimen name="setup_step_bullet_text_size">24sp</dimen>
     <dimen name="setup_step_triangle_indicator_height">24dp</dimen>
     <dimen name="setup_step_indicator_height">24dp</dimen>
@@ -25,16 +25,18 @@
     <dimen name="setup_step_instruction_text_size">18sp</dimen>
     <dimen name="setup_step_action_text_size">20sp</dimen>
     <dimen name="setup_vertical_padding">96dp</dimen>
-    <dimen name="setup_horizontal_padding">192dp</dimen>
+    <dimen name="setup_horizontal_padding">160dp</dimen>
     <dimen name="setup_step_action_height">48dp</dimen>
     <dimen name="setup_step_horizontal_padding">24dp</dimen>
     <dimen name="setup_step_horizontal_padding_half">12dp</dimen>
     <dimen name="setup_step_vertical_padding">16dp</dimen>
     <dimen name="setup_step_horizontal_line_height">2dp</dimen>
-    <integer name="setup_title_weight_in_screen">40</integer>
-    <integer name="setup_body_weight_in_screen">60</integer>
+    <integer name="setup_title_weight_in_screen">50</integer>
+    <integer name="setup_body_weight_in_screen">50</integer>
     <dimen name="setup_title_end_margin">24dp</dimen>
-    <dimen name="setup_welcome_video_vertical_margin">24dp</dimen>
-    <integer name="setup_welcome_video_weight_in_screen">70</integer>
-    <integer name="setup_welcome_video_end_padding_weight_in_screen">30</integer>
+    <dimen name="setup_welcome_description_top_margin">12dp</dimen>
+    <dimen name="setup_welcome_video_top_padding">0dp</dimen>
+    <dimen name="setup_welcome_video_bottom_padding">24dp</dimen>
+    <integer name="setup_welcome_video_weight_in_screen">80</integer>
+    <integer name="setup_welcome_video_end_padding_weight_in_screen">20</integer>
 </resources>
diff --git a/java/res/values-h800dp-port/setup-dimens-small-tablet-port.xml b/java/res/values-h800dp-port/setup-dimens-small-tablet-port.xml
index 770b4e8..86cf3a0 100644
--- a/java/res/values-h800dp-port/setup-dimens-small-tablet-port.xml
+++ b/java/res/values-h800dp-port/setup-dimens-small-tablet-port.xml
@@ -34,7 +34,9 @@
     <integer name="setup_title_weight_in_screen">40</integer>
     <integer name="setup_body_weight_in_screen">60</integer>
     <dimen name="setup_title_end_margin">24dp</dimen>
-    <dimen name="setup_welcome_video_vertical_margin">24dp</dimen>
-    <integer name="setup_welcome_video_weight_in_screen">60</integer>
-    <integer name="setup_welcome_video_end_padding_weight_in_screen">40</integer>
+    <dimen name="setup_welcome_description_top_margin">12dp</dimen>
+    <dimen name="setup_welcome_video_top_padding">24dp</dimen>
+    <dimen name="setup_welcome_video_bottom_padding">24dp</dimen>
+    <integer name="setup_welcome_video_weight_in_screen">70</integer>
+    <integer name="setup_welcome_video_end_padding_weight_in_screen">30</integer>
 </resources>
diff --git a/java/res/values-land/setup-dimens-small-phone-land.xml b/java/res/values-land/setup-dimens-small-phone-land.xml
index e6dbaa7..088e656 100644
--- a/java/res/values-land/setup-dimens-small-phone-land.xml
+++ b/java/res/values-land/setup-dimens-small-phone-land.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
     <!-- Setup wizard dimensions for small-phone/landscape. -->
-    <dimen name="setup_title_text_size">36sp</dimen>
+    <dimen name="setup_title_text_size">32sp</dimen>
     <dimen name="setup_welcome_description_text_size">18sp</dimen>
     <dimen name="setup_step_bullet_text_size">18sp</dimen>
     <dimen name="setup_step_triangle_indicator_height">18dp</dimen>
@@ -24,7 +24,7 @@
     <dimen name="setup_step_title_text_size">18sp</dimen>
     <dimen name="setup_step_instruction_text_size">14sp</dimen>
     <dimen name="setup_step_action_text_size">16sp</dimen>
-    <dimen name="setup_vertical_padding">12dp</dimen>
+    <dimen name="setup_vertical_padding">16dp</dimen>
     <dimen name="setup_horizontal_padding">12dp</dimen>
     <dimen name="setup_step_action_height">42dp</dimen>
     <dimen name="setup_step_horizontal_padding">20dp</dimen>
@@ -34,7 +34,9 @@
     <integer name="setup_title_weight_in_screen">40</integer>
     <integer name="setup_body_weight_in_screen">60</integer>
     <dimen name="setup_title_end_margin">12dp</dimen>
-    <dimen name="setup_welcome_video_vertical_margin">12dp</dimen>
-    <integer name="setup_welcome_video_weight_in_screen">60</integer>
-    <integer name="setup_welcome_video_end_padding_weight_in_screen">40</integer>
+    <dimen name="setup_welcome_description_top_margin">12dp</dimen>
+    <dimen name="setup_welcome_video_top_padding">0dp</dimen>
+    <dimen name="setup_welcome_video_bottom_padding">12dp</dimen>
+    <integer name="setup_welcome_video_weight_in_screen">70</integer>
+    <integer name="setup_welcome_video_end_padding_weight_in_screen">30</integer>
 </resources>
diff --git a/java/res/values-port/setup-dimens-small-phone-port.xml b/java/res/values-port/setup-dimens-small-phone-port.xml
index a3b18af..8ac72ea 100644
--- a/java/res/values-port/setup-dimens-small-phone-port.xml
+++ b/java/res/values-port/setup-dimens-small-phone-port.xml
@@ -24,7 +24,7 @@
     <dimen name="setup_step_title_text_size">18sp</dimen>
     <dimen name="setup_step_instruction_text_size">14sp</dimen>
     <dimen name="setup_step_action_text_size">16sp</dimen>
-    <dimen name="setup_vertical_padding">12dp</dimen>
+    <dimen name="setup_vertical_padding">2dp</dimen>
     <dimen name="setup_horizontal_padding">12dp</dimen>
     <dimen name="setup_step_action_height">42dp</dimen>
     <dimen name="setup_step_horizontal_padding">20dp</dimen>
@@ -34,7 +34,9 @@
     <integer name="setup_title_weight_in_screen">40</integer>
     <integer name="setup_body_weight_in_screen">60</integer>
     <dimen name="setup_title_end_margin">16dp</dimen>
-    <dimen name="setup_welcome_video_vertical_margin">16dp</dimen>
+    <dimen name="setup_welcome_description_top_margin">4dp</dimen>
+    <dimen name="setup_welcome_video_top_padding">12dp</dimen>
+    <dimen name="setup_welcome_video_bottom_padding">12dp</dimen>
     <integer name="setup_welcome_video_weight_in_screen">70</integer>
     <integer name="setup_welcome_video_end_padding_weight_in_screen">30</integer>
 </resources>
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index e5365de..ad0c1c8 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -90,7 +90,7 @@
 /**
  * Input method implementation for Qwerty'ish keyboard.
  */
-public final class LatinIME extends InputMethodService implements KeyboardActionListener,
+public class LatinIME extends InputMethodService implements KeyboardActionListener,
         SuggestionStripView.Listener, TargetApplicationGetter.OnTargetApplicationKnownListener,
         Suggest.SuggestInitializationListener {
     private static final String TAG = LatinIME.class.getSimpleName();
@@ -188,6 +188,8 @@
     // Keeps track of most recently inserted text (multi-character key) for reverting
     private String mEnteredText;
 
+    // TODO: This boolean is persistent state and causes large side effects at unexpected times.
+    // Find a way to remove it for readability.
     private boolean mIsAutoCorrectionIndicatorOn;
 
     private AlertDialog mOptionsDialog;
@@ -902,7 +904,12 @@
         // we know for sure the cursor moved while we were composing and we should reset
         // the state.
         final boolean noComposingSpan = composingSpanStart == -1 && composingSpanEnd == -1;
-        if (!mExpectingUpdateSelection
+        // If the keyboard is not visible, we don't need to do all the housekeeping work, as it
+        // will be reset when the keyboard shows up anyway.
+        // TODO: revisit this when LatinIME supports hardware keyboards.
+        // NOTE: the test harness subclasses LatinIME and overrides isInputViewShown().
+        // TODO: find a better way to simulate actual execution.
+        if (isInputViewShown() && !mExpectingUpdateSelection
                 && !mConnection.isBelatedExpectedUpdate(oldSelStart, newSelStart)) {
             // TAKE CARE: there is a race condition when we enter this test even when the user
             // did not explicitly move the cursor. This happens when typing fast, where two keys
@@ -2507,7 +2514,10 @@
 
         // Note that it's very important here that suggestedWords.mWillAutoCorrect is false.
         // We never want to auto-correct on a resumed suggestion. Please refer to the three
-        // places above where suggestedWords is affected.
+        // places above where suggestedWords is affected. We also need to reset
+        // mIsAutoCorrectionIndicatorOn to avoid showSuggestionStrip touching the text to adapt it.
+        // TODO: remove mIsAutoCorrectionIndicator on (see comment on definition)
+        mIsAutoCorrectionIndicatorOn = false;
         showSuggestionStrip(suggestedWords, typedWord);
     }
 
diff --git a/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java b/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java
index 0d25bc3..78a6478 100644
--- a/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java
+++ b/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java
@@ -27,7 +27,6 @@
 import android.provider.Settings;
 import android.util.Log;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.inputmethod.InputMethodInfo;
 import android.widget.ImageView;
 import android.widget.TextView;
@@ -47,11 +46,14 @@
 public final class SetupWizardActivity extends Activity implements View.OnClickListener {
     static final String TAG = SetupWizardActivity.class.getSimpleName();
 
+    private static final boolean ENABLE_WELCOME_VIDEO = true;
+
     private View mSetupWizard;
     private View mWelcomeScreen;
     private View mSetupScreen;
     private Uri mWelcomeVideoUri;
     private VideoView mWelcomeVideoView;
+    private ImageView mWelcomeImageView;
     private View mActionStart;
     private View mActionNext;
     private TextView mStep1Bullet;
@@ -59,6 +61,7 @@
     private SetupStepGroup mSetupStepGroup;
     private static final String STATE_STEP = "step";
     private int mStepNumber;
+    private boolean mNeedsToAdjustStepNumberToSystemState;
     private static final int STEP_WELCOME = 0;
     private static final int STEP_1 = 1;
     private static final int STEP_2 = 2;
@@ -157,9 +160,7 @@
         step2.setAction(new Runnable() {
             @Override
             public void run() {
-                // Invoke input method picker.
-                RichInputMethodManager.getInstance().getInputMethodManager()
-                        .showInputMethodPicker();
+                invokeInputMethodPicker();
             }
         });
         mSetupStepGroup.addStep(step2);
@@ -192,23 +193,16 @@
                 mp.setLooping(true);
             }
         });
-        final ImageView welcomeImageView = (ImageView)findViewById(R.id.setup_welcome_image);
         welcomeVideoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
             @Override
             public boolean onError(final MediaPlayer mp, final int what, final int extra) {
                 Log.e(TAG, "Playing welcome video causes error: what=" + what + " extra=" + extra);
-                welcomeVideoView.setVisibility(View.GONE);
-                welcomeImageView.setImageResource(R.raw.setup_welcome_image);
-                welcomeImageView.setVisibility(View.VISIBLE);
-                // Remove unnecessary light gray background around still image.
-                final ViewGroup videoFrame = (ViewGroup)findViewById(
-                        R.id.setup_welcome_video_frame);
-                videoFrame.setBackgroundColor(getResources().getColor(R.color.setup_background));
-                videoFrame.requestLayout();
+                hideWelcomeVideoAndShowWelcomeImage();
                 return true;
             }
         });
         mWelcomeVideoView = welcomeVideoView;
+        mWelcomeImageView = (ImageView)findViewById(R.id.setup_welcome_image);
 
         mActionStart = findViewById(R.id.setup_start_label);
         mActionStart.setOnClickListener(this);
@@ -250,6 +244,7 @@
                 | Intent.FLAG_ACTIVITY_SINGLE_TOP
                 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
         startActivity(intent);
+        mNeedsToAdjustStepNumberToSystemState = true;
     }
 
     private void invokeSettingsOfThisIme() {
@@ -265,6 +260,14 @@
         intent.setAction(Settings.ACTION_INPUT_METHOD_SETTINGS);
         intent.addCategory(Intent.CATEGORY_DEFAULT);
         startActivity(intent);
+        mNeedsToAdjustStepNumberToSystemState = true;
+    }
+
+    void invokeInputMethodPicker() {
+        // Invoke input method picker.
+        RichInputMethodManager.getInstance().getInputMethodManager()
+                .showInputMethodPicker();
+        mNeedsToAdjustStepNumberToSystemState = true;
     }
 
     void invokeSubtypeEnablerOfThisIme() {
@@ -318,6 +321,9 @@
     @Override
     protected void onRestart() {
         super.onRestart();
+        // Probably the setup wizard has been invoked from "Recent" menu. The setup step number
+        // needs to be adjusted to system state, because the state (IME is enabled and/or current)
+        // may have been changed.
         if (isInSetupSteps(mStepNumber)) {
             mStepNumber = determineSetupStepNumber();
         }
@@ -350,21 +356,34 @@
         super.onBackPressed();
     }
 
-    private static void hideAndStopVideo(final VideoView videoView) {
-        videoView.stopPlayback();
-        videoView.setVisibility(View.INVISIBLE);
+    void hideWelcomeVideoAndShowWelcomeImage() {
+        mWelcomeVideoView.setVisibility(View.GONE);
+        mWelcomeImageView.setImageResource(R.raw.setup_welcome_image);
+        mWelcomeImageView.setVisibility(View.VISIBLE);
+    }
+
+    private void showAndStartWelcomeVideo() {
+        mWelcomeVideoView.setVisibility(View.VISIBLE);
+        mWelcomeVideoView.setVideoURI(mWelcomeVideoUri);
+        mWelcomeVideoView.start();
+    }
+
+    private void hideAndStopWelcomeVideo() {
+        mWelcomeVideoView.stopPlayback();
+        mWelcomeVideoView.setVisibility(View.GONE);
     }
 
     @Override
     protected void onPause() {
-        hideAndStopVideo(mWelcomeVideoView);
+        hideAndStopWelcomeVideo();
         super.onPause();
     }
 
     @Override
     public void onWindowFocusChanged(final boolean hasFocus) {
         super.onWindowFocusChanged(hasFocus);
-        if (hasFocus && isInSetupSteps(mStepNumber)) {
+        if (hasFocus && mNeedsToAdjustStepNumberToSystemState) {
+            mNeedsToAdjustStepNumberToSystemState = false;
             mStepNumber = determineSetupStepNumber();
             updateSetupStepView();
         }
@@ -376,12 +395,14 @@
         mWelcomeScreen.setVisibility(welcomeScreen ? View.VISIBLE : View.GONE);
         mSetupScreen.setVisibility(welcomeScreen ? View.GONE : View.VISIBLE);
         if (welcomeScreen) {
-            mWelcomeVideoView.setVisibility(View.VISIBLE);
-            mWelcomeVideoView.setVideoURI(mWelcomeVideoUri);
-            mWelcomeVideoView.start();
+            if (ENABLE_WELCOME_VIDEO) {
+                showAndStartWelcomeVideo();
+            } else {
+                hideWelcomeVideoAndShowWelcomeImage();
+            }
             return;
         }
-        hideAndStopVideo(mWelcomeVideoView);
+        hideAndStopWelcomeVideo();
         final boolean isStepActionAlreadyDone = mStepNumber < determineSetupStepNumber();
         mSetupStepGroup.enableStep(mStepNumber, isStepActionAlreadyDone);
         mActionNext.setVisibility(isStepActionAlreadyDone ? View.VISIBLE : View.GONE);
diff --git a/java/src/com/android/inputmethod/research/MainLogBuffer.java b/java/src/com/android/inputmethod/research/MainLogBuffer.java
index 9aa3499..7e8f166 100644
--- a/java/src/com/android/inputmethod/research/MainLogBuffer.java
+++ b/java/src/com/android/inputmethod/research/MainLogBuffer.java
@@ -196,6 +196,22 @@
         }
     }
 
+    /**
+     * If there is a safe n-gram at the front of this log buffer, publish it with all details, and
+     * remove the LogUnits that constitute it.
+     *
+     * An n-gram might not be "safe" if it violates privacy controls.  E.g., it might contain
+     * numbers, an out-of-vocabulary word, or another n-gram may have been published recently.  If
+     * there is no safe n-gram, then the LogUnits up through the first word-containing LogUnit are
+     * published, but without disclosing any privacy-related details, such as the word the LogUnit
+     * generated, motion data, etc.
+     *
+     * Note that a LogUnit can hold more than one word if the user types without explicit spaces.
+     * In this case, the words may be grouped together in such a way that pulling an n-gram off the
+     * front would require splitting a LogUnit.  Splitting a LogUnit is not possible, so this case
+     * is treated just as the unsafe n-gram case.  This may cause n-grams to be sampled at slightly
+     * less than the target frequency.
+     */
     protected final void publishLogUnitsAtFrontOfBuffer() throws IOException {
         // TODO: Refactor this method to require fewer passes through the LogUnits.  Should really
         // require only one pass.
diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
index 807c9f3..aec4aac 100644
--- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java
+++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
@@ -39,7 +39,7 @@
 
 import java.util.Locale;
 
-public class InputTestsBase extends ServiceTestCase<LatinIME> {
+public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
 
     private static final String PREF_DEBUG_MODE = "debug_mode";
 
@@ -121,7 +121,7 @@
     }
 
     public InputTestsBase() {
-        super(LatinIME.class);
+        super(LatinIMEForTests.class);
     }
 
     // TODO: Isn't there a way to make this generic somehow? We can take a <T> and return a <T>
diff --git a/tests/src/com/android/inputmethod/latin/LatinIMEForTests.java b/tests/src/com/android/inputmethod/latin/LatinIMEForTests.java
new file mode 100644
index 0000000..e47c557
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/LatinIMEForTests.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+package com.android.inputmethod.latin;
+
+public class LatinIMEForTests extends LatinIME {
+    @Override
+    public boolean isInputViewShown() {
+        return true;
+    }
+}