diff --git a/java/res/layout/emoji_palettes_view.xml b/java/res/layout/emoji_palettes_view.xml
index a6ea38ba4f3f99c7a508047637afd80cb1c67faf..26cc042ab8487c9c308e01765fe51463c078c7a3 100644
--- a/java/res/layout/emoji_palettes_view.xml
+++ b/java/res/layout/emoji_palettes_view.xml
@@ -20,10 +20,10 @@
 
 <com.android.inputmethod.keyboard.emoji.EmojiPalettesView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/emoji_keyboard_view"
-    android:orientation="vertical"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:layout_gravity="bottom"
+    android:orientation="vertical"
     style="?attr/emojiPalettesViewStyle"
 >
     <LinearLayout
diff --git a/java/res/layout/input_view.xml b/java/res/layout/input_view.xml
index a4bcdcc8ab9f1122c082d3b1b384cdc959fbc764..46551f63fd9e0cca937c08fbf84523533f7ead90 100644
--- a/java/res/layout/input_view.xml
+++ b/java/res/layout/input_view.xml
@@ -21,38 +21,11 @@
 <com.android.inputmethod.latin.InputView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:gravity="bottom|center_horizontal"
-    android:orientation="vertical" >
-    <!-- The height of key_preview_backing view will automatically be determined by code. -->
-    <FrameLayout
-        android:id="@+id/key_preview_backing"
-        android:layout_width="match_parent"
-        android:layout_height="0dp" />
-    <LinearLayout
+    android:layout_height="wrap_content">
+    <include
         android:id="@+id/main_keyboard_frame"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="vertical" >
-
-        <!-- To ensure that key preview popup is correctly placed when the current system locale is
-             one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
-        <com.android.inputmethod.latin.suggestions.SuggestionStripView
-            android:id="@+id/suggestion_strip_view"
-            android:layoutDirection="ltr"
-            android:layout_width="match_parent"
-            android:layout_height="@dimen/config_suggestions_strip_height"
-            android:gravity="center_vertical"
-            style="?attr/suggestionStripViewStyle" />
-
-        <!-- To ensure that key preview popup is correctly placed when the current system locale is
-             one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
-        <com.android.inputmethod.keyboard.MainKeyboardView
-            android:id="@+id/keyboard_view"
-            android:layoutDirection="ltr"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content" />
-    </LinearLayout>
+        layout="@layout/main_keyboard_frame" />
     <include
+        android:id="@+id/emoji_palettes_view"
         layout="@layout/emoji_palettes_view" />
 </com.android.inputmethod.latin.InputView>
diff --git a/java/res/layout/main_keyboard_frame.xml b/java/res/layout/main_keyboard_frame.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ebf746679c603d9899ed78f591c665bfcf1c806d
--- /dev/null
+++ b/java/res/layout/main_keyboard_frame.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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.
+*/
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_gravity="bottom"
+    android:orientation="vertical" >
+
+    <!-- To ensure that key preview popup is correctly placed when the current system locale is
+         one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
+    <com.android.inputmethod.latin.suggestions.SuggestionStripView
+        android:id="@+id/suggestion_strip_view"
+        android:layoutDirection="ltr"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/config_suggestions_strip_height"
+        android:gravity="center_vertical"
+        style="?attr/suggestionStripViewStyle" />
+
+    <!-- To ensure that key preview popup is correctly placed when the current system locale is
+         one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
+    <com.android.inputmethod.keyboard.MainKeyboardView
+        android:id="@+id/keyboard_view"
+        android:layoutDirection="ltr"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
+</LinearLayout>
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 77cdf49fbb8a349d9e6dd836c0332e895dbb8764..549b5fafca65867dd061762b20798e53eaf967c0 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -359,7 +359,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
                 R.layout.input_view, null);
         mMainKeyboardFrame = mCurrentInputView.findViewById(R.id.main_keyboard_frame);
         mEmojiPalettesView = (EmojiPalettesView)mCurrentInputView.findViewById(
-                R.id.emoji_keyboard_view);
+                R.id.emoji_palettes_view);
 
         mKeyboardView = (MainKeyboardView) mCurrentInputView.findViewById(R.id.keyboard_view);
         mKeyboardView.setHardwareAcceleratedDrawingEnabled(isHardwareAcceleratedDrawingEnabled);
diff --git a/java/src/com/android/inputmethod/latin/InputView.java b/java/src/com/android/inputmethod/latin/InputView.java
index e9e12f09f908e421e01b8596cfc1ce9446bca11e..7fa9354134efb6daa48e6fc68970fc04df3955bc 100644
--- a/java/src/com/android/inputmethod/latin/InputView.java
+++ b/java/src/com/android/inputmethod/latin/InputView.java
@@ -21,14 +21,14 @@ import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.View;
-import android.widget.LinearLayout;
+import android.widget.FrameLayout;
 
 import com.android.inputmethod.accessibility.AccessibilityUtils;
 import com.android.inputmethod.keyboard.MainKeyboardView;
 import com.android.inputmethod.latin.suggestions.MoreSuggestionsView;
 import com.android.inputmethod.latin.suggestions.SuggestionStripView;
 
-public final class InputView extends LinearLayout {
+public final class InputView extends FrameLayout {
     private final Rect mInputViewRect = new Rect();
     private MainKeyboardView mMainKeyboardView;
     private KeyboardTopPaddingForwarder mKeyboardTopPaddingForwarder;
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 2a7a5413dd87581c535a7154aba843efcaafe8d6..c348e6cfe486583be8b40d0ca763694df766152d 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -29,7 +29,6 @@ import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.graphics.Rect;
 import android.inputmethodservice.InputMethodService;
 import android.media.AudioManager;
 import android.net.ConnectivityManager;
@@ -43,6 +42,7 @@ import android.util.Log;
 import android.util.PrintWriterPrinter;
 import android.util.Printer;
 import android.util.SparseArray;
+import android.view.Gravity;
 import android.view.KeyEvent;
 import android.view.View;
 import android.view.ViewGroup.LayoutParams;
@@ -94,6 +94,7 @@ import com.android.inputmethod.latin.utils.JniUtils;
 import com.android.inputmethod.latin.utils.LeakGuardHandlerWrapper;
 import com.android.inputmethod.latin.utils.StatsUtils;
 import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
+import com.android.inputmethod.latin.utils.ViewLayoutUtils;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -150,8 +151,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
 
     // TODO: Move these {@link View}s to {@link KeyboardSwitcher}.
     private View mInputView;
-    private View mExtractArea;
-    private View mKeyPreviewBackingView;
     private SuggestionStripView mSuggestionStripView;
 
     private RichInputMethodManager mRichImm;
@@ -735,9 +734,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
     public void setInputView(final View view) {
         super.setInputView(view);
         mInputView = view;
-        mExtractArea = getWindow().getWindow().getDecorView()
-                .findViewById(android.R.id.extractArea);
-        mKeyPreviewBackingView = view.findViewById(R.id.key_preview_backing);
         mSuggestionStripView = (SuggestionStripView)view.findViewById(R.id.suggestion_strip_view);
         if (hasSuggestionStripView()) {
             mSuggestionStripView.setListener(this, view);
@@ -1075,36 +1071,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         setSuggestedWords(suggestedWords);
     }
 
-    private int getAdjustedBackingViewHeight() {
-        final int currentHeight = mKeyPreviewBackingView.getHeight();
-        if (currentHeight > 0) {
-            return currentHeight;
-        }
-
-        final View visibleKeyboardView = mKeyboardSwitcher.getVisibleKeyboardView();
-        if (visibleKeyboardView == null) {
-            return 0;
-        }
-        // TODO: !!!!!!!!!!!!!!!!!!!! Handle different backing view heights between the main   !!!
-        // keyboard and the emoji keyboard. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-        final int keyboardHeight = visibleKeyboardView.getHeight();
-        final int suggestionsHeight = mSuggestionStripView.getHeight();
-        final int displayHeight = getResources().getDisplayMetrics().heightPixels;
-        final Rect rect = new Rect();
-        mKeyPreviewBackingView.getWindowVisibleDisplayFrame(rect);
-        final int notificationBarHeight = rect.top;
-        final int remainingHeight = displayHeight - notificationBarHeight - suggestionsHeight
-                - keyboardHeight;
-
-        final LayoutParams params = mKeyPreviewBackingView.getLayoutParams();
-        mSuggestionStripView.setMoreSuggestionsHeight(remainingHeight);
-
-        // Let the backing cover the remaining region entirely.
-        params.height = remainingHeight;
-        mKeyPreviewBackingView.setLayoutParams(params);
-        return params.height;
-    }
-
     @Override
     public void onComputeInsets(final InputMethodService.Insets outInsets) {
         super.onComputeInsets(outInsets);
@@ -1112,40 +1078,30 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         if (visibleKeyboardView == null || !hasSuggestionStripView()) {
             return;
         }
+        final int inputHeight = mInputView.getHeight();
         final boolean hasHardwareKeyboard = mKeyboardSwitcher.hasHardwareKeyboard();
         if (hasHardwareKeyboard && visibleKeyboardView.getVisibility() == View.GONE) {
             // If there is a hardware keyboard and a visible software keyboard view has been hidden,
             // no visual element will be shown on the screen.
-            outInsets.touchableInsets = mInputView.getHeight();
-            outInsets.visibleTopInsets = mInputView.getHeight();
+            outInsets.touchableInsets = inputHeight;
+            outInsets.visibleTopInsets = inputHeight;
             return;
         }
-        final int adjustedBackingHeight = getAdjustedBackingViewHeight();
-        final boolean backingGone = (mKeyPreviewBackingView.getVisibility() == View.GONE);
-        final int backingHeight = backingGone ? 0 : adjustedBackingHeight;
-        // In fullscreen mode, the height of the extract area managed by InputMethodService should
-        // be considered.
-        // See {@link android.inputmethodservice.InputMethodService#onComputeInsets}.
-        final int extractHeight = isFullscreenMode() ? mExtractArea.getHeight() : 0;
-        final int suggestionsHeight = (mSuggestionStripView.getVisibility() == View.GONE) ? 0
-                : mSuggestionStripView.getHeight();
-        final int extraHeight = extractHeight + backingHeight + suggestionsHeight;
-        int visibleTopY = extraHeight;
-        // Need to set touchable region only if input view is being shown
+        final int suggestionsHeight = (!mKeyboardSwitcher.isShowingEmojiPalettes()
+                && mSuggestionStripView.getVisibility() == View.VISIBLE)
+                ? mSuggestionStripView.getHeight() : 0;
+        final int visibleTopY = inputHeight - visibleKeyboardView.getHeight() - suggestionsHeight;
+        mSuggestionStripView.setMoreSuggestionsHeight(visibleTopY);
+        // Need to set touchable region only if a keyboard view is being shown.
         if (visibleKeyboardView.isShown()) {
-            // Note that the height of Emoji layout is the same as the height of the main keyboard
-            // and the suggestion strip
-            if (mKeyboardSwitcher.isShowingEmojiPalettes()
-                    || mSuggestionStripView.getVisibility() == View.VISIBLE) {
-                visibleTopY -= suggestionsHeight;
-            }
-            final int touchY = mKeyboardSwitcher.isShowingMoreKeysPanel() ? 0 : visibleTopY;
-            final int touchWidth = visibleKeyboardView.getWidth();
-            final int touchHeight = visibleKeyboardView.getHeight() + extraHeight
+            final int touchLeft = 0;
+            final int touchTop = mKeyboardSwitcher.isShowingMoreKeysPanel() ? 0 : visibleTopY;
+            final int touchRight = visibleKeyboardView.getWidth();
+            final int touchBottom = inputHeight
                     // Extend touchable region below the keyboard.
                     + EXTENDED_TOUCHABLE_REGION_HEIGHT;
             outInsets.touchableInsets = InputMethodService.Insets.TOUCHABLE_INSETS_REGION;
-            outInsets.touchableRegion.set(0, touchY, touchWidth, touchHeight);
+            outInsets.touchableRegion.set(touchLeft, touchTop, touchRight, touchBottom);
         }
         outInsets.contentTopInsets = visibleTopY;
         outInsets.visibleTopInsets = visibleTopY;
@@ -1190,12 +1146,27 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
 
     @Override
     public void updateFullscreenMode() {
+        // Override layout parameters to expand {@link SoftInputWindow} to the entire screen.
+        // See {@link InputMethodService#setinputView(View) and
+        // {@link SoftInputWindow#updateWidthHeight(WindowManager.LayoutParams)}.
+        final Window window = getWindow().getWindow();
+        ViewLayoutUtils.updateLayoutHeightOf(window, LayoutParams.MATCH_PARENT);
+        // This method may be called before {@link #setInputView(View)}.
+        if (mInputView != null) {
+            // In non-fullscreen mode, {@link InputView} and its parent inputArea should expand to
+            // the entire screen and be placed at the bottom of {@link SoftInputWindow}.
+            // In fullscreen mode, these shouldn't expand to the entire screen and should be
+            // coexistent with {@link #mExtractedArea} above.
+            // See {@link InputMethodService#setInputView(View) and
+            // com.android.internal.R.layout.input_method.xml.
+            final int layoutHeight = isFullscreenMode()
+                    ? LayoutParams.WRAP_CONTENT : LayoutParams.MATCH_PARENT;
+            final View inputArea = window.findViewById(android.R.id.inputArea);
+            ViewLayoutUtils.updateLayoutHeightOf(inputArea, layoutHeight);
+            ViewLayoutUtils.updateLayoutGravityOf(inputArea, Gravity.BOTTOM);
+            ViewLayoutUtils.updateLayoutHeightOf(mInputView, layoutHeight);
+        }
         super.updateFullscreenMode();
-
-        if (mKeyPreviewBackingView == null) return;
-        // In fullscreen mode, no need to have extra space to show the key preview.
-        // If not, we should have extra space above the keyboard to show the key preview.
-        mKeyPreviewBackingView.setVisibility(isFullscreenMode() ? View.GONE : View.VISIBLE);
         mInputLogic.onUpdateFullscreenMode(isFullscreenMode());
     }
 
diff --git a/java/src/com/android/inputmethod/latin/utils/ViewLayoutUtils.java b/java/src/com/android/inputmethod/latin/utils/ViewLayoutUtils.java
index f9d853493e1fdc2cd50a3b8ae4ce0f6e1aa0f767..dd122b63481a3ef15b9639381c097d95576ee8ca 100644
--- a/java/src/com/android/inputmethod/latin/utils/ViewLayoutUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/ViewLayoutUtils.java
@@ -19,7 +19,10 @@ package com.android.inputmethod.latin.utils;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewGroup.MarginLayoutParams;
+import android.view.Window;
+import android.view.WindowManager;
 import android.widget.FrameLayout;
+import android.widget.LinearLayout;
 import android.widget.RelativeLayout;
 
 public final class ViewLayoutUtils {
@@ -51,4 +54,40 @@ public final class ViewLayoutUtils {
             marginLayoutParams.setMargins(x, y, 0, 0);
         }
     }
+
+    public static void updateLayoutHeightOf(final Window window, final int layoutHeight) {
+        final WindowManager.LayoutParams params = window.getAttributes();
+        if (params.height != layoutHeight) {
+            params.height = layoutHeight;
+            window.setAttributes(params);
+        }
+    }
+
+    public static void updateLayoutHeightOf(final View view, final int layoutHeight) {
+        final ViewGroup.LayoutParams params = view.getLayoutParams();
+        if (params.height != layoutHeight) {
+            params.height = layoutHeight;
+            view.setLayoutParams(params);
+        }
+    }
+
+    public static void updateLayoutGravityOf(final View view, final int layoutGravity) {
+        final ViewGroup.LayoutParams lp = view.getLayoutParams();
+        if (lp instanceof LinearLayout.LayoutParams) {
+            final LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)lp;
+            if (params.gravity != layoutGravity) {
+                params.gravity = layoutGravity;
+                view.setLayoutParams(params);
+            }
+        } else if (lp instanceof FrameLayout.LayoutParams) {
+            final FrameLayout.LayoutParams params = (FrameLayout.LayoutParams)lp;
+            if (params.gravity != layoutGravity) {
+                params.gravity = layoutGravity;
+                view.setLayoutParams(params);
+            }
+        } else {
+            throw new IllegalArgumentException("Layout parameter doesn't have gravity: "
+                    + lp.getClass().getName());
+        }
+    }
 }