Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1a0750dc authored by Kurt Partridge's avatar Kurt Partridge
Browse files

Move splash screen to separate file

Change-Id: I5cad5d5814303d7ca4abadd3fca1c37bd1bc357e
parent 9380b56d
Loading
Loading
Loading
Loading
+16 −64
Original line number Diff line number Diff line
@@ -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;
+111 −0
Original line number Diff line number Diff line
/*
 * 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();
    }
}