Postponing memory deallocation after onFinishInputView

Bug: 17559789
Change-Id: I1d4b1524028164d27ec4eadd3960b567148f2b84
This commit is contained in:
Adrian Velicu 2014-09-29 15:15:07 +09:00
parent 4f04fd95f4
commit 7b8f317050
3 changed files with 83 additions and 9 deletions

View File

@ -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,

View File

@ -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;
}
}

View File

@ -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());
}
}