From 7b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cf Mon Sep 17 00:00:00 2001 From: Adrian Velicu Date: Mon, 29 Sep 2014 15:15:07 +0900 Subject: [PATCH] Postponing memory deallocation after onFinishInputView Bug: 17559789 Change-Id: I1d4b1524028164d27ec4eadd3960b567148f2b84 --- .../android/inputmethod/latin/LatinIME.java | 40 ++++++++++++++----- .../inputmethod/latin/LatinIMEForTests.java | 12 ++++++ .../inputmethod/latin/LatinImeTests.java | 40 +++++++++++++++++++ 3 files changed, 83 insertions(+), 9 deletions(-) create mode 100644 tests/src/com/android/inputmethod/latin/LatinImeTests.java diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 1cd285c0f..bb7a36b4f 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -119,12 +119,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private static boolean DEBUG = false; private static final int EXTENDED_TOUCHABLE_REGION_HEIGHT = 100; - - private static final int PENDING_IMS_CALLBACK_DURATION = 800; - - private static final int DELAY_WAIT_FOR_DICTIONARY_LOAD = 2000; // 2s - private static final int PERIOD_FOR_AUDIO_AND_HAPTIC_FEEDBACK_IN_KEY_REPEAT = 2; + private static final int PENDING_IMS_CALLBACK_DURATION_MILLIS = 800; + private static final long DELAY_WAIT_FOR_DICTIONARY_LOAD_MILLIS = TimeUnit.SECONDS.toMillis(2); + private static final long DELAY_DEALLOCATE_MEMORY_MILLIS = TimeUnit.SECONDS.toMillis(10); /** * The name of the scheme used by the Package Manager to warn of a new package installation, @@ -192,8 +190,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private static final int MSG_UPDATE_TAIL_BATCH_INPUT_COMPLETED = 6; private static final int MSG_RESET_CACHES = 7; private static final int MSG_WAIT_FOR_DICTIONARY_LOAD = 8; + private static final int MSG_DEALLOCATE_MEMORY = 9; // Update this when adding new messages - private static final int MSG_LAST = MSG_WAIT_FOR_DICTIONARY_LOAD; + private static final int MSG_LAST = MSG_DEALLOCATE_MEMORY; private static final int ARG1_NOT_GESTURE_INPUT = 0; private static final int ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT = 1; @@ -280,6 +279,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen case MSG_WAIT_FOR_DICTIONARY_LOAD: Log.i(TAG, "Timeout waiting for dictionary load"); break; + case MSG_DEALLOCATE_MEMORY: + latinIme.deallocateMemory(); + break; } } @@ -317,7 +319,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen public void postWaitForDictionaryLoad() { sendMessageDelayed(obtainMessage(MSG_WAIT_FOR_DICTIONARY_LOAD), - DELAY_WAIT_FOR_DICTIONARY_LOAD); + DELAY_WAIT_FOR_DICTIONARY_LOAD_MILLIS); } public void cancelWaitForDictionaryLoad() { @@ -346,6 +348,19 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mDelayInMillisecondsToUpdateShiftState); } + public void postDeallocateMemory() { + sendMessageDelayed(obtainMessage(MSG_DEALLOCATE_MEMORY), + DELAY_DEALLOCATE_MEMORY_MILLIS); + } + + public void cancelDeallocateMemory() { + removeMessages(MSG_DEALLOCATE_MEMORY); + } + + public boolean hasPendingDeallocateMemory() { + return hasMessages(MSG_DEALLOCATE_MEMORY); + } + @UsedForTesting public void removeAllMessages() { for (int i = 0; i <= MSG_LAST; ++i) { @@ -443,7 +458,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mPendingSuccessiveImsCallback = false; resetPendingImsCallback(); sendMessageDelayed(obtainMessage(MSG_PENDING_IMS_CALLBACK), - PENDING_IMS_CALLBACK_DURATION); + PENDING_IMS_CALLBACK_DURATION_MILLIS); } final LatinIME latinIme = getOwnerInstance(); if (latinIme != null) { @@ -451,6 +466,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen latinIme.onStartInputViewInternal(editorInfo, restarting); mAppliedEditorInfo = editorInfo; } + cancelDeallocateMemory(); } } @@ -464,6 +480,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen latinIme.onFinishInputViewInternal(finishingInput); mAppliedEditorInfo = null; } + if (!hasPendingDeallocateMemory()) { + postDeallocateMemory(); + } } } @@ -1026,13 +1045,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } private void cleanupInternalStateForFinishInput() { - mKeyboardSwitcher.deallocateMemory(); // Remove pending messages related to update suggestions mHandler.cancelUpdateSuggestionStrip(); // Should do the following in onFinishInputInternal but until JB MR2 it's not called :( mInputLogic.finishInput(); } + protected void deallocateMemory() { + mKeyboardSwitcher.deallocateMemory(); + } + @Override public void onUpdateSelection(final int oldSelStart, final int oldSelEnd, final int newSelStart, final int newSelEnd, diff --git a/tests/src/com/android/inputmethod/latin/LatinIMEForTests.java b/tests/src/com/android/inputmethod/latin/LatinIMEForTests.java index e47c55736..035c8d7ce 100644 --- a/tests/src/com/android/inputmethod/latin/LatinIMEForTests.java +++ b/tests/src/com/android/inputmethod/latin/LatinIMEForTests.java @@ -21,4 +21,16 @@ public class LatinIMEForTests extends LatinIME { public boolean isInputViewShown() { return true; } + + private boolean deallocateMemoryWasPerformed = false; + + @Override + protected void deallocateMemory() { + super.deallocateMemory(); + deallocateMemoryWasPerformed = true; + } + + public boolean getDeallocateMemoryWasPerformed() { + return deallocateMemoryWasPerformed; + } } diff --git a/tests/src/com/android/inputmethod/latin/LatinImeTests.java b/tests/src/com/android/inputmethod/latin/LatinImeTests.java new file mode 100644 index 000000000..c6f631328 --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/LatinImeTests.java @@ -0,0 +1,40 @@ +/* + * 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.latin; + +import android.test.suitebuilder.annotation.LargeTest; + +@LargeTest +public class LatinImeTests extends InputTestsBase { + public void testDeferredDeallocation_doesntHappenBeforeTimeout() { + mLatinIME.mHandler.onFinishInputView(true); + runMessages(); + sleep(1000); // 1s + runMessages(); + assertFalse("memory deallocation performed before timeout passed", + ((LatinIMEForTests)mLatinIME).getDeallocateMemoryWasPerformed()); + } + + public void testDeferredDeallocation_doesHappenAfterTimeout() { + mLatinIME.mHandler.onFinishInputView(true); + runMessages(); + sleep(11000); // 11s (timeout is at 10s) + runMessages(); + assertTrue("memory deallocation not performed although timeout passed", + ((LatinIMEForTests)mLatinIME).getDeallocateMemoryWasPerformed()); + } +}