// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package org.mozc.android.inputmethod.japanese;

import static org.mozc.android.inputmethod.japanese.testing.MozcMatcher.matchesKeyEvent;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.isA;
import static org.easymock.EasyMock.same;

import org.mozc.android.inputmethod.japanese.FeedbackManager.FeedbackEvent;
import org.mozc.android.inputmethod.japanese.KeycodeConverter.KeyEventInterface;
import org.mozc.android.inputmethod.japanese.MozcView.HeightLinearInterpolationListener;
import org.mozc.android.inputmethod.japanese.ViewManager.ViewManagerEventListener;
import org.mozc.android.inputmethod.japanese.emoji.EmojiProviderType;
import org.mozc.android.inputmethod.japanese.emoji.EmojiUtil;
import org.mozc.android.inputmethod.japanese.hardwarekeyboard.HardwareKeyboard;
import org.mozc.android.inputmethod.japanese.hardwarekeyboard.HardwareKeyboard.CompositionSwitchMode;
import org.mozc.android.inputmethod.japanese.keyboard.BackgroundDrawableFactory.DrawableType;
import org.mozc.android.inputmethod.japanese.keyboard.Key;
import org.mozc.android.inputmethod.japanese.keyboard.Key.Stick;
import org.mozc.android.inputmethod.japanese.keyboard.KeyEntity;
import org.mozc.android.inputmethod.japanese.keyboard.KeyEventContext;
import org.mozc.android.inputmethod.japanese.keyboard.KeyState;
import org.mozc.android.inputmethod.japanese.keyboard.KeyState.MetaState;
import org.mozc.android.inputmethod.japanese.keyboard.Keyboard;
import org.mozc.android.inputmethod.japanese.keyboard.Keyboard.KeyboardSpecification;
import org.mozc.android.inputmethod.japanese.keyboard.KeyboardActionListener;
import org.mozc.android.inputmethod.japanese.keyboard.KeyboardView;
import org.mozc.android.inputmethod.japanese.keyboard.ProbableKeyEventGuesser;
import org.mozc.android.inputmethod.japanese.model.JapaneseSoftwareKeyboardModel;
import org.mozc.android.inputmethod.japanese.model.JapaneseSoftwareKeyboardModel.KeyboardMode;
import org.mozc.android.inputmethod.japanese.model.SymbolCandidateStorage.SymbolHistoryStorage;
import org.mozc.android.inputmethod.japanese.model.SymbolMajorCategory;
import org.mozc.android.inputmethod.japanese.preference.ClientSidePreference.InputStyle;
import org.mozc.android.inputmethod.japanese.preference.ClientSidePreference.KeyboardLayout;
import org.mozc.android.inputmethod.japanese.protobuf.ProtoCandidates.CandidateList;
import org.mozc.android.inputmethod.japanese.protobuf.ProtoCandidates.CandidateWord;
import org.mozc.android.inputmethod.japanese.protobuf.ProtoCandidates.Candidates;
import org.mozc.android.inputmethod.japanese.protobuf.ProtoCandidates.Candidates.Candidate;
import org.mozc.android.inputmethod.japanese.protobuf.ProtoCommands;
import org.mozc.android.inputmethod.japanese.protobuf.ProtoCommands.Command;
import org.mozc.android.inputmethod.japanese.protobuf.ProtoCommands.CompositionMode;
import org.mozc.android.inputmethod.japanese.protobuf.ProtoCommands.Input;
import org.mozc.android.inputmethod.japanese.protobuf.ProtoCommands.Input.TouchEvent;
import org.mozc.android.inputmethod.japanese.protobuf.ProtoCommands.KeyEvent.ProbableKeyEvent;
import org.mozc.android.inputmethod.japanese.protobuf.ProtoCommands.KeyEvent.SpecialKey;
import org.mozc.android.inputmethod.japanese.protobuf.ProtoCommands.Output;
import org.mozc.android.inputmethod.japanese.resources.R;
import org.mozc.android.inputmethod.japanese.testing.InstrumentationTestCaseWithMock;
import org.mozc.android.inputmethod.japanese.testing.MockWindow;
import org.mozc.android.inputmethod.japanese.testing.Parameter;
import org.mozc.android.inputmethod.japanese.ui.MenuDialog;
import org.mozc.android.inputmethod.japanese.ui.MenuDialog.MenuDialogListener;
import org.mozc.android.inputmethod.japanese.util.ImeSwitcherFactory.ImeSwitcher;
import org.mozc.android.inputmethod.japanese.view.SkinType;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.graphics.Rect;
import android.inputmethodservice.InputMethodService.Insets;
import android.os.Build;
import android.os.Bundle;
import android.test.MoreAsserts;
import android.test.mock.MockContext;
import android.test.mock.MockResources;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.inputmethod.EditorInfo;

import org.easymock.Capture;
import org.easymock.EasyMock;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 */
public class ViewManagerTest extends InstrumentationTestCaseWithMock {

  private ViewManager createViewManager(Context context) {
    return createViewManagerWithEventListener(context, createNiceMock(ViewEventListener.class));
  }

  private ViewManager createViewManagerWithEventListener(
      Context context, ViewEventListener listener) {
    return new ViewManager(
        context, listener, createNiceMock(SymbolHistoryStorage.class),
        createNiceMock(ImeSwitcher.class), createNiceMock(MenuDialogListener.class));
  }

  @SmallTest
  public void testViewManagerEventListener() {
    ViewEventListener viewEventListener = createNiceMock(ViewEventListener.class);
    replayAll();
    Context context = getInstrumentation().getTargetContext();
    ViewManager viewManager = createViewManagerWithEventListener(context, viewEventListener);
    ViewManagerEventListener viewManagerEventListener =
        ViewManagerEventListener.class.cast(viewManager.eventListener);

    MozcView mozcView = viewManager.createMozcView(context);

    // Minimize keyboard frame view.
    View keyboardFrame = mozcView.getKeyboardFrame();
    keyboardFrame.setVisibility(View.INVISIBLE);
    LayoutParams layoutParams = keyboardFrame.getLayoutParams();
    layoutParams.height = 0;
    keyboardFrame.setLayoutParams(layoutParams);

    // Set the input frame fold button checked.
    mozcView.candidateViewManager.keyboardCandidateView.getInputFrameFoldButton().setChecked(true);

    resetAllToDefault();

    viewEventListener.onConversionCandidateSelected(0, Optional.<Integer>absent());
    replayAll();

    viewManagerEventListener.onConversionCandidateSelected(0, Optional.<Integer>absent());

    verifyAll();

    MoreAsserts.assertNotEqual(0, keyboardFrame.getLayoutParams().height);
    assertFalse(
        mozcView.candidateViewManager.keyboardCandidateView.getInputFrameFoldButton().isChecked());
  }

  @SmallTest
  public void testHeightLinearInterpolationListener() {
    HeightLinearInterpolationListener listener = new HeightLinearInterpolationListener(0, 256);
    LayoutParams layoutParams = new LayoutParams(0, 0);

    listener.calculateAnimatedParams(0, layoutParams);
    assertEquals(0, layoutParams.height);

    listener.calculateAnimatedParams(0.25f, layoutParams);
    assertEquals(64, layoutParams.height);

    listener.calculateAnimatedParams(0.5f, layoutParams);
    assertEquals(128, layoutParams.height);

    listener.calculateAnimatedParams(0.75f, layoutParams);
    assertEquals(192, layoutParams.height);

    listener.calculateAnimatedParams(1, layoutParams);
    assertEquals(256, layoutParams.height);
  }

  @SmallTest
  public void testCreateInputViewReturnsDifferentInstance() {
    Context context = getInstrumentation().getTargetContext();
    ViewManager viewManager = createViewManager(context);
    replayAll();

    View inputView1 = viewManager.createMozcView(context);
    View inputView2 = viewManager.createMozcView(context);

    verifyAll();
    assertNotSame(inputView1, inputView2);
  }

  @SmallTest
  public void testCreateInputView() {
    Context context = getInstrumentation().getTargetContext();
    ViewManager viewManager = createViewManager(context);
    replayAll();

    MozcView mozcView = viewManager.createMozcView(context);

    verifyAll();

    // createInputView shouldn't return null.
    assertNotNull(mozcView);

    // Keyboard instance is correctly registered.
    KeyboardView keyboardView = mozcView.getKeyboardView();
    assertTrue(keyboardView.getKeyboard().isPresent());

    // Make sure layout params.
    assertEquals(LayoutParams.MATCH_PARENT, keyboardView.getLayoutParams().width);
    assertEquals(LayoutParams.MATCH_PARENT, keyboardView.getLayoutParams().height);

    // Check visibility
    assertFalse(mozcView.candidateViewManager.isKeyboardCandidateViewVisible());
  }

  @SmallTest
  public void testRender_nullOutput() {
    ViewManager viewManager = createViewManager(getInstrumentation().getTargetContext());
    replayAll();

    viewManager.render(null);

    verifyAll();
  }

  @SmallTest
  public void testRender_noCandidateView() {
    ViewManager viewManager = createViewManager(getInstrumentation().getTargetContext());
    replayAll();

    // Render with no CandidateView
    Command outCommand = Command.newBuilder()
        .setOutput(Output.newBuilder()
            .setCandidates(Candidates.newBuilder()
                .addCandidate(Candidate.newBuilder().setId(0).setIndex(0).setValue("cand0"))
                .addCandidate(Candidate.newBuilder().setId(1).setIndex(1).setValue("cand1"))
                .setSize(2)
                .setPosition(0)))
        .buildPartial();
    viewManager.render(outCommand);

    verifyAll();
  }

  @SmallTest
  public void testRender_noRequestSuggest() {
    ViewManager viewManager = createViewManager(getInstrumentation().getTargetContext());
    MozcView mozcView = createViewMock(MozcView.class);
    viewManager.mozcView = mozcView;

    replayAll();

    // Render with CandidateView
    Command outCommand = Command.newBuilder()
        .setInput(Input.newBuilder()
            .setRequestSuggestion(false)
            .buildPartial())
        .setOutput(Output.getDefaultInstance())
        .buildPartial();
    viewManager.render(outCommand);

    // Make sure that mozcView is not touched.
    verifyAll();
  }

  @SuppressLint("WrongCall")
  @MediumTest
  public void testRender_withCandidate() {
    Context context = getInstrumentation().getTargetContext();
    ViewManager viewManager = createViewManager(context);
    replayAll();

    // Render with CandidateView
    MozcView mozcView = viewManager.createMozcView(context);
    CandidateView candidateView = mozcView.candidateViewManager.keyboardCandidateView;
    assertNotNull(candidateView);
    CandidateView.ConversionCandidateWordView candidateWordView =
        candidateView.getConversionCandidateWordView();
    candidateWordView.onLayout(false, 0, 0, 320, 240);
    assertNull(candidateWordView.calculatedLayout);

    viewManager.render(Command.newBuilder()
        .setOutput(Output.newBuilder()
            .setAllCandidateWords(CandidateList.newBuilder()
                .addCandidates(CandidateWord.getDefaultInstance())))
        .buildPartial());

    verifyAll();
    // CandidateView's bodyView has children now as a result of
    // calling CandidateView#update() from ViewManager#render().
    assertNotNull(candidateWordView.calculatedLayout);
  }

  @SmallTest
  public void testSetEditorInfo() {
    Context context = getInstrumentation().getTargetContext();
    MozcView mozcView = createViewMock(MozcView.class);
    ViewManager viewManager = createViewManager(context);
    viewManager.mozcView = mozcView;

    class TestData extends Parameter {
      final boolean allowEmoji;
      final boolean expectCarrierEnableEmoji;

      TestData(boolean allowEmoji, boolean expectCarrierEmojiEnabled) {
        this.allowEmoji = allowEmoji;
        this.expectCarrierEnableEmoji = expectCarrierEmojiEnabled;
      }
    }
    TestData[] testDataList = {
        new TestData(true, true),
        new TestData(false, false),
    };

    for (TestData testData : testDataList) {
      Bundle bundle = new Bundle();
      bundle.putBoolean("allowEmoji", testData.allowEmoji);
      EditorInfo editorInfo = new EditorInfo();
      editorInfo.extras = bundle;

      resetAll();
      mozcView.setEmojiEnabled(
          EmojiUtil.isUnicodeEmojiAvailable(Build.VERSION.SDK_INT),
          testData.expectCarrierEnableEmoji);
      expect(mozcView.getKeyboardSize()).andReturn(new Rect(0, 0, 100, 200));
      expect(mozcView.getResources()).andReturn(context.getResources());
      expect(mozcView.getInputFrameHeight()).andStubReturn(200);
      mozcView.setEditorInfo(editorInfo);
      mozcView.setPasswordField(false);
      mozcView.setKeyboard(isA(Keyboard.class));
      replayAll();

      viewManager.setEditorInfo(editorInfo);

      verifyAll();
    }
  }

  @SmallTest
  public void testNumberField() {
    ViewManager viewManager = createViewManager(getInstrumentation().getTargetContext());
    EditorInfo editorInfo = new EditorInfo();

    editorInfo.inputType = EditorInfo.TYPE_CLASS_DATETIME;
    viewManager.setEditorInfo(editorInfo);
    assertEquals(
        KeyboardMode.NUMBER, viewManager.getActiveSoftwareKeyboardModel().getKeyboardMode());
    assertEquals(
        KeyboardSpecification.HARDWARE_QWERTY_ALPHABET,
        viewManager.hardwareKeyboard.getKeyboardSpecification());

    editorInfo.inputType = EditorInfo.TYPE_CLASS_NUMBER;
    viewManager.setEditorInfo(editorInfo);
    assertEquals(
        KeyboardMode.NUMBER, viewManager.getActiveSoftwareKeyboardModel().getKeyboardMode());
    assertEquals(
        KeyboardSpecification.HARDWARE_QWERTY_ALPHABET,
        viewManager.hardwareKeyboard.getKeyboardSpecification());

    editorInfo.inputType = EditorInfo.TYPE_CLASS_PHONE;
    viewManager.setEditorInfo(editorInfo);
    assertEquals(
        KeyboardMode.NUMBER, viewManager.getActiveSoftwareKeyboardModel().getKeyboardMode());
    assertEquals(
        KeyboardSpecification.HARDWARE_QWERTY_ALPHABET,
        viewManager.hardwareKeyboard.getKeyboardSpecification());

    editorInfo.inputType = EditorInfo.TYPE_CLASS_TEXT;
    viewManager.setEditorInfo(editorInfo);
    assertEquals(KeyboardMode.KANA, viewManager.getActiveSoftwareKeyboardModel().getKeyboardMode());
    assertEquals(
        KeyboardSpecification.HARDWARE_QWERTY_KANA,
        viewManager.hardwareKeyboard.getKeyboardSpecification());
  }

  @SmallTest
  public void testHideSubInputView() {
    Context context = getInstrumentation().getTargetContext();
    ViewManager viewManager = createViewManager(context);
    MozcView mozcView = viewManager.createMozcView(context);
    SymbolInputView symbolInputView = mozcView.getSymbolInputView();

    class TestData extends Parameter {
      final int symbolInputViewVisibility;
      final boolean expectedResult;
      final int expectedSymbolInputViewVisibility;
      final boolean expectedSymbolInputViewOutAnimation;

      TestData(int symbolInputViewVisibility,
               boolean expectedResult,
               int expectedSymbolInputViewVisibility,
               boolean expectedSymbolInputViewOutAnimation) {
        this.symbolInputViewVisibility = symbolInputViewVisibility;
        this.expectedResult = expectedResult;
        this.expectedSymbolInputViewVisibility = expectedSymbolInputViewVisibility;
        this.expectedSymbolInputViewOutAnimation = expectedSymbolInputViewOutAnimation;
      }
    }
    TestData[] testDataList = {
        // If SymbolInputView is not visible, just returns false.
        new TestData(View.GONE, false, View.GONE, false),

        // If SymbolInputView is visible, start hiding animation.
        new TestData(View.VISIBLE, true, View.VISIBLE, true),
    };

    for (TestData testData : testDataList) {
      symbolInputView.setVisibility(testData.symbolInputViewVisibility);
      symbolInputView.clearAnimation();

      assertEquals(testData.toString(), testData.expectedResult, viewManager.hideSubInputView());
      assertEquals(testData.toString(),
                   testData.expectedSymbolInputViewVisibility, symbolInputView.getVisibility());
      assertEquals(
          testData.toString(),
          testData.expectedSymbolInputViewOutAnimation, symbolInputView.getAnimation() != null);
    }
  }

  @SmallTest
  public void testKeyboardSwitchEventCallback() {
    Context context = getInstrumentation().getTargetContext();
    ViewEventListener eventListener = createMock(ViewEventListener.class);
    ViewManager viewManager = createViewManagerWithEventListener(context, eventListener);

    assertEquals(KeyboardSpecification.TWELVE_KEY_TOGGLE_KANA,
                 viewManager.getKeyboardSpecification());

    // Make sure that whenever keyboard is changed, the callback should be invoked.
    eventListener.onKeyEvent(null, null, KeyboardSpecification.QWERTY_KANA,
                             Collections.<TouchEvent>emptyList());
    replayAll();
    viewManager.setKeyboardLayout(KeyboardLayout.QWERTY);
    verifyAll();

    resetAll();
    eventListener.onKeyEvent(null, null, KeyboardSpecification.TWELVE_KEY_TOGGLE_KANA,
                             Collections.<TouchEvent>emptyList());
    replayAll();
    viewManager.setKeyboardLayout(KeyboardLayout.TWELVE_KEYS);
    verifyAll();
  }

  @SmallTest
  public void testKeyboardSwitching() {
    Context context = getInstrumentation().getTargetContext();
    Resources resources = context.getResources();

    ViewManager viewManager = createViewManager(context);
    replayAll();
    MozcView mozcView = viewManager.createMozcView(context);
    KeyboardView keyboardView = mozcView.getKeyboardView();
    HardwareKeyboard hardwareKeyboard = viewManager.hardwareKeyboard;
    List<TouchEvent> touchEventList = Collections.singletonList(TouchEvent.getDefaultInstance());

    // The default keyboard is 12key's-"kana"-toggle mode.
    assertEquals(KeyboardSpecification.TWELVE_KEY_TOGGLE_KANA,
                 keyboardView.getKeyboard().get().getSpecification());
    assertEquals(KeyboardSpecification.HARDWARE_QWERTY_KANA,
                 hardwareKeyboard.getKeyboardSpecification());

    viewManager.onKey(resources.getInteger(R.integer.key_chartype_to_abc), touchEventList);
    assertEquals(KeyboardSpecification.TWELVE_KEY_TOGGLE_ALPHABET,
                 keyboardView.getKeyboard().get().getSpecification());
    assertEquals(KeyboardSpecification.HARDWARE_QWERTY_ALPHABET,
                 hardwareKeyboard.getKeyboardSpecification());

    viewManager.onKey(resources.getInteger(R.integer.key_chartype_to_kana), touchEventList);
    assertEquals(KeyboardSpecification.TWELVE_KEY_TOGGLE_KANA,
                 keyboardView.getKeyboard().get().getSpecification());
    assertEquals(KeyboardSpecification.HARDWARE_QWERTY_KANA,
                 hardwareKeyboard.getKeyboardSpecification());

    // The default mode is "kana".
    viewManager.setKeyboardLayout(KeyboardLayout.QWERTY);
    assertEquals(KeyboardSpecification.QWERTY_KANA,
                 keyboardView.getKeyboard().get().getSpecification());
    assertEquals(KeyboardSpecification.HARDWARE_QWERTY_KANA,
                 hardwareKeyboard.getKeyboardSpecification());


    viewManager.onKey(resources.getInteger(R.integer.key_chartype_to_kana), touchEventList);
    assertEquals(KeyboardSpecification.QWERTY_KANA,
                 keyboardView.getKeyboard().get().getSpecification());
    assertEquals(KeyboardSpecification.HARDWARE_QWERTY_KANA,
                 hardwareKeyboard.getKeyboardSpecification());

    viewManager.onKey(resources.getInteger(R.integer.key_chartype_to_abc), touchEventList);
    assertEquals(KeyboardSpecification.QWERTY_ALPHABET,
                 keyboardView.getKeyboard().get().getSpecification());
    assertEquals(KeyboardSpecification.HARDWARE_QWERTY_ALPHABET,
                 hardwareKeyboard.getKeyboardSpecification());

    viewManager.onKey(resources.getInteger(R.integer.key_chartype_to_abc), touchEventList);
    assertEquals(KeyboardSpecification.QWERTY_ALPHABET,
                 keyboardView.getKeyboard().get().getSpecification());
    assertEquals(KeyboardSpecification.HARDWARE_QWERTY_ALPHABET,
                 hardwareKeyboard.getKeyboardSpecification());

    viewManager.onKey(resources.getInteger(R.integer.key_chartype_to_kana), touchEventList);
    assertEquals(KeyboardSpecification.QWERTY_KANA,
                 keyboardView.getKeyboard().get().getSpecification());
    assertEquals(KeyboardSpecification.HARDWARE_QWERTY_KANA,
                 hardwareKeyboard.getKeyboardSpecification());

    // Make sure we can return back to 12-keys keyboard.
    viewManager.setKeyboardLayout(KeyboardLayout.TWELVE_KEYS);
    assertEquals(KeyboardSpecification.TWELVE_KEY_TOGGLE_KANA,
                 keyboardView.getKeyboard().get().getSpecification());
    assertEquals(KeyboardSpecification.HARDWARE_QWERTY_KANA,
                 hardwareKeyboard.getKeyboardSpecification());

    // Then set to flick mode.
    viewManager.setInputStyle(InputStyle.FLICK);
    assertEquals(KeyboardSpecification.TWELVE_KEY_FLICK_KANA,
                 keyboardView.getKeyboard().get().getSpecification());
    assertEquals(KeyboardSpecification.HARDWARE_QWERTY_KANA,
                 hardwareKeyboard.getKeyboardSpecification());

    viewManager.onKey(resources.getInteger(R.integer.key_chartype_to_abc), touchEventList);
    assertEquals(KeyboardSpecification.TWELVE_KEY_FLICK_ALPHABET,
                 keyboardView.getKeyboard().get().getSpecification());
    assertEquals(KeyboardSpecification.HARDWARE_QWERTY_ALPHABET,
                 hardwareKeyboard.getKeyboardSpecification());

    // Return back to flick-kana mode.
    viewManager.onKey(resources.getInteger(R.integer.key_chartype_to_kana), touchEventList);
    assertEquals(KeyboardSpecification.TWELVE_KEY_FLICK_KANA,
                 keyboardView.getKeyboard().get().getSpecification());
    assertEquals(KeyboardSpecification.HARDWARE_QWERTY_KANA,
                 hardwareKeyboard.getKeyboardSpecification());

    // Then set to toggle-flick mode.
    viewManager.setInputStyle(InputStyle.TOGGLE_FLICK);
    assertEquals(KeyboardSpecification.TWELVE_KEY_TOGGLE_FLICK_KANA,
                 keyboardView.getKeyboard().get().getSpecification());
    assertEquals(KeyboardSpecification.HARDWARE_QWERTY_KANA,
                 hardwareKeyboard.getKeyboardSpecification());

    viewManager.onKey(resources.getInteger(R.integer.key_chartype_to_abc), touchEventList);
    assertEquals(KeyboardSpecification.TWELVE_KEY_TOGGLE_FLICK_ALPHABET,
                 keyboardView.getKeyboard().get().getSpecification());
    assertEquals(KeyboardSpecification.HARDWARE_QWERTY_ALPHABET,
                 hardwareKeyboard.getKeyboardSpecification());

    // Return back to flick-kana mode.
    viewManager.onKey(resources.getInteger(R.integer.key_chartype_to_kana), touchEventList);
    assertEquals(KeyboardSpecification.TWELVE_KEY_TOGGLE_FLICK_KANA,
                 keyboardView.getKeyboard().get().getSpecification());
    assertEquals(KeyboardSpecification.HARDWARE_QWERTY_KANA,
                 hardwareKeyboard.getKeyboardSpecification());

    // Testing for qwerty layout for alphabet mode.
    viewManager.setQwertyLayoutForAlphabet(true);
    assertEquals(KeyboardSpecification.TWELVE_KEY_TOGGLE_FLICK_KANA,
                 keyboardView.getKeyboard().get().getSpecification());
    assertEquals(KeyboardSpecification.HARDWARE_QWERTY_KANA,
                 hardwareKeyboard.getKeyboardSpecification());

    viewManager.onKey(resources.getInteger(R.integer.key_chartype_to_abc), touchEventList);
    assertEquals(KeyboardSpecification.TWELVE_KEY_TOGGLE_QWERTY_ALPHABET,
                 keyboardView.getKeyboard().get().getSpecification());
    assertEquals(KeyboardSpecification.HARDWARE_QWERTY_ALPHABET,
                 hardwareKeyboard.getKeyboardSpecification());

    // Switching the mode should trigger the alphabet keyboard view switching as well.
    viewManager.setQwertyLayoutForAlphabet(false);
    assertEquals(KeyboardSpecification.TWELVE_KEY_TOGGLE_FLICK_ALPHABET,
                 keyboardView.getKeyboard().get().getSpecification());
    assertEquals(KeyboardSpecification.HARDWARE_QWERTY_ALPHABET,
                 hardwareKeyboard.getKeyboardSpecification());

    viewManager.setQwertyLayoutForAlphabet(true);
    assertEquals(KeyboardSpecification.TWELVE_KEY_TOGGLE_QWERTY_ALPHABET,
                 keyboardView.getKeyboard().get().getSpecification());
    assertEquals(KeyboardSpecification.HARDWARE_QWERTY_ALPHABET,
                 hardwareKeyboard.getKeyboardSpecification());

    viewManager.onKey(resources.getInteger(R.integer.key_chartype_to_abc), touchEventList);
    assertEquals(KeyboardSpecification.TWELVE_KEY_TOGGLE_QWERTY_ALPHABET,
                 keyboardView.getKeyboard().get().getSpecification());
    assertEquals(KeyboardSpecification.HARDWARE_QWERTY_ALPHABET,
                 hardwareKeyboard.getKeyboardSpecification());

    viewManager.onKey(resources.getInteger(R.integer.key_chartype_to_kana), touchEventList);
    assertEquals(KeyboardSpecification.TWELVE_KEY_TOGGLE_FLICK_KANA,
                 keyboardView.getKeyboard().get().getSpecification());
    assertEquals(KeyboardSpecification.HARDWARE_QWERTY_KANA,
                 hardwareKeyboard.getKeyboardSpecification());

    viewManager.setQwertyLayoutForAlphabet(false);
    assertEquals(KeyboardSpecification.TWELVE_KEY_TOGGLE_FLICK_KANA,
                 keyboardView.getKeyboard().get().getSpecification());
    assertEquals(KeyboardSpecification.HARDWARE_QWERTY_KANA,
                 hardwareKeyboard.getKeyboardSpecification());
  }

  @SmallTest
  public void testShowMenuDialog() {
    Context context = getInstrumentation().getTargetContext();

    ViewEventListener listener = createMock(ViewEventListener.class);
    List<TouchEvent> touchEventList = Collections.singletonList(TouchEvent.getDefaultInstance());
    listener.onShowMenuDialog(touchEventList);
    ViewManager viewManager = createViewManagerWithEventListener(context, listener);
    replayAll();
    viewManager.onKey(
        context.getResources().getInteger(R.integer.key_menu_dialog), touchEventList);
    verifyAll();
  }

  @SmallTest
  public void testSetKeyboardStyleForUninitializedKeyboardViewDefault() {
    Context context = getInstrumentation().getTargetContext();
    ViewManager viewManager = createViewManager(context);

    // Make sure keyboard by createInputView is 12keys-kana keyboard by default.
    MozcView mozcView = viewManager.createMozcView(context);
    KeyboardView keyboardView = mozcView.getKeyboardView();
    assertEquals(KeyboardSpecification.TWELVE_KEY_TOGGLE_KANA,
                 keyboardView.getKeyboard().get().getSpecification());
  }

  @SmallTest
  public void testSetKeyboardLayoutForUninitializedInputView() {
    Context context = getInstrumentation().getTargetContext();
    ViewManager viewManager = createViewManager(context);

    // Set MobileInputStyle before creating InputView.
    viewManager.setKeyboardLayout(KeyboardLayout.QWERTY);

    // Make sure the keyboard instance created via createInputView is not default keyboard.
    MozcView mozcView = viewManager.createMozcView(context);
    KeyboardView keyboardView = mozcView.getKeyboardView();
    assertEquals(KeyboardSpecification.QWERTY_KANA,
                 keyboardView.getKeyboard().get().getSpecification());
  }

  @SmallTest
  public void testSetTwelveKeyInputStyleForUninitializedInputView() {
    Context context = getInstrumentation().getTargetContext();
    ViewManager viewManager = createViewManager(context);

    // Set TwelveKeysInputStyle before creating InputView.
    viewManager.setInputStyle(InputStyle.FLICK);

    // Make sure the keyboard instance created via createInputView is not default keyboard.
    MozcView mozcView = viewManager.createMozcView(context);
    KeyboardView keyboardView = mozcView.getKeyboardView();
    assertEquals(KeyboardSpecification.TWELVE_KEY_FLICK_KANA,
                 keyboardView.getKeyboard().get().getSpecification());
  }

  @SmallTest
  public void testSetKeyboardLayoutWithNull() {
    ViewManager viewManager = createViewManager(getInstrumentation().getTargetContext());
    try {
      viewManager.setKeyboardLayout(null);
      fail("NullPointerException is expected.");
    } catch (NullPointerException e) {
      // success.
    }
  }

  @SmallTest
  public void testCreateKeyEvent() {
    Context context = getInstrumentation().getTargetContext();
    ViewEventListener listener = createMock(ViewEventListener.class);
    ProbableKeyEventGuesser guesser = createMockBuilder(ProbableKeyEventGuesser.class)
        .addMockedMethod("getProbableKeyEvents")
        .withConstructor(AssetManager.class)
        .withArgs(getInstrumentation().getTargetContext().getAssets())
        .createMock();
    ViewManager viewManager = new ViewManager(
        context, listener, createNiceMock(SymbolHistoryStorage.class),
        createMock(ImeSwitcher.class), createNiceMock(MenuDialogListener.class), guesser,
        new HardwareKeyboard());
    viewManager.createMozcView(context);
    KeyboardSpecification keyboardSpecification =
        JapaneseSoftwareKeyboardModel.class.cast(viewManager.getActiveSoftwareKeyboardModel())
            .getKeyboardSpecification();

    Resources resources = context.getResources();
    List<TouchEvent> touchEventList = Collections.singletonList(TouchEvent.getDefaultInstance());

    class TestData {
      final int keyCode;
      final List<ProbableKeyEvent> probableKeyEvents;
      final boolean expectInvokeGuesser;
      final ProtoCommands.KeyEvent expectKeyEvent;
      final int expectKeyCode;
      TestData(int keyCode, ProbableKeyEvent[] probableKeyEvents,
               boolean expectInvokeGuesser,
               ProtoCommands.KeyEvent expectKeyEvent, int expectKeyCode) {
        this.keyCode = keyCode;
        this.probableKeyEvents =
            probableKeyEvents == null ? Collections.<ProbableKeyEvent>emptyList()
                                      : Arrays.asList(probableKeyEvents);
        this.expectInvokeGuesser = expectInvokeGuesser;
        this.expectKeyEvent = expectKeyEvent;
        this.expectKeyCode = expectKeyCode;
      }
    }

    TestData[] testDataList = {
        // White space.
        new TestData(' ',
                     new ProbableKeyEvent[0],
                     false,
                     ProtoCommands.KeyEvent.newBuilder().setSpecialKey(SpecialKey.SPACE).build(),
                     KeyEvent.KEYCODE_SPACE),
        // Enter.
        new TestData(resources.getInteger(R.integer.key_enter),
                     new ProbableKeyEvent[0],
                     false,
                     ProtoCommands.KeyEvent.newBuilder()
                         .setSpecialKey(SpecialKey.VIRTUAL_ENTER).build(),
                     KeyEvent.KEYCODE_ENTER),
        // Delete.
        new TestData(resources.getInteger(R.integer.key_backspace),
                     new ProbableKeyEvent[0],
                     false,
                     ProtoCommands.KeyEvent.newBuilder().setSpecialKey(SpecialKey.BACKSPACE)
                         .build(),
                     KeyEvent.KEYCODE_DEL),
        // Left.
        new TestData(resources.getInteger(R.integer.key_left),
                     new ProbableKeyEvent[0],
                     false,
                     ProtoCommands.KeyEvent.newBuilder()
                         .setSpecialKey(SpecialKey.VIRTUAL_LEFT).build(),
                     KeyEvent.KEYCODE_DPAD_LEFT),
        // Right.
        new TestData(resources.getInteger(R.integer.key_right),
                     new ProbableKeyEvent[0],
                     false,
                     ProtoCommands.KeyEvent.newBuilder()
                         .setSpecialKey(SpecialKey.VIRTUAL_RIGHT).build(),
                     KeyEvent.KEYCODE_DPAD_RIGHT),
        // Normal character with no correction stats.
        new TestData('a',
                     new ProbableKeyEvent[0],
                     true,
                     ProtoCommands.KeyEvent.newBuilder().setKeyCode('a').build(),
                     KeyEvent.KEYCODE_A),
        // Normal character with correction stats.
        new TestData('a',
                     new ProbableKeyEvent[] {
                        ProbableKeyEvent.newBuilder().setKeyCode('b').setProbability(0.1d).build()},
                     true,
                     ProtoCommands.KeyEvent.newBuilder()
                                           .setKeyCode('a')
                                           .addAllProbableKeyEvent(
                                               Arrays.asList(
                                                   ProbableKeyEvent.newBuilder()
                                                                   .setKeyCode('b')
                                                                   .setProbability(0.1d)
                                                                   .build()))
                                           .build(),
                     KeyEvent.KEYCODE_A)
    };

    for (TestData testData : testDataList) {
      resetAll();
      listener.onKeyEvent(eq(testData.expectKeyEvent),
                          matchesKeyEvent(testData.expectKeyCode),
                          eq(keyboardSpecification), eq(touchEventList));
      if (testData.expectInvokeGuesser) {
        expect(guesser.getProbableKeyEvents(touchEventList))
            .andReturn(testData.probableKeyEvents);
      }
      replayAll();
      viewManager.onKey(testData.keyCode, touchEventList);
      verifyAll();
    }
  }

  @SmallTest
  public void testCreateKeyEventForInvalidKeyCode() {
    Context context = getInstrumentation().getTargetContext();
    ViewEventListener listener = createNiceMock(ViewEventListener.class);
    ViewManager viewManager = createViewManagerWithEventListener(context, listener);
    viewManager.createMozcView(context);
    // Invalid Keycode.
    resetAll();
    replayAll();
    viewManager.onKey(Integer.MIN_VALUE, Collections.<TouchEvent>emptyList());
    verifyAll();
  }

  @SmallTest
  public void testOnKeyForSwitchingKeyboard() {
    Context context = getInstrumentation().getTargetContext();
    ViewEventListener listener = createMock(ViewEventListener.class);
    ViewManager viewManager = createViewManagerWithEventListener(context, listener);
    MozcView mozcView = viewManager.createMozcView(context);

    Resources resources = context.getResources();

    resetAll();
    List<TouchEvent> touchEventList = Collections.singletonList(TouchEvent.getDefaultInstance());
    listener.onKeyEvent(null, null,
                        KeyboardSpecification.TWELVE_KEY_TOGGLE_ALPHABET, touchEventList);
    replayAll();

    // Make sure the current keyboard is 12keys-toggle-kana mode before sending a key.
    KeyboardView keyboardView = mozcView.getKeyboardView();
    assertEquals(KeyboardSpecification.TWELVE_KEY_TOGGLE_KANA,
                 keyboardView.getKeyboard().get().getSpecification());

    // Send key code to switch number keyboard style.
    viewManager.onKey(resources.getInteger(R.integer.key_chartype_to_abc), touchEventList);

    // Make sure actually keyboard style has been changed.
    assertEquals(KeyboardSpecification.TWELVE_KEY_TOGGLE_ALPHABET,
                 keyboardView.getKeyboard().get().getSpecification());

    // Make sure that the listener can catch the expected events.
    verifyAll();
  }

  @SmallTest
  public void testOnKeyForGlobeButton() {
    Context context = getInstrumentation().getTargetContext();
    ImeSwitcher imeSwitcher = createMock(ImeSwitcher.class);

    ViewManager viewManager = new ViewManager(
        context, createNiceMock(ViewEventListener.class),
        createNiceMock(SymbolHistoryStorage.class),
        imeSwitcher, createNiceMock(MenuDialogListener.class));

    expect(imeSwitcher.switchToNextInputMethod(false)).andReturn(Boolean.TRUE);

    replayAll();
    viewManager.onKey(context.getResources().getInteger(R.integer.key_globe),
                      Collections.<TouchEvent>emptyList());
    verifyAll();
  }

  @SmallTest
  public void testKeyboardActionAdapter_onKey() {
    Context context = getInstrumentation().getTargetContext();
    List<TouchEvent> touchEventList = Collections.singletonList(TouchEvent.getDefaultInstance());
    ViewEventListener listener = createNiceMock(ViewEventListener.class);
    ViewManager viewManager = createViewManagerWithEventListener(context, listener);
    resetAll();
    listener.onKeyEvent(
        eq(ProtoCommands.KeyEvent.newBuilder().setKeyCode('1').build()),
        anyObject(KeyEventInterface.class),
        anyObject(KeyboardSpecification.class), same(touchEventList));
    replayAll();
    KeyboardActionListener keyboardActionListener = viewManager.new KeyboardActionAdapter();
    keyboardActionListener.onKey('1', touchEventList);

    verifyAll();
  }

  @SmallTest
  public void testKeyboardActionAdapter_onPress() {
    Context context = getInstrumentation().getTargetContext();
    ViewEventListener listener = createMock(ViewEventListener.class);
    ViewManager viewManager = createViewManagerWithEventListener(context, listener);

    KeyboardActionListener keyboardActionListener = viewManager.new KeyboardActionAdapter();

    // Listener should receive onFireFeedbackEvent.
    listener.onFireFeedbackEvent(FeedbackEvent.KEY_DOWN);
    replayAll();
    keyboardActionListener.onPress(10);
    verifyAll();

    // Listener shouldn't receive onFireFeedbackEvent for INVALID_KEY_CODE.
    resetAll();
    replayAll();
    keyboardActionListener.onPress(KeyEntity.INVALID_KEY_CODE);
    verifyAll();
  }

  @SmallTest
  public void testSimpleOnKey() {
    Context context = getInstrumentation().getTargetContext();
    ViewEventListener listener = createMock(ViewEventListener.class);
    ViewManager viewManager = createViewManagerWithEventListener(context, listener);
    viewManager.createMozcView(context);
    KeyboardSpecification keyboardSpecification =
        JapaneseSoftwareKeyboardModel.class.cast(viewManager.getActiveSoftwareKeyboardModel())
            .getKeyboardSpecification();

    // Emulate toggling a key.
    resetAll();
    List<TouchEvent> touchEventList = Collections.singletonList(TouchEvent.getDefaultInstance());
    listener.onKeyEvent(anyObject(ProtoCommands.KeyEvent.class),
                        matchesKeyEvent(KeyEvent.KEYCODE_1),
                        eq(keyboardSpecification), eq(touchEventList));
    replayAll();
    viewManager.onKey('1', touchEventList);

    verifyAll();
  }

  @SmallTest
  public void testRender_visibility() {
    Context context = getInstrumentation().getTargetContext();
    ViewEventListener listener = createMock(ViewEventListener.class);
    ViewManager viewManager = createViewManagerWithEventListener(context, listener);

    // Rendering null. Just making sure that this shouldn't fail.
    viewManager.render(null);

    // Rendering before the mozcView is initialized. Again making sure no-failure.
    viewManager.render(Command.getDefaultInstance());

    // Set mozcView mock.
    MozcView mozcView = createViewMock(MozcView.class);
    viewManager.mozcView = mozcView;

    // Render with empty output.
    {
      resetAll();
      Command emptyOutput = Command.getDefaultInstance();
      mozcView.setCommand(emptyOutput);
      mozcView.resetKeyboardFrameVisibility();
      replayAll();

      viewManager.render(emptyOutput);

      verifyAll();
    }

    // Render with non-empty output.
    {
      resetAll();
      Command output = Command.newBuilder()
          .setOutput(Output.newBuilder()
              .setAllCandidateWords(CandidateList.newBuilder()
                  .addCandidates(CandidateWord.getDefaultInstance())))
          .buildPartial();
      mozcView.setCommand(output);
      replayAll();

      viewManager.render(output);

      verifyAll();
    }
  }

  @SmallTest
  public void testReset() {
    Context context = getInstrumentation().getTargetContext();
    ViewManager viewManager = createViewManager(context);

    MozcView mozcView = viewManager.createMozcView(context);
    // TODO(matsuzakit): The lines from the beginning of the method to here should be
    //     extracted into a method.
    // Set pre-condition and call reset().
    mozcView.getKeyboardFrame().setVisibility(View.GONE);
    LayoutParams layoutParams = mozcView.getKeyboardFrame().getLayoutParams();
    layoutParams.height = 0;
    Map<Integer, KeyEventContext> keyEventContextMap =
        mozcView.getKeyboardView().keyEventContextMap;
    {
      // Add dummy KeyEventContext.
      KeyEventContext keyEventContext =
          new KeyEventContext(
              new Key(0, 0, 0, 0, 0, 0, false, false, Stick.EVEN,
                      DrawableType.TWELVEKEYS_REGULAR_KEY_BACKGROUND,
                      Collections.<KeyState>emptyList()),
              0, 0, 0, 0, 0, 0, Collections.<MetaState>emptySet());
      keyEventContextMap.put(0, keyEventContext);
    }

    mozcView.softwareKeyboardHeightListener.onExpanded();
    mozcView.getSymbolInputView().startInAnimation();

    MenuDialog menuDialog = createMockBuilder(MenuDialog.class)
        .withConstructor(Context.class, Optional.class)
        .withArgs(context, Optional.of(createNiceMock(MenuDialogListener.class)))
        .createMock();
    resetAll();
    viewManager.menuDialog = menuDialog;
    menuDialog.dismiss();
    replayAll();

    viewManager.reset();

    // Post-condition.
    verifyAll();
    assertEquals(View.VISIBLE, mozcView.getKeyboardFrame().getVisibility());
    assertEquals(context.getResources().getDimensionPixelSize(R.dimen.input_frame_height),
                 mozcView.getKeyboardFrame().getLayoutParams().height);
    assertFalse(mozcView.candidateViewManager.isKeyboardCandidateViewVisible());
    assertEquals(View.GONE, mozcView.getSymbolInputView().getVisibility());
    assertNull(mozcView.candidateViewManager.keyboardCandidateView.getAnimation());
    assertNull(mozcView.getSymbolInputView().getAnimation());
    assertTrue(keyEventContextMap.isEmpty());
  }

  @SmallTest
  public void testComputeInsets() {
    class TestData extends Parameter {
      final int contentViewHeight;
      final int inputFrameHeight;
      final int expectedContentTopInsets;

      public TestData(int contentViewHeight,
                      int inputFrameHeight,
                      int expectedContentTopInsets) {
        this.contentViewHeight = contentViewHeight;
        this.inputFrameHeight = inputFrameHeight;
        this.expectedContentTopInsets = expectedContentTopInsets;
      }
    }

    TestData[] testDataList = {
        new TestData(480, 240, 240),
        new TestData(480, 325, 155),
    };

    Context context = getInstrumentation().getTargetContext();
    ViewManager viewManager = createViewManager(context);
    Window window = createMockBuilder(MockWindow.class)
        .withConstructor(Context.class)
        .withArgs(context)
        .createMock();
    Resources mockResources = createNiceMock(MockResources.class);
    Context mockContext = createNiceMock(MockContext.class);

    for (TestData testData : testDataList) {
      resetAll();
      viewManager.mozcView = null;

      View mockContentView = new View(context);
      mockContentView.layout(0, 0, 0, testData.contentViewHeight);
      expect(window.findViewById(Window.ID_ANDROID_CONTENT)).andReturn(mockContentView);

      expect(mockResources.getDimensionPixelSize(R.dimen.input_frame_height))
          .andStubReturn(testData.inputFrameHeight);
      expect(mockContext.getResources()).andStubReturn(mockResources);
      replayAll();

      Insets insets = new Insets();
      viewManager.computeInsets(mockContext, insets, window);

      verifyAll();
      assertEquals(
          testData.toString(), testData.expectedContentTopInsets, insets.contentTopInsets);
      assertEquals(
          testData.toString(), insets.contentTopInsets, insets.visibleTopInsets);
      assertEquals(
          testData.toString(), Insets.TOUCHABLE_INSETS_CONTENT, insets.touchableInsets);
    }

    {
      MozcView mozcView = createViewMock(MozcView.class);
      resetAll();
      viewManager.mozcView = mozcView;

      int contentViewWidth = 200;
      int contentViewHeight = 400;
      View mockContentView = new View(context);
      mockContentView.layout(0, 0, contentViewWidth, contentViewHeight);
      expect(window.findViewById(Window.ID_ANDROID_CONTENT)).andReturn(mockContentView);
      Insets insets = new Insets();
      mozcView.setInsets(contentViewWidth, contentViewHeight, insets);

      replayAll();

      viewManager.computeInsets(mockContext, insets, window);

      verifyAll();
    }
  }

  @SmallTest
  public void testSetFullscreenMode() {
    Context context = getInstrumentation().getTargetContext();
    ViewManager viewManager = createViewManager(context);
    MozcView mozcView = viewManager.createMozcView(context);

    for (boolean fullscreenMode : new boolean[] {true, false}) {
      viewManager.setFullscreenMode(fullscreenMode);
      assertEquals(fullscreenMode, viewManager.isFullscreenMode());
      assertEquals(fullscreenMode, mozcView.isFullscreenMode());
    }
  }

  @SmallTest
  public void testSetEmojiProviderType() {
    Context context = getInstrumentation().getTargetContext();
    ViewManager viewManager = createViewManager(context);
    MozcView mozcView = createViewMock(MozcView.class);
    viewManager.mozcView = mozcView;

    for (EmojiProviderType emojiProviderType : EmojiProviderType.values()) {
      resetAll();
      mozcView.setEmojiProviderType(emojiProviderType);
      replayAll();

      viewManager.setEmojiProviderType(emojiProviderType);

      verifyAll();
      assertEquals(emojiProviderType, viewManager.emojiProviderType);
    }
  }

  @SmallTest
  public void testSetNarrowMode() {
    Context context = getInstrumentation().getTargetContext();
    ViewManager viewManager = createViewManager(context);
    MozcView mozcView = viewManager.createMozcView(context);

    // viewManager to mozcView.
    viewManager.setNarrowMode(true);
    assertTrue(mozcView.isNarrowMode());
    viewManager.setNarrowMode(false);
    assertFalse(mozcView.isNarrowMode());
  }

  @SmallTest
  public void testSetPopupEnabled() {
    Context context = getInstrumentation().getTargetContext();
    ViewManager viewManager = createViewManager(context);
    MozcView mozcView = viewManager.createMozcView(context);

    // viewManager to mozcView.
    viewManager.setPopupEnabled(false);
    assertFalse(mozcView.isPopupEnabled());
    viewManager.setPopupEnabled(true);
    assertTrue(mozcView.isPopupEnabled());
  }

  @SmallTest
  public void testSetFlickSensitivity() {
    Context context = getInstrumentation().getTargetContext();
    ViewManager viewManager = createViewManager(context);
    MozcView mozcView = viewManager.createMozcView(context);

    viewManager.setFlickSensitivity(10);
    assertEquals(10, mozcView.getKeyboardView().getFlickSensitivity());
    viewManager.setFlickSensitivity(-10);
    assertEquals(-10, mozcView.getKeyboardView().getFlickSensitivity());
  }

  @SmallTest
  public void testSetSkinType() {
    Context context = getInstrumentation().getTargetContext();
    Resources resources = context.getResources();
    ViewManager viewManager = createViewManager(context);
    MozcView mozcView = viewManager.createMozcView(context);

    viewManager.setSkin(SkinType.ORANGE_LIGHTGRAY.getSkin(resources));
    assertEquals(SkinType.ORANGE_LIGHTGRAY.getSkin(resources), mozcView.getSkin());
    viewManager.setSkin(SkinType.TEST.getSkin(resources));
    assertEquals(SkinType.TEST.getSkin(resources), mozcView.getSkin());
  }

  @SmallTest
  public void testMaybeTransitToNarrowMode() {
    Context context = getInstrumentation().getTargetContext();
    ViewManager viewManager = createViewManager(context);

    class TestData extends Parameter {
      final Command command;
      final KeyEventInterface keyEventInterface;
      final boolean expectation;
      public TestData(Command command, KeyEventInterface keyEventInterface, boolean expectation) {
        this.command = command;
        this.keyEventInterface = keyEventInterface;
        this.expectation = expectation;
      }
    }
    KeyEventInterface softwareEvent = new KeyEventInterface() {
      @Override
      public Optional<KeyEvent> getNativeEvent() {
        return Optional.absent();
      }
      @Override
      public int getKeyCode() {
        return 0;
      }
    };
    KeyEventInterface hardwareEvent = new KeyEventInterface() {
      @Override
      public Optional<KeyEvent> getNativeEvent() {
        return Optional.of(new KeyEvent(0, 0));
      }
      @Override
      public int getKeyCode() {
        return 0;
      }
    };
    Command noKey = Command.newBuilder().setInput(Input.getDefaultInstance()).buildPartial();
    Command noKeyCode = Command.newBuilder()
        .setInput(Input.newBuilder()
            .setKey(ProtoCommands.KeyEvent.getDefaultInstance())
            .buildPartial())
        .buildPartial();
    Command withModifier = Command.newBuilder()
        .setInput(Input.newBuilder()
            .setKey(ProtoCommands.KeyEvent.newBuilder()
                .setKeyCode(0)
                .setModifiers(0))
            .buildPartial())
        .buildPartial();
    Command printable = Command.newBuilder()
        .setInput(Input.newBuilder()
            .setKey(ProtoCommands.KeyEvent.newBuilder()
                .setKeyCode(0))
            .buildPartial())
        .buildPartial();
    TestData[] testDataList = new TestData[] {
        new TestData(noKey, hardwareEvent, false),
        new TestData(noKeyCode, hardwareEvent, true),
        new TestData(withModifier, hardwareEvent, true),
        new TestData(printable, null, false),
        new TestData(printable, softwareEvent, false),
        new TestData(printable, hardwareEvent, true),
    };
    for (TestData testData : testDataList) {
      viewManager.setNarrowMode(false);
      viewManager.maybeTransitToNarrowMode(testData.command, testData.keyEventInterface);
      assertEquals(testData.expectation, viewManager.isNarrowMode());
    }
  }

  @SmallTest
  public void testHandleEmojiKey() {
    Context context = getInstrumentation().getTargetContext();
    ViewManager viewManager = createViewManager(context);
    MozcView mozcView = createViewMockBuilder(MozcView.class)
        .addMockedMethods("showSymbolInputView", "setLayoutAdjustmentAndNarrowMode")
        .createNiceMock();
    viewManager.mozcView = mozcView;

    // Disable input device check.
    // Otherwise, this feature doesn't work except for keyboards which has Emoji key(s).
    viewManager.viewLayerKeyEventHandler.disableDeviceCheck = true;

    KeyEvent aDown = new KeyEvent(0L, 0L, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A, 0);
    KeyEvent aUp = new KeyEvent(0L, 0L, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_A, 0);
    KeyEvent aDownWithAlt = new KeyEvent(
        0L, 0L, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A, 0, KeyEvent.META_ALT_ON);
    KeyEvent aUpWithAlt = new KeyEvent(
        0L, 0L, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_A, 0, KeyEvent.META_ALT_ON);
    KeyEvent altDown = new KeyEvent(
        0L, 0L, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ALT_LEFT, 0, KeyEvent.META_ALT_ON);
    KeyEvent altUp = new KeyEvent(0L, 0L, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ALT_LEFT, 0);
    KeyEvent shiftDown = new KeyEvent(
        0L, 0L, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_SHIFT_LEFT, 0, KeyEvent.META_SHIFT_ON);
    KeyEvent shiftUp = new KeyEvent(0L, 0L, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_SHIFT_LEFT, 0);
    KeyEvent altDownWithShift = new KeyEvent(
        0L, 0L, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ALT_LEFT, 0, KeyEvent.META_SHIFT_ON);
    KeyEvent altUpWithShift = new KeyEvent(
        0L, 0L, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ALT_LEFT, 0, KeyEvent.META_SHIFT_ON);
    KeyEvent shiftDownWithAlt = new KeyEvent(
        0L, 0L, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_SHIFT_LEFT, 0, KeyEvent.META_ALT_ON);
    KeyEvent shiftUpWithAlt = new KeyEvent(
        0L, 0L, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_SHIFT_LEFT, 0, KeyEvent.META_ALT_ON);
    KeyEvent altDownWithAlt = new KeyEvent(
        0L, 0L, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ALT_LEFT, 0, KeyEvent.META_ALT_ON);
    KeyEvent altUpWithAlt = new KeyEvent(
        0L, 0L, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ALT_LEFT, 0, KeyEvent.META_ALT_ON);


    class TestData extends Parameter {
      final KeyEvent[] keyEvents;
      final boolean expectLaunchEmojiPalette;
      TestData(KeyEvent[] keyEvents, boolean expectLaunchEmojiPalette) {
        this.keyEvents = Preconditions.checkNotNull(keyEvents);
        this.expectLaunchEmojiPalette = expectLaunchEmojiPalette;
      }
    }
    TestData[] testDataArray = new TestData[] {
        new TestData(new KeyEvent[] {altDown, altUp}, true),
        new TestData(new KeyEvent[] {shiftDown, shiftUp}, false),
        new TestData(new KeyEvent[] {aDown, aUp}, false),

        new TestData(new KeyEvent[] {altDown, aDownWithAlt, aUpWithAlt, altUp}, false),
        new TestData(new KeyEvent[] {aDown, altDown, altUp, aUp}, false),
        new TestData(new KeyEvent[] {altDown, aDownWithAlt, altUp, aUpWithAlt}, false),
        new TestData(new KeyEvent[] {aDown, altDown, aUpWithAlt, altUp}, false),

        new TestData(new KeyEvent[] {altDown, shiftDownWithAlt, shiftUpWithAlt, altUp}, false),
        new TestData(new KeyEvent[] {shiftDown, altDownWithShift, altUpWithShift, shiftUp}, false),
        new TestData(new KeyEvent[] {altDown, shiftDownWithAlt, altUpWithShift, shiftUp}, false),
        new TestData(new KeyEvent[] {shiftDown, altDownWithShift, shiftUpWithAlt, altUp}, false),

        new TestData(new KeyEvent[] {altDown, altDownWithAlt, altUpWithAlt, altUp}, false),
    };

    for (TestData testData : testDataArray) {
      // Key events except for last one should NOT be consumed by view layer.
      for (int i = 0; i < testData.keyEvents.length - 1; ++i) {
        assertFalse(viewManager.isKeyConsumedOnViewAsynchronously(testData.keyEvents[i]));
      }

      KeyEvent lastKeyEvent = testData.keyEvents[testData.keyEvents.length - 1];
      if (testData.expectLaunchEmojiPalette) {
        assertTrue(viewManager.isKeyConsumedOnViewAsynchronously(lastKeyEvent));
        resetAll();
        expect(mozcView.showSymbolInputView(Optional.of(SymbolMajorCategory.EMOJI)))
            .andReturn(true);
        replayAll();
        viewManager.consumeKeyOnViewSynchronously(lastKeyEvent);
        verifyAll();
      } else {
        assertFalse(viewManager.isKeyConsumedOnViewAsynchronously(lastKeyEvent));
        resetAll();
        replayAll();
        viewManager.consumeKeyOnViewSynchronously(lastKeyEvent);
        verifyAll();
      }
    }
  }

  @SmallTest
  public void testOnKeyDownByHardwareKeyboard() {
    Context context = getInstrumentation().getTargetContext();
    HardwareKeyboard hardwareKeyboard = createNiceMock(HardwareKeyboard.class);
    ViewEventListener listener = createMock(ViewEventListener.class);
    ViewManager viewManager = new ViewManager(
        context, listener, createNiceMock(SymbolHistoryStorage.class),
        createNiceMock(ImeSwitcher.class), createNiceMock(MenuDialogListener.class),
        new ProbableKeyEventGuesser(context.getAssets()), hardwareKeyboard);

    MozcView mozcView = createViewMockBuilder(MozcView.class)
        .addMockedMethods("setKeyboard")
        .createNiceMock();
    viewManager.mozcView = mozcView;

    KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A);
    ProtoCommands.KeyEvent mozcKeyEvent =
        ProtoCommands.KeyEvent.newBuilder().setKeyCode('a').build();
    KeyEventInterface keyEventInterface = KeycodeConverter.getKeyEventInterface(event);
    KeyboardSpecification keyboardSpecification = KeyboardSpecification.HARDWARE_QWERTY_KANA;

    resetAll();

    expect(hardwareKeyboard.getCompositionMode()).andStubReturn(CompositionMode.HIRAGANA);
    expect(hardwareKeyboard.setCompositionModeByKey(event)).andReturn(false);
    expect(hardwareKeyboard.getMozcKeyEvent(event)).andReturn(mozcKeyEvent);
    expect(hardwareKeyboard.getKeyEventInterface(event)).andReturn(keyEventInterface);
    expect(hardwareKeyboard.getKeyboardSpecification()).andReturn(keyboardSpecification);
    listener.onKeyEvent(
        same(mozcKeyEvent), same(keyEventInterface), same(keyboardSpecification),
        eq(Collections.<TouchEvent>emptyList()));

    replayAll();
    viewManager.onHardwareKeyEvent(event);
    verifyAll();

    resetAll();

    keyboardSpecification = KeyboardSpecification.HARDWARE_QWERTY_ALPHABET;
    expect(hardwareKeyboard.getCompositionMode()).andReturn(CompositionMode.HIRAGANA);
    expect(hardwareKeyboard.setCompositionModeByKey(event)).andReturn(false);
    expect(hardwareKeyboard.getCompositionMode()).andReturn(CompositionMode.HALF_ASCII);
    expect(hardwareKeyboard.getMozcKeyEvent(event)).andReturn(mozcKeyEvent);
    expect(hardwareKeyboard.getKeyEventInterface(event)).andReturn(keyEventInterface);
    expect(hardwareKeyboard.getKeyboardSpecification()).andReturn(keyboardSpecification);
    Capture<Keyboard> keyboardCapture = new Capture<Keyboard>();
    mozcView.setKeyboard(capture(keyboardCapture));
    listener.onKeyEvent(
        same(mozcKeyEvent), same(keyEventInterface), same(keyboardSpecification),
        eq(Collections.<TouchEvent>emptyList()));

    replayAll();
    viewManager.onHardwareKeyEvent(event);
    verifyAll();
    assertEquals(KeyboardSpecification.TWELVE_KEY_TOGGLE_ALPHABET,
                 keyboardCapture.getValue().getSpecification());
  }

  @SmallTest
  public void testSwitchHardwareKeyboardCompositionMode() {
    Context context = getInstrumentation().getTargetContext();
    ViewEventListener listener = createMock(ViewEventListener.class);
    ViewManager viewManager = createViewManagerWithEventListener(context, listener);

    // Set KANA as a initial composition mode without MozcView.
    viewManager.switchHardwareKeyboardCompositionMode(CompositionSwitchMode.KANA);

    MozcView mozcView = createViewMockBuilder(MozcView.class)
        .addMockedMethods("setKeyboard")
        .createNiceMock();
    viewManager.mozcView = mozcView;

    Capture<Keyboard> keyboardCapture = new Capture<Keyboard>();

    // HIRAGANA to HIRAGANA by CompositionSwitchMode.KANA.
    resetAll();
    replayAll();
    viewManager.switchHardwareKeyboardCompositionMode(CompositionSwitchMode.KANA);
    verifyAll();

    // HIRAGANA to HALF_ASCII by CompositionSwitchMode.HALF_ASCII.
    resetAll();
    mozcView.setKeyboard(capture(keyboardCapture));
    listener.onKeyEvent(EasyMock.<ProtoCommands.KeyEvent>isNull(),
                        EasyMock.<KeyEventInterface>isNull(),
                        same(KeyboardSpecification.HARDWARE_QWERTY_ALPHABET),
                        eq(Collections.<TouchEvent>emptyList()));
    replayAll();
    viewManager.switchHardwareKeyboardCompositionMode(CompositionSwitchMode.ALPHABET);
    verifyAll();
    assertEquals(KeyboardSpecification.TWELVE_KEY_TOGGLE_ALPHABET,
        keyboardCapture.getValue().getSpecification());

    // HALF_ASCII to HIRAGANA by CompositionSwitchMode.TOGGLE.
    resetAll();
    mozcView.setKeyboard(capture(keyboardCapture));
    listener.onKeyEvent(EasyMock.<ProtoCommands.KeyEvent>isNull(),
                        EasyMock.<KeyEventInterface>isNull(),
                        same(KeyboardSpecification.HARDWARE_QWERTY_KANA),
                        eq(Collections.<TouchEvent>emptyList()));
    replayAll();
    viewManager.switchHardwareKeyboardCompositionMode(CompositionSwitchMode.TOGGLE);
    verifyAll();
    assertEquals(KeyboardSpecification.TWELVE_KEY_TOGGLE_KANA,
                 keyboardCapture.getValue().getSpecification());
  }
}
