19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.imftest.samples;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.Activity;
209abc55ec4a81cf83aebda6513c425553d8b33ae3Swarna Kumarimport android.app.KeyguardManager;
219abc55ec4a81cf83aebda6513c425553d8b33ae3Swarna Kumarimport android.content.Context;
22e9d0b2962d21eada2e51479cc8f46b900cd7a553Brett Chabotimport android.content.Intent;
231d679147d508b4c5d0a2ae1cc85bd030eb2f8761Brett Chabotimport android.content.res.Configuration;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.test.InstrumentationTestCase;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyEvent;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.WindowManager;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputMethodManager;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.imftest.R;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class ImfBaseTestCase<T extends Activity> extends InstrumentationTestCase {
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The amount of time we are willing to wait for the IME to appear after a user action
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * before we give up and fail the test.
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final long WAIT_FOR_IME = 5000;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*
42e9d0b2962d21eada2e51479cc8f46b900cd7a553Brett Chabot     * Unfortunately there is now way for us to know how tall the IME is,
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * so we have to hard code a minimum and maximum value.
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final int IME_MIN_HEIGHT = 150;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final int IME_MAX_HEIGHT = 300;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected InputMethodManager mImm;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected T mTargetActivity;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean mExpectAutoPop;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Class<T> mTargetActivityClass;
52e9d0b2962d21eada2e51479cc8f46b900cd7a553Brett Chabot
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ImfBaseTestCase(Class<T> activityClass) {
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTargetActivityClass = activityClass;
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
56e9d0b2962d21eada2e51479cc8f46b900cd7a553Brett Chabot
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setUp() throws Exception {
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.setUp();
601d679147d508b4c5d0a2ae1cc85bd030eb2f8761Brett Chabot        final String packageName = getInstrumentation().getTargetContext().getPackageName();
61e9d0b2962d21eada2e51479cc8f46b900cd7a553Brett Chabot        Intent intent = new Intent(Intent.ACTION_MAIN);
62e9d0b2962d21eada2e51479cc8f46b900cd7a553Brett Chabot        intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
63e9d0b2962d21eada2e51479cc8f46b900cd7a553Brett Chabot        mTargetActivity = launchActivityWithIntent(packageName, mTargetActivityClass, intent);
641d679147d508b4c5d0a2ae1cc85bd030eb2f8761Brett Chabot        // expect ime to auto pop up if device has no hard keyboard
65e9d0b2962d21eada2e51479cc8f46b900cd7a553Brett Chabot        int keyboardType = mTargetActivity.getResources().getConfiguration().keyboard;
66e9d0b2962d21eada2e51479cc8f46b900cd7a553Brett Chabot        mExpectAutoPop = (keyboardType  == Configuration.KEYBOARD_NOKEYS ||
67e9d0b2962d21eada2e51479cc8f46b900cd7a553Brett Chabot                keyboardType == Configuration.KEYBOARD_UNDEFINED);
68e9d0b2962d21eada2e51479cc8f46b900cd7a553Brett Chabot
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mImm = InputMethodManager.getInstance(mTargetActivity);
709abc55ec4a81cf83aebda6513c425553d8b33ae3Swarna Kumar
719abc55ec4a81cf83aebda6513c425553d8b33ae3Swarna Kumar        KeyguardManager keyguardManager =
729abc55ec4a81cf83aebda6513c425553d8b33ae3Swarna Kumar            (KeyguardManager) getInstrumentation().getContext().getSystemService(
739abc55ec4a81cf83aebda6513c425553d8b33ae3Swarna Kumar                    Context.KEYGUARD_SERVICE);
749abc55ec4a81cf83aebda6513c425553d8b33ae3Swarna Kumar        keyguardManager.newKeyguardLock("imftest").disableKeyguard();
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Utility test methods
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void verifyEditTextAdjustment(final View editText, int rootViewHeight) {
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int[] origLocation = new int[2];
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int[] newLocation = new int[2];
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Tell the keyboard to go away.
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mImm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Bring the target EditText into focus.
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTargetActivity.runOnUiThread(new Runnable() {
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public void run() {
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                editText.requestFocus();
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        });
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Get the original location of the EditText.
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        editText.getLocationOnScreen(origLocation);
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Tap the EditText to bring up the IME.
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Wait until the EditText pops above the IME or until we hit the timeout.
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        editText.getLocationOnScreen(newLocation);
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long timeoutTime = SystemClock.uptimeMillis() + WAIT_FOR_IME;
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (newLocation[1] > rootViewHeight - IME_MIN_HEIGHT && SystemClock.uptimeMillis() < timeoutTime) {
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            editText.getLocationOnScreen(newLocation);
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pause(100);
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertTrue(newLocation[1] <= rootViewHeight - IME_MIN_HEIGHT);
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Tell the keyboard to go away.
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mImm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void destructiveCheckImeInitialState(View rootView, View servedView) {
1141d679147d508b4c5d0a2ae1cc85bd030eb2f8761Brett Chabot        int windowSoftInputMode = mTargetActivity.getWindow().getAttributes().softInputMode;
1151d679147d508b4c5d0a2ae1cc85bd030eb2f8761Brett Chabot        int adjustMode = windowSoftInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
1161d679147d508b4c5d0a2ae1cc85bd030eb2f8761Brett Chabot        if (mExpectAutoPop && adjustMode == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) {
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            assertTrue(destructiveCheckImeUp(rootView, servedView));
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            assertFalse(destructiveCheckImeUp(rootView, servedView));
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
122e9d0b2962d21eada2e51479cc8f46b900cd7a553Brett Chabot
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean destructiveCheckImeUp(View rootView, View servedView) {
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int origHeight;
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int newHeight;
126e9d0b2962d21eada2e51479cc8f46b900cd7a553Brett Chabot
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        origHeight = rootView.getHeight();
128e9d0b2962d21eada2e51479cc8f46b900cd7a553Brett Chabot
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Tell the keyboard to go away.
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mImm.hideSoftInputFromWindow(servedView.getWindowToken(), 0);
131e9d0b2962d21eada2e51479cc8f46b900cd7a553Brett Chabot
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Give it five seconds to adjust
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        newHeight = rootView.getHeight();
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long timeoutTime = SystemClock.uptimeMillis() + WAIT_FOR_IME;
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (Math.abs(newHeight - origHeight) < IME_MIN_HEIGHT && SystemClock.uptimeMillis() < timeoutTime) {
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            newHeight = rootView.getHeight();
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
138e9d0b2962d21eada2e51479cc8f46b900cd7a553Brett Chabot
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return (Math.abs(origHeight - newHeight) >= IME_MIN_HEIGHT);
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
141e9d0b2962d21eada2e51479cc8f46b900cd7a553Brett Chabot
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void pause(int millis) {
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Thread.sleep(millis);
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (InterruptedException e) {
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
150