Postponing memory deallocation after onFinishInputView

Bug: 17559789
Change-Id: I1d4b1524028164d27ec4eadd3960b567148f2b84
main
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 boolean DEBUG = false;
private static final int EXTENDED_TOUCHABLE_REGION_HEIGHT = 100; 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 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, * 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_UPDATE_TAIL_BATCH_INPUT_COMPLETED = 6;
private static final int MSG_RESET_CACHES = 7; private static final int MSG_RESET_CACHES = 7;
private static final int MSG_WAIT_FOR_DICTIONARY_LOAD = 8; private static final int MSG_WAIT_FOR_DICTIONARY_LOAD = 8;
private static final int MSG_DEALLOCATE_MEMORY = 9;
// Update this when adding new messages // 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_NOT_GESTURE_INPUT = 0;
private static final int ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT = 1; 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: case MSG_WAIT_FOR_DICTIONARY_LOAD:
Log.i(TAG, "Timeout waiting for dictionary load"); Log.i(TAG, "Timeout waiting for dictionary load");
break; break;
case MSG_DEALLOCATE_MEMORY:
latinIme.deallocateMemory();
break;
} }
} }
@ -317,7 +319,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public void postWaitForDictionaryLoad() { public void postWaitForDictionaryLoad() {
sendMessageDelayed(obtainMessage(MSG_WAIT_FOR_DICTIONARY_LOAD), sendMessageDelayed(obtainMessage(MSG_WAIT_FOR_DICTIONARY_LOAD),
DELAY_WAIT_FOR_DICTIONARY_LOAD); DELAY_WAIT_FOR_DICTIONARY_LOAD_MILLIS);
} }
public void cancelWaitForDictionaryLoad() { public void cancelWaitForDictionaryLoad() {
@ -346,6 +348,19 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mDelayInMillisecondsToUpdateShiftState); 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 @UsedForTesting
public void removeAllMessages() { public void removeAllMessages() {
for (int i = 0; i <= MSG_LAST; ++i) { for (int i = 0; i <= MSG_LAST; ++i) {
@ -443,7 +458,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mPendingSuccessiveImsCallback = false; mPendingSuccessiveImsCallback = false;
resetPendingImsCallback(); resetPendingImsCallback();
sendMessageDelayed(obtainMessage(MSG_PENDING_IMS_CALLBACK), sendMessageDelayed(obtainMessage(MSG_PENDING_IMS_CALLBACK),
PENDING_IMS_CALLBACK_DURATION); PENDING_IMS_CALLBACK_DURATION_MILLIS);
} }
final LatinIME latinIme = getOwnerInstance(); final LatinIME latinIme = getOwnerInstance();
if (latinIme != null) { if (latinIme != null) {
@ -451,6 +466,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
latinIme.onStartInputViewInternal(editorInfo, restarting); latinIme.onStartInputViewInternal(editorInfo, restarting);
mAppliedEditorInfo = editorInfo; mAppliedEditorInfo = editorInfo;
} }
cancelDeallocateMemory();
} }
} }
@ -464,6 +480,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
latinIme.onFinishInputViewInternal(finishingInput); latinIme.onFinishInputViewInternal(finishingInput);
mAppliedEditorInfo = null; mAppliedEditorInfo = null;
} }
if (!hasPendingDeallocateMemory()) {
postDeallocateMemory();
}
} }
} }
@ -1026,13 +1045,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} }
private void cleanupInternalStateForFinishInput() { private void cleanupInternalStateForFinishInput() {
mKeyboardSwitcher.deallocateMemory();
// Remove pending messages related to update suggestions // Remove pending messages related to update suggestions
mHandler.cancelUpdateSuggestionStrip(); mHandler.cancelUpdateSuggestionStrip();
// Should do the following in onFinishInputInternal but until JB MR2 it's not called :( // Should do the following in onFinishInputInternal but until JB MR2 it's not called :(
mInputLogic.finishInput(); mInputLogic.finishInput();
} }
protected void deallocateMemory() {
mKeyboardSwitcher.deallocateMemory();
}
@Override @Override
public void onUpdateSelection(final int oldSelStart, final int oldSelEnd, public void onUpdateSelection(final int oldSelStart, final int oldSelEnd,
final int newSelStart, final int newSelEnd, final int newSelStart, final int newSelEnd,

View File

@ -21,4 +21,16 @@ public class LatinIMEForTests extends LatinIME {
public boolean isInputViewShown() { public boolean isInputViewShown() {
return true; 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());
}
}