diff options
Diffstat (limited to 'java/src')
9 files changed, 90 insertions, 71 deletions
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 252fb02c8..e7c64c695 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -1451,7 +1451,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction } else { didAutoCorrect = false; if (SPACE_STATE_PHANTOM == spaceState) { - if (ProductionFlag.IS_INTERNAL) { + if (mSettings.isInternal()) { if (mWordComposer.isComposingWord() && mWordComposer.isBatchMode()) { Stats.onAutoCorrection( "", mWordComposer.getTypedWord(), " ", mWordComposer); @@ -1506,7 +1506,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction mHandler.cancelUpdateSuggestionStrip(); mConnection.beginBatchEdit(); if (mWordComposer.isComposingWord()) { - if (ProductionFlag.IS_INTERNAL) { + if (mSettings.isInternal()) { if (mWordComposer.isBatchMode()) { Stats.onAutoCorrection("", mWordComposer.getTypedWord(), " ", mWordComposer); } @@ -1736,7 +1736,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction } } else { if (mLastComposedWord.canRevertCommit()) { - if (ProductionFlag.IS_INTERNAL) { + if (mSettings.isInternal()) { Stats.onAutoCorrectionCancellation(); } revertCommit(); @@ -1895,7 +1895,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction if (null != mSuggestionStripView) mSuggestionStripView.dismissAddToDictionaryHint(); } mHandler.postUpdateSuggestionStrip(); - if (ProductionFlag.IS_INTERNAL) { + if (mSettings.isInternal()) { Utils.Stats.onNonSeparator((char)primaryCode, x, y); } } @@ -1962,7 +1962,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction // already displayed or not, so it's okay. setPunctuationSuggestions(); } - if (ProductionFlag.IS_INTERNAL) { + if (mSettings.isInternal()) { Utils.Stats.onSeparator((char)primaryCode, x, y); } @@ -2145,7 +2145,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction throw new RuntimeException("We have an auto-correction but the typed word " + "is empty? Impossible! I must commit suicide."); } - if (ProductionFlag.IS_INTERNAL) { + if (mSettings.isInternal()) { Stats.onAutoCorrection(typedWord, autoCorrection, separatorString, mWordComposer); } if (ProductionFlag.IS_EXPERIMENTAL) { @@ -2244,7 +2244,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction // If the suggestion is not in the dictionary, the hint should be shown. && !AutoCorrection.isValidWord(mSuggest.getUnigramDictionaries(), suggestion, true); - if (ProductionFlag.IS_INTERNAL) { + if (mSettings.isInternal()) { Stats.onSeparator((char)Constants.CODE_SPACE, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE); } @@ -2368,7 +2368,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction mUserHistoryDictionary.cancelAddingUserHistory(previousWord, committedWord); } mConnection.commitText(originallyTypedWord + mLastComposedWord.mSeparatorString, 1); - if (ProductionFlag.IS_INTERNAL) { + if (mSettings.isInternal()) { Stats.onSeparator(mLastComposedWord.mSeparatorString, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE); } @@ -2502,12 +2502,6 @@ public final class LatinIME extends InputMethodService implements KeyboardAction launchSubActivity(SettingsActivity.class); } - // Called from debug code only - public void launchDebugSettings() { - handleClose(); - launchSubActivity(DebugSettingsActivity.class); - } - public void launchKeyboardedDialogActivity(final Class<? extends Activity> activityClass) { // Put the text in the attached EditText into a safe, saved state before switching to a // new activity that will also use the soft keyboard. diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java index 435074bdb..4cbfa8ea1 100644 --- a/java/src/com/android/inputmethod/latin/Settings.java +++ b/java/src/com/android/inputmethod/latin/Settings.java @@ -70,6 +70,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static final String PREF_INPUT_LANGUAGE = "input_language"; public static final String PREF_SELECTED_LANGUAGES = "selected_languages"; public static final String PREF_DEBUG_SETTINGS = "debug_settings"; + public static final String PREF_KEY_IS_INTERNAL = "pref_key_is_internal"; // This preference key is deprecated. Use {@link #PREF_SHOW_LANGUAGE_SWITCH_KEY} instead. // This is being used only for the backward compatibility. @@ -127,6 +128,10 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang return mSettingsValues; } + public boolean isInternal() { + return mSettingsValues.mIsInternal; + } + // Accessed from the settings interface, hence public public static boolean readKeypressSoundEnabled(final SharedPreferences prefs, final Resources res) { @@ -274,4 +279,8 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang } return prefs.getBoolean(Settings.PREF_SHOW_SETUP_WIZARD_ICON, false); } + + public static boolean isInternal(final SharedPreferences prefs) { + return prefs.getBoolean(Settings.PREF_KEY_IS_INTERNAL, false); + } } diff --git a/java/src/com/android/inputmethod/latin/SettingsFragment.java b/java/src/com/android/inputmethod/latin/SettingsFragment.java index 4c90e485a..cc9f168d0 100644 --- a/java/src/com/android/inputmethod/latin/SettingsFragment.java +++ b/java/src/com/android/inputmethod/latin/SettingsFragment.java @@ -92,7 +92,7 @@ public final class SettingsFragment extends InputMethodSettingsFragment final Preference debugSettings = findPreference(Settings.PREF_DEBUG_SETTINGS); if (debugSettings != null) { - if (ProductionFlag.IS_INTERNAL) { + if (Settings.isInternal(prefs)) { final Intent debugSettingsIntent = new Intent(Intent.ACTION_MAIN); debugSettingsIntent.setClassName( context.getPackageName(), DebugSettingsActivity.class.getName()); @@ -156,10 +156,6 @@ public final class SettingsFragment extends InputMethodSettingsFragment removePreference(Settings.PREF_GESTURE_SETTINGS, getPreferenceScreen()); } - final CheckBoxPreference showSetupWizardIcon = - (CheckBoxPreference)findPreference(Settings.PREF_SHOW_SETUP_WIZARD_ICON); - showSetupWizardIcon.setChecked(Settings.readShowSetupWizardIcon(prefs, context)); - setupKeyLongpressTimeoutSettings(prefs, res); setupKeypressVibrationDurationSettings(prefs, res); setupKeypressSoundVolumeSettings(prefs, res); @@ -175,6 +171,10 @@ public final class SettingsFragment extends InputMethodSettingsFragment } else { getPreferenceScreen().removePreference(mVoicePreference); } + final SharedPreferences prefs = getPreferenceManager().getSharedPreferences(); + final CheckBoxPreference showSetupWizardIcon = + (CheckBoxPreference)findPreference(Settings.PREF_SHOW_SETUP_WIZARD_ICON); + showSetupWizardIcon.setChecked(Settings.readShowSetupWizardIcon(prefs, getActivity())); updateShowCorrectionSuggestionsSummary(); updateKeyPreviewPopupDelaySummary(); updateCustomInputStylesSummary(); diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java index d05868029..f77a92885 100644 --- a/java/src/com/android/inputmethod/latin/SettingsValues.java +++ b/java/src/com/android/inputmethod/latin/SettingsValues.java @@ -76,6 +76,9 @@ public final class SettingsValues { private final boolean mVoiceKeyEnabled; private final boolean mVoiceKeyOnMain; + // Debug settings + public final boolean mIsInternal; + public SettingsValues(final SharedPreferences prefs, final Resources res, final InputAttributes inputAttributes) { // Get the resources @@ -141,6 +144,7 @@ public final class SettingsValues { Settings.PREF_SHOW_SUGGESTIONS_SETTING, res.getString(R.string.prefs_suggestion_visibility_default_value)); mSuggestionVisibility = createSuggestionVisibility(res, showSuggestionsSetting); + mIsInternal = Settings.isInternal(prefs); } public boolean isApplicationSpecifiedCompletionsOn() { diff --git a/java/src/com/android/inputmethod/latin/StaticInnerHandlerWrapper.java b/java/src/com/android/inputmethod/latin/StaticInnerHandlerWrapper.java index 89d9ea844..e50af4d2d 100644 --- a/java/src/com/android/inputmethod/latin/StaticInnerHandlerWrapper.java +++ b/java/src/com/android/inputmethod/latin/StaticInnerHandlerWrapper.java @@ -22,17 +22,17 @@ import android.os.Looper; import java.lang.ref.WeakReference; public class StaticInnerHandlerWrapper<T> extends Handler { - final private WeakReference<T> mOuterInstanceRef; + private final WeakReference<T> mOuterInstanceRef; - public StaticInnerHandlerWrapper(T outerInstance) { - super(); - if (outerInstance == null) throw new NullPointerException("outerInstance is null"); - mOuterInstanceRef = new WeakReference<T>(outerInstance); + public StaticInnerHandlerWrapper(final T outerInstance) { + this(outerInstance, Looper.myLooper()); } - public StaticInnerHandlerWrapper(T outerInstance, Looper looper) { + public StaticInnerHandlerWrapper(final T outerInstance, final Looper looper) { super(looper); - if (outerInstance == null) throw new NullPointerException("outerInstance is null"); + if (outerInstance == null) { + throw new NullPointerException("outerInstance is null"); + } mOuterInstanceRef = new WeakReference<T>(outerInstance); } diff --git a/java/src/com/android/inputmethod/latin/define/ProductionFlag.java b/java/src/com/android/inputmethod/latin/define/ProductionFlag.java index fe9be16c6..3df0d044e 100644 --- a/java/src/com/android/inputmethod/latin/define/ProductionFlag.java +++ b/java/src/com/android/inputmethod/latin/define/ProductionFlag.java @@ -22,7 +22,6 @@ public final class ProductionFlag { } public static final boolean IS_EXPERIMENTAL = false; - public static final boolean IS_INTERNAL = false; // When false, IS_EXPERIMENTAL_DEBUG suggests that all guarded class-private DEBUG flags should // be false, and any privacy controls should be enforced. IS_EXPERIMENTAL_DEBUG should be false diff --git a/java/src/com/android/inputmethod/latin/setup/SetupActivity.java b/java/src/com/android/inputmethod/latin/setup/SetupActivity.java index e009fbc39..7f66c6d3e 100644 --- a/java/src/com/android/inputmethod/latin/setup/SetupActivity.java +++ b/java/src/com/android/inputmethod/latin/setup/SetupActivity.java @@ -62,6 +62,9 @@ public final class SetupActivity extends Activity { @Override public void handleMessage(final Message msg) { final SetupActivity setupActivity = getOuterInstance(); + if (setupActivity == null) { + return; + } switch (msg.what) { case MSG_POLLING_IME_SETTINGS: if (SetupActivity.isThisImeEnabled(setupActivity)) { diff --git a/java/src/com/android/inputmethod/research/ResearchLog.java b/java/src/com/android/inputmethod/research/ResearchLog.java index 9016e23b3..f7c5fd50e 100644 --- a/java/src/com/android/inputmethod/research/ResearchLog.java +++ b/java/src/com/android/inputmethod/research/ResearchLog.java @@ -20,11 +20,11 @@ import android.content.Context; import android.util.JsonWriter; import android.util.Log; +import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.define.ProductionFlag; import java.io.BufferedWriter; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; @@ -54,7 +54,6 @@ public class ResearchLog { private static final String TAG = ResearchLog.class.getSimpleName(); private static final boolean DEBUG = false && ProductionFlag.IS_EXPERIMENTAL_DEBUG; private static final long FLUSH_DELAY_IN_MS = 1000 * 5; - private static final int ABORT_TIMEOUT_IN_MS = 1000 * 4; /* package */ final ScheduledExecutorService mExecutor; /* package */ final File mFile; @@ -99,8 +98,10 @@ public class ResearchLog { * output. * * See class comment for details about {@code JsonWriter} construction. + * + * @param onClosed run after the close() operation has completed asynchronously */ - public synchronized void close(final Runnable onClosed) { + private synchronized void close(final Runnable onClosed) { mExecutor.submit(new Callable<Object>() { @Override public Object call() throws Exception { @@ -131,15 +132,24 @@ public class ResearchLog { mExecutor.shutdown(); } - private boolean mIsAbortSuccessful; + /** + * Block until the research log has shut down and spooled out all output or {@code timeout} + * occurs. + * + * @param timeout time to wait for close in milliseconds + */ + public void blockingClose(final long timeout) { + close(null); + awaitTermination(timeout, TimeUnit.MILLISECONDS); + } /** - * Waits for publication requests to finish, closes the {@link JsonWriter}, but then deletes the - * backing file used for output. + * Waits for publication requests to finish, closes the JsonWriter, but then deletes the backing + * output file. * - * See class comment for details about {@code JsonWriter} construction. + * @param onAbort run after the abort() operation has completed asynchronously */ - public synchronized void abort() { + private synchronized void abort(final Runnable onAbort) { mExecutor.submit(new Callable<Object>() { @Override public Object call() throws Exception { @@ -151,7 +161,10 @@ public class ResearchLog { } } finally { if (mFile != null) { - mIsAbortSuccessful = mFile.delete(); + mFile.delete(); + } + if (onAbort != null) { + onAbort.run(); } } return null; @@ -161,14 +174,25 @@ public class ResearchLog { mExecutor.shutdown(); } - public boolean blockingAbort() throws InterruptedException { - abort(); - mExecutor.awaitTermination(ABORT_TIMEOUT_IN_MS, TimeUnit.MILLISECONDS); - return mIsAbortSuccessful; + /** + * Block until the research log has aborted or {@code timeout} occurs. + * + * @param timeout time to wait for close in milliseconds + */ + public void blockingAbort(final long timeout) { + abort(null); + awaitTermination(timeout, TimeUnit.MILLISECONDS); } - public void awaitTermination(int delay, TimeUnit timeUnit) throws InterruptedException { - mExecutor.awaitTermination(delay, timeUnit); + @UsedForTesting + public void awaitTermination(final long delay, final TimeUnit timeUnit) { + try { + if (!mExecutor.awaitTermination(delay, timeUnit)) { + Log.e(TAG, "ResearchLog executor timed out while awaiting terminaion"); + } + } catch (final InterruptedException e) { + Log.e(TAG, "ResearchLog executor interrupted while awaiting terminaion", e); + } } /* package */ synchronized void flush() { @@ -214,10 +238,10 @@ public class ResearchLog { return null; } }); - } catch (RejectedExecutionException e) { + } catch (final RejectedExecutionException e) { // TODO: Add code to record loss of data, and report. if (DEBUG) { - Log.d(TAG, "ResearchLog.publish() rejecting scheduled execution"); + Log.d(TAG, "ResearchLog.publish() rejecting scheduled execution", e); } } } diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java index e705ddda1..11d1a5222 100644 --- a/java/src/com/android/inputmethod/research/ResearchLogger.java +++ b/java/src/com/android/inputmethod/research/ResearchLogger.java @@ -154,6 +154,9 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang private static final int MAX_INPUTVIEW_LENGTH_TO_CAPTURE = 8192; // must be >=1 private static final String PREF_RESEARCH_SAVED_CHANNEL = "pref_research_saved_channel"; + private static final long RESEARCHLOG_CLOSE_TIMEOUT_IN_MS = 5 * 1000; + private static final long RESEARCHLOG_ABORT_TIMEOUT_IN_MS = 5 * 1000; + private static final ResearchLogger sInstance = new ResearchLogger(); private static String sAccountType = null; private static String sAllowedAccountDomain = null; @@ -502,42 +505,29 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang commitCurrentLogUnit(); mMainLogBuffer.setIsStopping(); mMainLogBuffer.shiftAndPublishAll(); - mMainResearchLog.close(null /* callback */); + mMainResearchLog.blockingClose(RESEARCHLOG_CLOSE_TIMEOUT_IN_MS); mMainLogBuffer = null; } if (mFeedbackLogBuffer != null) { - mFeedbackLog.close(null /* callback */); + mFeedbackLog.blockingClose(RESEARCHLOG_CLOSE_TIMEOUT_IN_MS); mFeedbackLogBuffer = null; } } - public boolean abort() { + public void abort() { if (DEBUG) { Log.d(TAG, "abort called"); } - boolean didAbortMainLog = false; if (mMainLogBuffer != null) { mMainLogBuffer.clear(); - try { - didAbortMainLog = mMainResearchLog.blockingAbort(); - } catch (InterruptedException e) { - // Don't know whether this succeeded or not. We assume not; this is reported - // to the caller. - } + mMainResearchLog.blockingAbort(RESEARCHLOG_ABORT_TIMEOUT_IN_MS); mMainLogBuffer = null; } - boolean didAbortFeedbackLog = false; if (mFeedbackLogBuffer != null) { mFeedbackLogBuffer.clear(); - try { - didAbortFeedbackLog = mFeedbackLog.blockingAbort(); - } catch (InterruptedException e) { - // Don't know whether this succeeded or not. We assume not; this is reported - // to the caller. - } + mFeedbackLog.blockingAbort(RESEARCHLOG_ABORT_TIMEOUT_IN_MS); mFeedbackLogBuffer = null; } - return didAbortMainLog && didAbortFeedbackLog; } private void restart() { @@ -620,7 +610,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang private void startRecordingInternal() { if (mUserRecordingLog != null) { - mUserRecordingLog.abort(); + mUserRecordingLog.blockingAbort(RESEARCHLOG_ABORT_TIMEOUT_IN_MS); } mUserRecordingFile = createUserRecordingFile(mFilesDir); mUserRecordingLog = new ResearchLog(mUserRecordingFile, mLatinIME); @@ -658,7 +648,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang private void cancelRecording() { if (mUserRecordingLog != null) { - mUserRecordingLog.abort(); + mUserRecordingLog.blockingAbort(RESEARCHLOG_ABORT_TIMEOUT_IN_MS); } mUserRecordingLog = null; mUserRecordingLogBuffer = null; @@ -670,7 +660,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang private void saveRecording() { commitCurrentLogUnit(); publishLogBuffer(mUserRecordingLogBuffer, mUserRecordingLog, true); - mUserRecordingLog.close(null); + mUserRecordingLog.blockingClose(RESEARCHLOG_CLOSE_TIMEOUT_IN_MS); mUserRecordingLog = null; mUserRecordingLogBuffer = null; @@ -782,12 +772,8 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang feedbackContents, accountName, recording); mFeedbackLogBuffer.shiftIn(feedbackLogUnit); publishLogBuffer(mFeedbackLogBuffer, mSavedFeedbackLog, true /* isIncludingPrivateData */); - mSavedFeedbackLog.close(new Runnable() { - @Override - public void run() { - uploadNow(); - } - }); + mSavedFeedbackLog.blockingClose(RESEARCHLOG_CLOSE_TIMEOUT_IN_MS); + uploadNow(); if (isIncludingRecording && DEBUG_REPLAY_AFTER_FEEDBACK) { final Handler handler = new Handler(); |