diff --git a/java/AndroidManifest.xml b/java/AndroidManifest.xml
index e39ca18ee..fb973f336 100644
--- a/java/AndroidManifest.xml
+++ b/java/AndroidManifest.xml
@@ -57,14 +57,22 @@
+ android:launchMode="singleTask"
+ android:noHistory="true">
+
+
+
+
+
+
diff --git a/java/src/com/android/inputmethod/latin/setup/SetupActivity.java b/java/src/com/android/inputmethod/latin/setup/SetupActivity.java
index 97cf7fc6c..8a2de887d 100644
--- a/java/src/com/android/inputmethod/latin/setup/SetupActivity.java
+++ b/java/src/com/android/inputmethod/latin/setup/SetupActivity.java
@@ -17,255 +17,27 @@
package com.android.inputmethod.latin.setup;
import android.app.Activity;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
-import android.content.res.Resources;
-import android.media.MediaPlayer;
-import android.net.Uri;
import android.os.Bundle;
-import android.os.Message;
import android.provider.Settings;
-import android.util.Log;
-import android.view.View;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
-import android.widget.ImageView;
-import android.widget.TextView;
-import android.widget.VideoView;
-import com.android.inputmethod.compat.TextViewCompatUtils;
-import com.android.inputmethod.compat.ViewCompatUtils;
-import com.android.inputmethod.latin.CollectionUtils;
-import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.RichInputMethodManager;
-import com.android.inputmethod.latin.SettingsActivity;
-import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
-
-import java.util.ArrayList;
-
-// TODO: Use Fragment to implement welcome screen and setup steps.
-public final class SetupActivity extends Activity implements View.OnClickListener {
- private static final String TAG = SetupActivity.class.getSimpleName();
-
- private View mWelcomeScreen;
- private View mSetupScreen;
- private Uri mWelcomeVideoUri;
- private VideoView mWelcomeVideoView;
- private View mActionStart;
- private View mActionNext;
- private TextView mStep1Bullet;
- private TextView mActionFinish;
- private SetupStepGroup mSetupStepGroup;
- private static final String STATE_STEP = "step";
- private int mStepNumber;
- private static final int STEP_WELCOME = 0;
- private static final int STEP_1 = 1;
- private static final int STEP_2 = 2;
- private static final int STEP_3 = 3;
- private static final int STEP_LAUNCHING_IME_SETTINGS = 4;
- private static final int STEP_BACK_FROM_IME_SETTINGS = 5;
-
- private final SettingsPoolingHandler mHandler = new SettingsPoolingHandler(this);
-
- static final class SettingsPoolingHandler extends StaticInnerHandlerWrapper {
- private static final int MSG_POLLING_IME_SETTINGS = 0;
- private static final long IME_SETTINGS_POLLING_INTERVAL = 200;
-
- public SettingsPoolingHandler(final SetupActivity outerInstance) {
- super(outerInstance);
- }
-
- @Override
- public void handleMessage(final Message msg) {
- final SetupActivity setupActivity = getOuterInstance();
- if (setupActivity == null) {
- return;
- }
- switch (msg.what) {
- case MSG_POLLING_IME_SETTINGS:
- if (isThisImeEnabled(setupActivity)) {
- setupActivity.invokeSetupWizardOfThisIme();
- return;
- }
- startPollingImeSettings();
- break;
- }
- }
-
- public void startPollingImeSettings() {
- sendMessageDelayed(obtainMessage(MSG_POLLING_IME_SETTINGS),
- IME_SETTINGS_POLLING_INTERVAL);
- }
-
- public void cancelPollingImeSettings() {
- removeMessages(MSG_POLLING_IME_SETTINGS);
- }
- }
+public final class SetupActivity extends Activity {
@Override
protected void onCreate(final Bundle savedInstanceState) {
- setTheme(android.R.style.Theme_DeviceDefault_Light_NoActionBar);
super.onCreate(savedInstanceState);
-
- setContentView(R.layout.setup_wizard);
-
- RichInputMethodManager.init(this);
-
- if (savedInstanceState == null) {
- mStepNumber = determineSetupStepNumberFromLauncher();
- } else {
- mStepNumber = savedInstanceState.getInt(STATE_STEP);
- }
-
- final String applicationName = getResources().getString(getApplicationInfo().labelRes);
- mWelcomeScreen = findViewById(R.id.setup_welcome_screen);
- final TextView welcomeTitle = (TextView)findViewById(R.id.setup_welcome_title);
- welcomeTitle.setText(getString(R.string.setup_welcome_title, applicationName));
-
- mSetupScreen = findViewById(R.id.setup_steps_screen);
- final TextView stepsTitle = (TextView)findViewById(R.id.setup_title);
- stepsTitle.setText(getString(R.string.setup_steps_title, applicationName));
-
- final SetupStepIndicatorView indicatorView =
- (SetupStepIndicatorView)findViewById(R.id.setup_step_indicator);
- mSetupStepGroup = new SetupStepGroup(indicatorView);
-
- mStep1Bullet = (TextView)findViewById(R.id.setup_step1_bullet);
- mStep1Bullet.setOnClickListener(this);
- final SetupStep step1 = new SetupStep(STEP_1, applicationName,
- mStep1Bullet, findViewById(R.id.setup_step1),
- R.string.setup_step1_title, R.string.setup_step1_instruction,
- R.string.setup_step1_finished_instruction, R.drawable.ic_setup_step1,
- R.string.setup_step1_action);
- step1.setAction(new Runnable() {
- @Override
- public void run() {
- invokeLanguageAndInputSettings();
- mHandler.startPollingImeSettings();
- }
- });
- mSetupStepGroup.addStep(step1);
-
- final SetupStep step2 = new SetupStep(STEP_2, applicationName,
- (TextView)findViewById(R.id.setup_step2_bullet), findViewById(R.id.setup_step2),
- R.string.setup_step2_title, R.string.setup_step2_instruction,
- 0 /* finishedInstruction */, R.drawable.ic_setup_step2,
- R.string.setup_step2_action);
- step2.setAction(new Runnable() {
- @Override
- public void run() {
- // Invoke input method picker.
- RichInputMethodManager.getInstance().getInputMethodManager()
- .showInputMethodPicker();
- }
- });
- mSetupStepGroup.addStep(step2);
-
- final SetupStep step3 = new SetupStep(STEP_3, applicationName,
- (TextView)findViewById(R.id.setup_step3_bullet), findViewById(R.id.setup_step3),
- R.string.setup_step3_title, R.string.setup_step3_instruction,
- 0 /* finishedInstruction */, R.drawable.ic_setup_step3,
- R.string.setup_step3_action);
- step3.setAction(new Runnable() {
- @Override
- public void run() {
- invokeSubtypeEnablerOfThisIme();
- }
- });
- mSetupStepGroup.addStep(step3);
-
- mWelcomeVideoUri = new Uri.Builder()
- .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
- .authority(getPackageName())
- .path(Integer.toString(R.raw.setup_welcome_video))
- .build();
- mWelcomeVideoView = (VideoView)findViewById(R.id.setup_welcome_video);
- mWelcomeVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
- @Override
- public void onPrepared(final MediaPlayer mp) {
- // Now VideoView has been laid-out and ready to play, remove background of it to
- // reveal the video.
- mWelcomeVideoView.setBackgroundResource(0);
- mp.setLooping(true);
- }
- });
- final ImageView welcomeImageView = (ImageView)findViewById(R.id.setup_welcome_image);
- mWelcomeVideoView.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);
- mWelcomeVideoView.setVisibility(View.GONE);
- welcomeImageView.setImageResource(R.raw.setup_welcome_image);
- welcomeImageView.setVisibility(View.VISIBLE);
- return true;
- }
- });
-
- mActionStart = findViewById(R.id.setup_start_label);
- mActionStart.setOnClickListener(this);
- mActionNext = findViewById(R.id.setup_next);
- mActionNext.setOnClickListener(this);
- mActionFinish = (TextView)findViewById(R.id.setup_finish);
- TextViewCompatUtils.setCompoundDrawablesRelativeWithIntrinsicBounds(mActionFinish,
- getResources().getDrawable(R.drawable.ic_setup_finish), null, null, null);
- mActionFinish.setOnClickListener(this);
- }
-
- @Override
- public void onClick(final View v) {
- if (v == mActionFinish) {
+ final Intent intent = new Intent();
+ intent.setClass(this, SetupWizardActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
+ | Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(intent);
+ if (!isFinishing()) {
finish();
- return;
}
- final int currentStep = determineSetupStepNumber();
- final int nextStep;
- if (v == mActionStart) {
- nextStep = STEP_1;
- } else if (v == mActionNext) {
- nextStep = mStepNumber + 1;
- } else if (v == mStep1Bullet && currentStep == STEP_2) {
- nextStep = STEP_1;
- } else {
- nextStep = mStepNumber;
- }
- if (mStepNumber != nextStep) {
- mStepNumber = nextStep;
- updateSetupStepView();
- }
- }
-
- private void invokeSetupWizardOfThisIme() {
- final Intent intent = new Intent();
- intent.setClass(this, SetupActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
- | Intent.FLAG_ACTIVITY_CLEAR_TOP);
- startActivity(intent);
- }
-
- private void invokeSettingsOfThisIme() {
- final Intent intent = new Intent();
- intent.setClass(this, SettingsActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
- | Intent.FLAG_ACTIVITY_CLEAR_TOP);
- startActivity(intent);
- }
-
- private void invokeLanguageAndInputSettings() {
- final Intent intent = new Intent();
- intent.setAction(Settings.ACTION_INPUT_METHOD_SETTINGS);
- intent.addCategory(Intent.CATEGORY_DEFAULT);
- startActivity(intent);
- }
-
- private void invokeSubtypeEnablerOfThisIme() {
- final InputMethodInfo imi =
- RichInputMethodManager.getInstance().getInputMethodInfoOfThisIme();
- final Intent intent = new Intent();
- intent.setAction(Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS);
- intent.addCategory(Intent.CATEGORY_DEFAULT);
- intent.putExtra(Settings.EXTRA_INPUT_METHOD_ID, imi.getId());
- startActivity(intent);
}
/**
@@ -302,194 +74,4 @@ public final class SetupActivity extends Activity implements View.OnClickListene
context.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
return myImi.getId().equals(currentImeId);
}
-
- private int determineSetupStepNumberFromLauncher() {
- final int stepNumber = determineSetupStepNumber();
- if (stepNumber == STEP_1) {
- return STEP_WELCOME;
- }
- if (stepNumber == STEP_3) {
- return STEP_LAUNCHING_IME_SETTINGS;
- }
- return stepNumber;
- }
-
- private int determineSetupStepNumber() {
- mHandler.cancelPollingImeSettings();
- if (!isThisImeEnabled(this)) {
- return STEP_1;
- }
- if (!isThisImeCurrent(this)) {
- return STEP_2;
- }
- return STEP_3;
- }
-
- @Override
- protected void onSaveInstanceState(final Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putInt(STATE_STEP, mStepNumber);
- }
-
- @Override
- protected void onRestoreInstanceState(final Bundle savedInstanceState) {
- super.onRestoreInstanceState(savedInstanceState);
- mStepNumber = savedInstanceState.getInt(STATE_STEP);
- }
-
- private static boolean isInSetupSteps(final int stepNumber) {
- return stepNumber >= STEP_1 && stepNumber <= STEP_3;
- }
-
- @Override
- protected void onRestart() {
- super.onRestart();
- if (isInSetupSteps(mStepNumber)) {
- mStepNumber = determineSetupStepNumber();
- }
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- if (mStepNumber == STEP_LAUNCHING_IME_SETTINGS) {
- invokeSettingsOfThisIme();
- mStepNumber = STEP_BACK_FROM_IME_SETTINGS;
- return;
- }
- if (mStepNumber == STEP_BACK_FROM_IME_SETTINGS) {
- finish();
- return;
- }
- updateSetupStepView();
- }
-
- @Override
- public void onBackPressed() {
- if (mStepNumber == STEP_1) {
- mStepNumber = STEP_WELCOME;
- updateSetupStepView();
- return;
- }
- super.onBackPressed();
- }
-
- private static void hideAndStopVideo(final VideoView videoView) {
- videoView.stopPlayback();
- videoView.setVisibility(View.INVISIBLE);
- }
-
- @Override
- protected void onPause() {
- hideAndStopVideo(mWelcomeVideoView);
- super.onPause();
- }
-
- @Override
- public void onWindowFocusChanged(final boolean hasFocus) {
- super.onWindowFocusChanged(hasFocus);
- if (hasFocus && isInSetupSteps(mStepNumber)) {
- mStepNumber = determineSetupStepNumber();
- updateSetupStepView();
- }
- }
-
- private void updateSetupStepView() {
- final boolean welcomeScreen = (mStepNumber == STEP_WELCOME);
- 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();
- return;
- }
- hideAndStopVideo(mWelcomeVideoView);
- final boolean isStepActionAlreadyDone = mStepNumber < determineSetupStepNumber();
- mSetupStepGroup.enableStep(mStepNumber, isStepActionAlreadyDone);
- mActionNext.setVisibility(isStepActionAlreadyDone ? View.VISIBLE : View.GONE);
- mActionFinish.setVisibility((mStepNumber == STEP_3) ? View.VISIBLE : View.GONE);
- }
-
- static final class SetupStep implements View.OnClickListener {
- public final int mStepNo;
- private final View mStepView;
- private final TextView mBulletView;
- private final int mActivatedColor;
- private final int mDeactivatedColor;
- private final String mInstruction;
- private final String mFinishedInstruction;
- private final TextView mActionLabel;
- private Runnable mAction;
-
- public SetupStep(final int stepNo, final String applicationName, final TextView bulletView,
- final View stepView, final int title, final int instruction,
- final int finishedInstruction, final int actionIcon, final int actionLabel) {
- mStepNo = stepNo;
- mStepView = stepView;
- mBulletView = bulletView;
- final Resources res = stepView.getResources();
- mActivatedColor = res.getColor(R.color.setup_text_action);
- mDeactivatedColor = res.getColor(R.color.setup_text_dark);
-
- final TextView titleView = (TextView)mStepView.findViewById(R.id.setup_step_title);
- titleView.setText(res.getString(title, applicationName));
- mInstruction = (instruction == 0) ? null
- : res.getString(instruction, applicationName);
- mFinishedInstruction = (finishedInstruction == 0) ? null
- : res.getString(finishedInstruction, applicationName);
-
- mActionLabel = (TextView)mStepView.findViewById(R.id.setup_step_action_label);
- mActionLabel.setText(res.getString(actionLabel));
- if (actionIcon == 0) {
- final int paddingEnd = ViewCompatUtils.getPaddingEnd(mActionLabel);
- ViewCompatUtils.setPaddingRelative(mActionLabel, paddingEnd, 0, paddingEnd, 0);
- } else {
- TextViewCompatUtils.setCompoundDrawablesRelativeWithIntrinsicBounds(
- mActionLabel, res.getDrawable(actionIcon), null, null, null);
- }
- }
-
- public void setEnabled(final boolean enabled, final boolean isStepActionAlreadyDone) {
- mStepView.setVisibility(enabled ? View.VISIBLE : View.GONE);
- mBulletView.setTextColor(enabled ? mActivatedColor : mDeactivatedColor);
- final TextView instructionView = (TextView)mStepView.findViewById(
- R.id.setup_step_instruction);
- instructionView.setText(isStepActionAlreadyDone ? mFinishedInstruction : mInstruction);
- mActionLabel.setVisibility(isStepActionAlreadyDone ? View.GONE : View.VISIBLE);
- }
-
- public void setAction(final Runnable action) {
- mActionLabel.setOnClickListener(this);
- mAction = action;
- }
-
- @Override
- public void onClick(final View v) {
- if (v == mActionLabel && mAction != null) {
- mAction.run();
- return;
- }
- }
- }
-
- static final class SetupStepGroup {
- private final SetupStepIndicatorView mIndicatorView;
- private final ArrayList mGroup = CollectionUtils.newArrayList();
-
- public SetupStepGroup(final SetupStepIndicatorView indicatorView) {
- mIndicatorView = indicatorView;
- }
-
- public void addStep(final SetupStep step) {
- mGroup.add(step);
- }
-
- public void enableStep(final int enableStepNo, final boolean isStepActionAlreadyDone) {
- for (final SetupStep step : mGroup) {
- step.setEnabled(step.mStepNo == enableStepNo, isStepActionAlreadyDone);
- }
- mIndicatorView.setIndicatorPosition(enableStepNo - STEP_1, mGroup.size());
- }
- }
}
diff --git a/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java b/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java
new file mode 100644
index 000000000..8f6a2e566
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java
@@ -0,0 +1,460 @@
+/*
+ * 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.setup;
+
+import android.app.Activity;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Message;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.View;
+import android.view.inputmethod.InputMethodInfo;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.VideoView;
+
+import com.android.inputmethod.compat.TextViewCompatUtils;
+import com.android.inputmethod.compat.ViewCompatUtils;
+import com.android.inputmethod.latin.CollectionUtils;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.RichInputMethodManager;
+import com.android.inputmethod.latin.SettingsActivity;
+import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
+
+import java.util.ArrayList;
+
+// TODO: Use Fragment to implement welcome screen and setup steps.
+public final class SetupWizardActivity extends Activity implements View.OnClickListener {
+ static final String TAG = SetupWizardActivity.class.getSimpleName();
+
+ private View mWelcomeScreen;
+ private View mSetupScreen;
+ private Uri mWelcomeVideoUri;
+ private VideoView mWelcomeVideoView;
+ private View mActionStart;
+ private View mActionNext;
+ private TextView mStep1Bullet;
+ private TextView mActionFinish;
+ private SetupStepGroup mSetupStepGroup;
+ private static final String STATE_STEP = "step";
+ private int mStepNumber;
+ private static final int STEP_WELCOME = 0;
+ private static final int STEP_1 = 1;
+ private static final int STEP_2 = 2;
+ private static final int STEP_3 = 3;
+ private static final int STEP_LAUNCHING_IME_SETTINGS = 4;
+ private static final int STEP_BACK_FROM_IME_SETTINGS = 5;
+
+ private final SettingsPoolingHandler mHandler = new SettingsPoolingHandler(this);
+
+ static final class SettingsPoolingHandler
+ extends StaticInnerHandlerWrapper {
+ private static final int MSG_POLLING_IME_SETTINGS = 0;
+ private static final long IME_SETTINGS_POLLING_INTERVAL = 200;
+
+ public SettingsPoolingHandler(final SetupWizardActivity outerInstance) {
+ super(outerInstance);
+ }
+
+ @Override
+ public void handleMessage(final Message msg) {
+ final SetupWizardActivity setupWizardActivity = getOuterInstance();
+ if (setupWizardActivity == null) {
+ return;
+ }
+ switch (msg.what) {
+ case MSG_POLLING_IME_SETTINGS:
+ if (SetupActivity.isThisImeEnabled(setupWizardActivity)) {
+ setupWizardActivity.invokeSetupWizardOfThisIme();
+ return;
+ }
+ startPollingImeSettings();
+ break;
+ }
+ }
+
+ public void startPollingImeSettings() {
+ sendMessageDelayed(obtainMessage(MSG_POLLING_IME_SETTINGS),
+ IME_SETTINGS_POLLING_INTERVAL);
+ }
+
+ public void cancelPollingImeSettings() {
+ removeMessages(MSG_POLLING_IME_SETTINGS);
+ }
+ }
+
+ @Override
+ protected void onCreate(final Bundle savedInstanceState) {
+ setTheme(android.R.style.Theme_DeviceDefault_Light_NoActionBar);
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.setup_wizard);
+
+ RichInputMethodManager.init(this);
+
+ if (savedInstanceState == null) {
+ mStepNumber = determineSetupStepNumberFromLauncher();
+ } else {
+ mStepNumber = savedInstanceState.getInt(STATE_STEP);
+ }
+
+ final String applicationName = getResources().getString(getApplicationInfo().labelRes);
+ mWelcomeScreen = findViewById(R.id.setup_welcome_screen);
+ final TextView welcomeTitle = (TextView)findViewById(R.id.setup_welcome_title);
+ welcomeTitle.setText(getString(R.string.setup_welcome_title, applicationName));
+
+ mSetupScreen = findViewById(R.id.setup_steps_screen);
+ final TextView stepsTitle = (TextView)findViewById(R.id.setup_title);
+ stepsTitle.setText(getString(R.string.setup_steps_title, applicationName));
+
+ final SetupStepIndicatorView indicatorView =
+ (SetupStepIndicatorView)findViewById(R.id.setup_step_indicator);
+ mSetupStepGroup = new SetupStepGroup(indicatorView);
+
+ mStep1Bullet = (TextView)findViewById(R.id.setup_step1_bullet);
+ mStep1Bullet.setOnClickListener(this);
+ final SetupStep step1 = new SetupStep(STEP_1, applicationName,
+ mStep1Bullet, findViewById(R.id.setup_step1),
+ R.string.setup_step1_title, R.string.setup_step1_instruction,
+ R.string.setup_step1_finished_instruction, R.drawable.ic_setup_step1,
+ R.string.setup_step1_action);
+ step1.setAction(new Runnable() {
+ @Override
+ public void run() {
+ invokeLanguageAndInputSettings();
+ mHandler.startPollingImeSettings();
+ }
+ });
+ mSetupStepGroup.addStep(step1);
+
+ final SetupStep step2 = new SetupStep(STEP_2, applicationName,
+ (TextView)findViewById(R.id.setup_step2_bullet), findViewById(R.id.setup_step2),
+ R.string.setup_step2_title, R.string.setup_step2_instruction,
+ 0 /* finishedInstruction */, R.drawable.ic_setup_step2,
+ R.string.setup_step2_action);
+ step2.setAction(new Runnable() {
+ @Override
+ public void run() {
+ // Invoke input method picker.
+ RichInputMethodManager.getInstance().getInputMethodManager()
+ .showInputMethodPicker();
+ }
+ });
+ mSetupStepGroup.addStep(step2);
+
+ final SetupStep step3 = new SetupStep(STEP_3, applicationName,
+ (TextView)findViewById(R.id.setup_step3_bullet), findViewById(R.id.setup_step3),
+ R.string.setup_step3_title, R.string.setup_step3_instruction,
+ 0 /* finishedInstruction */, R.drawable.ic_setup_step3,
+ R.string.setup_step3_action);
+ step3.setAction(new Runnable() {
+ @Override
+ public void run() {
+ invokeSubtypeEnablerOfThisIme();
+ }
+ });
+ mSetupStepGroup.addStep(step3);
+
+ mWelcomeVideoUri = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
+ .authority(getPackageName())
+ .path(Integer.toString(R.raw.setup_welcome_video))
+ .build();
+ mWelcomeVideoView = (VideoView)findViewById(R.id.setup_welcome_video);
+ mWelcomeVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
+ @Override
+ public void onPrepared(final MediaPlayer mp) {
+ // Now VideoView has been laid-out and ready to play, remove background of it to
+ // reveal the video.
+ mWelcomeVideoView.setBackgroundResource(0);
+ mp.setLooping(true);
+ }
+ });
+ final ImageView welcomeImageView = (ImageView)findViewById(R.id.setup_welcome_image);
+ mWelcomeVideoView.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);
+ mWelcomeVideoView.setVisibility(View.GONE);
+ welcomeImageView.setImageResource(R.raw.setup_welcome_image);
+ welcomeImageView.setVisibility(View.VISIBLE);
+ return true;
+ }
+ });
+
+ mActionStart = findViewById(R.id.setup_start_label);
+ mActionStart.setOnClickListener(this);
+ mActionNext = findViewById(R.id.setup_next);
+ mActionNext.setOnClickListener(this);
+ mActionFinish = (TextView)findViewById(R.id.setup_finish);
+ TextViewCompatUtils.setCompoundDrawablesRelativeWithIntrinsicBounds(mActionFinish,
+ getResources().getDrawable(R.drawable.ic_setup_finish), null, null, null);
+ mActionFinish.setOnClickListener(this);
+ }
+
+ @Override
+ public void onClick(final View v) {
+ if (v == mActionFinish) {
+ finish();
+ return;
+ }
+ final int currentStep = determineSetupStepNumber();
+ final int nextStep;
+ if (v == mActionStart) {
+ nextStep = STEP_1;
+ } else if (v == mActionNext) {
+ nextStep = mStepNumber + 1;
+ } else if (v == mStep1Bullet && currentStep == STEP_2) {
+ nextStep = STEP_1;
+ } else {
+ nextStep = mStepNumber;
+ }
+ if (mStepNumber != nextStep) {
+ mStepNumber = nextStep;
+ updateSetupStepView();
+ }
+ }
+
+ private void invokeSetupWizardOfThisIme() {
+ final Intent intent = new Intent();
+ intent.setClass(this, SetupWizardActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
+ | Intent.FLAG_ACTIVITY_SINGLE_TOP
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ startActivity(intent);
+ }
+
+ private void invokeSettingsOfThisIme() {
+ final Intent intent = new Intent();
+ intent.setClass(this, SettingsActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ startActivity(intent);
+ }
+
+ private void invokeLanguageAndInputSettings() {
+ final Intent intent = new Intent();
+ intent.setAction(Settings.ACTION_INPUT_METHOD_SETTINGS);
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ startActivity(intent);
+ }
+
+ private void invokeSubtypeEnablerOfThisIme() {
+ final InputMethodInfo imi =
+ RichInputMethodManager.getInstance().getInputMethodInfoOfThisIme();
+ final Intent intent = new Intent();
+ intent.setAction(Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS);
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ intent.putExtra(Settings.EXTRA_INPUT_METHOD_ID, imi.getId());
+ startActivity(intent);
+ }
+
+ private int determineSetupStepNumberFromLauncher() {
+ final int stepNumber = determineSetupStepNumber();
+ if (stepNumber == STEP_1) {
+ return STEP_WELCOME;
+ }
+ if (stepNumber == STEP_3) {
+ return STEP_LAUNCHING_IME_SETTINGS;
+ }
+ return stepNumber;
+ }
+
+ private int determineSetupStepNumber() {
+ mHandler.cancelPollingImeSettings();
+ if (!SetupActivity.isThisImeEnabled(this)) {
+ return STEP_1;
+ }
+ if (!SetupActivity.isThisImeCurrent(this)) {
+ return STEP_2;
+ }
+ return STEP_3;
+ }
+
+ @Override
+ protected void onSaveInstanceState(final Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putInt(STATE_STEP, mStepNumber);
+ }
+
+ @Override
+ protected void onRestoreInstanceState(final Bundle savedInstanceState) {
+ super.onRestoreInstanceState(savedInstanceState);
+ mStepNumber = savedInstanceState.getInt(STATE_STEP);
+ }
+
+ private static boolean isInSetupSteps(final int stepNumber) {
+ return stepNumber >= STEP_1 && stepNumber <= STEP_3;
+ }
+
+ @Override
+ protected void onRestart() {
+ super.onRestart();
+ if (isInSetupSteps(mStepNumber)) {
+ mStepNumber = determineSetupStepNumber();
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ if (mStepNumber == STEP_LAUNCHING_IME_SETTINGS) {
+ invokeSettingsOfThisIme();
+ mStepNumber = STEP_BACK_FROM_IME_SETTINGS;
+ return;
+ }
+ if (mStepNumber == STEP_BACK_FROM_IME_SETTINGS) {
+ finish();
+ return;
+ }
+ updateSetupStepView();
+ }
+
+ @Override
+ public void onBackPressed() {
+ if (mStepNumber == STEP_1) {
+ mStepNumber = STEP_WELCOME;
+ updateSetupStepView();
+ return;
+ }
+ super.onBackPressed();
+ }
+
+ private static void hideAndStopVideo(final VideoView videoView) {
+ videoView.stopPlayback();
+ videoView.setVisibility(View.INVISIBLE);
+ }
+
+ @Override
+ protected void onPause() {
+ hideAndStopVideo(mWelcomeVideoView);
+ super.onPause();
+ }
+
+ @Override
+ public void onWindowFocusChanged(final boolean hasFocus) {
+ super.onWindowFocusChanged(hasFocus);
+ if (hasFocus && isInSetupSteps(mStepNumber)) {
+ mStepNumber = determineSetupStepNumber();
+ updateSetupStepView();
+ }
+ }
+
+ private void updateSetupStepView() {
+ final boolean welcomeScreen = (mStepNumber == STEP_WELCOME);
+ 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();
+ return;
+ }
+ hideAndStopVideo(mWelcomeVideoView);
+ final boolean isStepActionAlreadyDone = mStepNumber < determineSetupStepNumber();
+ mSetupStepGroup.enableStep(mStepNumber, isStepActionAlreadyDone);
+ mActionNext.setVisibility(isStepActionAlreadyDone ? View.VISIBLE : View.GONE);
+ mActionFinish.setVisibility((mStepNumber == STEP_3) ? View.VISIBLE : View.GONE);
+ }
+
+ static final class SetupStep implements View.OnClickListener {
+ public final int mStepNo;
+ private final View mStepView;
+ private final TextView mBulletView;
+ private final int mActivatedColor;
+ private final int mDeactivatedColor;
+ private final String mInstruction;
+ private final String mFinishedInstruction;
+ private final TextView mActionLabel;
+ private Runnable mAction;
+
+ public SetupStep(final int stepNo, final String applicationName, final TextView bulletView,
+ final View stepView, final int title, final int instruction,
+ final int finishedInstruction, final int actionIcon, final int actionLabel) {
+ mStepNo = stepNo;
+ mStepView = stepView;
+ mBulletView = bulletView;
+ final Resources res = stepView.getResources();
+ mActivatedColor = res.getColor(R.color.setup_text_action);
+ mDeactivatedColor = res.getColor(R.color.setup_text_dark);
+
+ final TextView titleView = (TextView)mStepView.findViewById(R.id.setup_step_title);
+ titleView.setText(res.getString(title, applicationName));
+ mInstruction = (instruction == 0) ? null
+ : res.getString(instruction, applicationName);
+ mFinishedInstruction = (finishedInstruction == 0) ? null
+ : res.getString(finishedInstruction, applicationName);
+
+ mActionLabel = (TextView)mStepView.findViewById(R.id.setup_step_action_label);
+ mActionLabel.setText(res.getString(actionLabel));
+ if (actionIcon == 0) {
+ final int paddingEnd = ViewCompatUtils.getPaddingEnd(mActionLabel);
+ ViewCompatUtils.setPaddingRelative(mActionLabel, paddingEnd, 0, paddingEnd, 0);
+ } else {
+ TextViewCompatUtils.setCompoundDrawablesRelativeWithIntrinsicBounds(
+ mActionLabel, res.getDrawable(actionIcon), null, null, null);
+ }
+ }
+
+ public void setEnabled(final boolean enabled, final boolean isStepActionAlreadyDone) {
+ mStepView.setVisibility(enabled ? View.VISIBLE : View.GONE);
+ mBulletView.setTextColor(enabled ? mActivatedColor : mDeactivatedColor);
+ final TextView instructionView = (TextView)mStepView.findViewById(
+ R.id.setup_step_instruction);
+ instructionView.setText(isStepActionAlreadyDone ? mFinishedInstruction : mInstruction);
+ mActionLabel.setVisibility(isStepActionAlreadyDone ? View.GONE : View.VISIBLE);
+ }
+
+ public void setAction(final Runnable action) {
+ mActionLabel.setOnClickListener(this);
+ mAction = action;
+ }
+
+ @Override
+ public void onClick(final View v) {
+ if (v == mActionLabel && mAction != null) {
+ mAction.run();
+ return;
+ }
+ }
+ }
+
+ static final class SetupStepGroup {
+ private final SetupStepIndicatorView mIndicatorView;
+ private final ArrayList mGroup = CollectionUtils.newArrayList();
+
+ public SetupStepGroup(final SetupStepIndicatorView indicatorView) {
+ mIndicatorView = indicatorView;
+ }
+
+ public void addStep(final SetupStep step) {
+ mGroup.add(step);
+ }
+
+ public void enableStep(final int enableStepNo, final boolean isStepActionAlreadyDone) {
+ for (final SetupStep step : mGroup) {
+ step.setEnabled(step.mStepNo == enableStepNo, isStepActionAlreadyDone);
+ }
+ mIndicatorView.setIndicatorPosition(enableStepNo - STEP_1, mGroup.size());
+ }
+ }
+}