From 1a0750dc95bcb7fa77d03207722562928d957775 Mon Sep 17 00:00:00 2001 From: Kurt Partridge Date: Wed, 19 Jun 2013 14:38:27 -0700 Subject: [PATCH] Move splash screen to separate file Change-Id: I5cad5d5814303d7ca4abadd3fca1c37bd1bc357e --- .../inputmethod/research/ResearchLogger.java | 76 +++--------- .../inputmethod/research/ui/SplashScreen.java | 111 ++++++++++++++++++ 2 files changed, 125 insertions(+), 62 deletions(-) create mode 100644 java/src/com/android/inputmethod/research/ui/SplashScreen.java diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java index 6029ba963..46d2314a8 100644 --- a/java/src/com/android/inputmethod/research/ResearchLogger.java +++ b/java/src/com/android/inputmethod/research/ResearchLogger.java @@ -20,11 +20,7 @@ import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.KEYBOAR import android.accounts.Account; import android.accounts.AccountManager; -import android.app.AlertDialog; -import android.app.Dialog; import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnCancelListener; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageInfo; @@ -34,7 +30,6 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Style; -import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Handler; @@ -46,8 +41,6 @@ import android.text.format.DateUtils; import android.util.Log; import android.view.KeyEvent; import android.view.MotionEvent; -import android.view.Window; -import android.view.WindowManager; import android.view.inputmethod.CompletionInfo; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; @@ -70,6 +63,7 @@ import com.android.inputmethod.latin.Suggest; import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.define.ProductionFlag; import com.android.inputmethod.research.MotionEventReader.ReplayData; +import com.android.inputmethod.research.ui.SplashScreen; import java.io.File; import java.io.FileInputStream; @@ -94,12 +88,12 @@ import java.util.regex.Pattern; * This functionality is off by default. See * {@link ProductionFlag#USES_DEVELOPMENT_ONLY_DIAGNOSTICS}. */ -public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChangeListener { +public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChangeListener, + SplashScreen.UserConsentListener { // TODO: This class has grown quite large and combines several concerns that should be // separated. The following refactorings will be applied as soon as possible after adding // support for replaying historical events, fixing some replay bugs, adding some ui constraints // on the feedback dialog, and adding the survey dialog. - // TODO: Refactor. Move splash screen code into separate class. // TODO: Refactor. Move feedback screen code into separate class. // TODO: Refactor. Move logging invocations into their own class. // TODO: Refactor. Move currentLogUnit management into separate class. @@ -184,6 +178,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang private final MotionEventReader mMotionEventReader = new MotionEventReader(); private final Replayer mReplayer = Replayer.getInstance(); private ResearchLogDirectory mResearchLogDirectory; + private SplashScreen mSplashScreen; private Intent mUploadIntent; private Intent mUploadNowIntent; @@ -301,62 +296,19 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang } } - private Dialog mSplashDialog = null; - private void maybeShowSplashScreen() { - if (ResearchSettings.readHasSeenSplash(mPrefs)) { - return; - } - if (mSplashDialog != null && mSplashDialog.isShowing()) { - return; - } - final IBinder windowToken = mMainKeyboardView != null - ? mMainKeyboardView.getWindowToken() : null; - if (windowToken == null) { - return; - } - final AlertDialog.Builder builder = new AlertDialog.Builder(mLatinIME) - .setTitle(R.string.research_splash_title) - .setMessage(R.string.research_splash_content) - .setPositiveButton(android.R.string.yes, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - onUserLoggingConsent(); - mSplashDialog.dismiss(); - } - }) - .setNegativeButton(android.R.string.no, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - final String packageName = mLatinIME.getPackageName(); - final Uri packageUri = Uri.parse("package:" + packageName); - final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, - packageUri); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - mLatinIME.startActivity(intent); - } - }) - .setCancelable(true) - .setOnCancelListener( - new OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - mLatinIME.requestHideSelf(0); - } - }); - mSplashDialog = builder.create(); - final Window w = mSplashDialog.getWindow(); - final WindowManager.LayoutParams lp = w.getAttributes(); - lp.token = windowToken; - lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; - w.setAttributes(lp); - w.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); - mSplashDialog.show(); + if (ResearchSettings.readHasSeenSplash(mPrefs)) return; + if (mSplashScreen != null && mSplashScreen.isShowing()) return; + if (mMainKeyboardView == null) return; + final IBinder windowToken = mMainKeyboardView.getWindowToken(); + if (windowToken == null) return; + + mSplashScreen = new SplashScreen(mLatinIME, this); + mSplashScreen.showSplashScreen(windowToken); } - public void onUserLoggingConsent() { + @Override + public void onSplashScreenUserClickedOk() { if (mPrefs == null) { mPrefs = PreferenceManager.getDefaultSharedPreferences(mLatinIME); if (mPrefs == null) return; diff --git a/java/src/com/android/inputmethod/research/ui/SplashScreen.java b/java/src/com/android/inputmethod/research/ui/SplashScreen.java new file mode 100644 index 000000000..78ed668d1 --- /dev/null +++ b/java/src/com/android/inputmethod/research/ui/SplashScreen.java @@ -0,0 +1,111 @@ +/* + * 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.research.ui; + +import android.app.AlertDialog.Builder; +import android.app.Dialog; +import android.content.DialogInterface; +import android.content.DialogInterface.OnCancelListener; +import android.content.Intent; +import android.inputmethodservice.InputMethodService; +import android.net.Uri; +import android.os.IBinder; +import android.view.Window; +import android.view.WindowManager.LayoutParams; + +import com.android.inputmethod.latin.R.string; + +/** + * Show a dialog when the user first opens the keyboard. + * + * The splash screen is a modal dialog box presented when the user opens this keyboard for the first + * time. It is useful for giving specific warnings that must be shown to the user before use. + * + * While the splash screen does share with the setup wizard the common goal of presenting + * information to the user before use, they are presented at different times and with different + * capabilities. The setup wizard is launched by tapping on the icon, and walks the user through + * the setup process. It can, however, be bypassed by enabling the keyboard from Settings directly. + * The splash screen cannot be bypassed, and is therefore more appropriate for obtaining user + * consent. + */ +public class SplashScreen { + public interface UserConsentListener { + public void onSplashScreenUserClickedOk(); + } + + final UserConsentListener mListener; + final Dialog mSplashDialog; + + public SplashScreen(final InputMethodService inputMethodService, + final UserConsentListener listener) { + mListener = listener; + final Builder builder = new Builder(inputMethodService) + .setTitle(string.research_splash_title) + .setMessage(string.research_splash_content) + .setPositiveButton(android.R.string.yes, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + mListener.onSplashScreenUserClickedOk(); + mSplashDialog.dismiss(); + } + }) + .setNegativeButton(android.R.string.no, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + final String packageName = inputMethodService.getPackageName(); + final Uri packageUri = Uri.parse("package:" + packageName); + final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, + packageUri); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + inputMethodService.startActivity(intent); + } + }) + .setCancelable(true) + .setOnCancelListener( + new OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + inputMethodService.requestHideSelf(0); + } + }); + mSplashDialog = builder.create(); + } + + /** + * Show the splash screen. + * + * The user must consent to the terms presented in the SplashScreen before they can use the + * keyboard. If they cancel instead, they are given the option to uninstall the keybard. + * + * @param windowToken {@link IBinder} to attach dialog to + */ + public void showSplashScreen(final IBinder windowToken) { + final Window window = mSplashDialog.getWindow(); + final LayoutParams lp = window.getAttributes(); + lp.token = windowToken; + lp.type = LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; + window.setAttributes(lp); + window.addFlags(LayoutParams.FLAG_ALT_FOCUSABLE_IM); + mSplashDialog.show(); + } + + public boolean isShowing() { + return mSplashDialog.isShowing(); + } +}