Merge "Fix some flaky tests."

main
Jean Chalard 2014-04-10 08:47:20 +00:00 committed by Android (Google) Code Review
commit 2e967f6607
5 changed files with 70 additions and 0 deletions

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2014 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.compat;
import android.os.Looper;
import java.lang.reflect.Method;
/**
* Helper to call Looper#quitSafely, which was introduced in API
* level 18 (Build.VERSION_CODES.JELLY_BEAN_MR2).
*
* In unit tests, we create lots of instances of LatinIME, which means we need to clean up
* some Loopers lest we leak file descriptors. In normal use on a device though, this is never
* necessary (although it does not hurt).
*/
public final class LooperCompatUtils {
private static final Method METHOD_quitSafely = CompatUtils.getMethod(
Looper.class, "quitSafely");
public static void quitSafely(final Looper looper) {
if (null != METHOD_quitSafely) {
CompatUtils.invoke(looper, null /* default return value */, METHOD_quitSafely);
} else {
looper.quit();
}
}
}

View File

@ -635,6 +635,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
super.onDestroy(); super.onDestroy();
} }
@UsedForTesting
public void recycle() {
mInputLogic.recycle();
}
@Override @Override
public void onConfigurationChanged(final Configuration conf) { public void onConfigurationChanged(final Configuration conf) {
// If orientation changed while predicting, commit the change // If orientation changed while predicting, commit the change

View File

@ -148,6 +148,17 @@ public final class InputLogic {
mInputLogicHandler.reset(); mInputLogicHandler.reset();
} }
// Normally this class just gets out of scope after the process ends, but in unit tests, we
// create several instances of LatinIME in the same process, which results in several
// instances of InputLogic. This cleans up the associated handler so that tests don't leak
// handlers.
public void recycle() {
final InputLogicHandler inputLogicHandler = mInputLogicHandler;
mInputLogicHandler = InputLogicHandler.NULL_HANDLER;
inputLogicHandler.destroy();
mSuggest.mDictionaryFacilitator.closeDictionaries();
}
/** /**
* React to a string input. * React to a string input.
* *

View File

@ -20,6 +20,7 @@ import android.os.Handler;
import android.os.HandlerThread; import android.os.HandlerThread;
import android.os.Message; import android.os.Message;
import com.android.inputmethod.compat.LooperCompatUtils;
import com.android.inputmethod.latin.InputPointers; import com.android.inputmethod.latin.InputPointers;
import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.latin.Suggest; import com.android.inputmethod.latin.Suggest;
@ -80,6 +81,12 @@ class InputLogicHandler implements Handler.Callback {
mNonUIThreadHandler.removeCallbacksAndMessages(null); mNonUIThreadHandler.removeCallbacksAndMessages(null);
} }
// In unit tests, we create several instances of LatinIME, which results in several instances
// of InputLogicHandler. To avoid these handlers lingering, we call this.
public void destroy() {
LooperCompatUtils.quitSafely(mNonUIThreadHandler.getLooper());
}
/** /**
* Handle a message. * Handle a message.
* @see android.os.Handler.Callback#handleMessage(android.os.Message) * @see android.os.Handler.Callback#handleMessage(android.os.Message)

View File

@ -213,13 +213,18 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
@Override @Override
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
mLatinIME.onFinishInputView(true);
mLatinIME.onFinishInput();
runMessages();
mLatinIME.mHandler.removeAllMessages(); mLatinIME.mHandler.removeAllMessages();
setBooleanPreference(Settings.PREF_BIGRAM_PREDICTIONS, mPreviousBigramPredictionSettings, setBooleanPreference(Settings.PREF_BIGRAM_PREDICTIONS, mPreviousBigramPredictionSettings,
true /* defaultValue */); true /* defaultValue */);
setStringPreference(Settings.PREF_AUTO_CORRECTION_THRESHOLD, mPreviousAutoCorrectSetting, setStringPreference(Settings.PREF_AUTO_CORRECTION_THRESHOLD, mPreviousAutoCorrectSetting,
DEFAULT_AUTO_CORRECTION_THRESHOLD); DEFAULT_AUTO_CORRECTION_THRESHOLD);
setDebugMode(false); setDebugMode(false);
mLatinIME.recycle();
super.tearDown(); super.tearDown();
mLatinIME = null;
} }
// We need to run the messages added to the handler from LatinIME. The only way to do // We need to run the messages added to the handler from LatinIME. The only way to do