add test for setLocalFosus and injectInputEvent
- create a presentation and use the presentation to test the APIs
bug: 10263354
Change-Id: I87164579bcaaba7503cdfe7121fa7b589984099b
diff --git a/tests/res/layout/windowstub_presentation.xml b/tests/res/layout/windowstub_presentation.xml
new file mode 100644
index 0000000..80490c4
--- /dev/null
+++ b/tests/res/layout/windowstub_presentation.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <Button
+ android:id="@+id/presentation_button1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:text="@string/vertical_text_1" />
+ <Button
+ android:id="@+id/presentation_button2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:text="@string/vertical_text_2" />
+ <Button
+ android:id="@+id/presentation_button3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:text="@string/vertical_text_3" />
+</LinearLayout>
diff --git a/tests/tests/view/src/android/view/cts/WindowTest.java b/tests/tests/view/src/android/view/cts/WindowTest.java
index 8f45f5c..7e147ab 100644
--- a/tests/tests/view/src/android/view/cts/WindowTest.java
+++ b/tests/tests/view/src/android/view/cts/WindowTest.java
@@ -18,37 +18,52 @@
import com.android.cts.stub.R;
-
import android.app.Instrumentation;
+import android.app.Presentation;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
+import android.cts.util.PollingCheck;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.VirtualDisplay;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.SystemClock;
import android.test.ActivityInstrumentationTestCase2;
import android.util.DisplayMetrics;
+import android.util.Log;
import android.view.ActionMode;
+import android.view.Display;
import android.view.Gravity;
+import android.view.InputDevice;
import android.view.InputQueue;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
+import android.view.Surface;
import android.view.SurfaceHolder;
+import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
+import android.widget.Button;
import android.widget.TextView;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
public class WindowTest extends ActivityInstrumentationTestCase2<WindowStubActivity> {
+ static final String TAG = "WindowTest";
private Window mWindow;
private Context mContext;
private Instrumentation mInstrumentation;
@@ -57,6 +72,10 @@
private static final int VIEWGROUP_LAYOUT_HEIGHT = 100;
private static final int VIEWGROUP_LAYOUT_WIDTH = 200;
+ // for testing setLocalFocus
+ private ProjectedPresentation mPresentation;
+ private VirtualDisplay mVirtualDisplay;
+
public WindowTest() {
super("com.android.cts.stub", WindowStubActivity.class);
}
@@ -629,6 +648,189 @@
// No way to test protected final method
}
+ /**
+ * Test setLocalFocus together with injectInputEvent.
+ */
+ public void testSetLocalFocus() throws Throwable {
+ final SurfaceView surfaceView = new SurfaceView(mContext);
+ final Semaphore waitingSemaphore = new Semaphore(0);
+ surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ }
+
+ @Override
+ public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+ destroyPresentation();
+ createPresentation(holder.getSurface(), width, height);
+ waitingSemaphore.release();
+ }
+
+ @Override
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ destroyPresentation();
+ }
+ });
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ mWindow.setContentView(surfaceView);
+ }
+ });
+ assertTrue(waitingSemaphore.tryAcquire(5, TimeUnit.SECONDS));
+ assertNotNull(mVirtualDisplay);
+ assertNotNull(mPresentation);
+ new PollingCheck() {
+ @Override
+ protected boolean check() {
+ return (mPresentation.button1 != null) && (mPresentation.button2 != null) &&
+ (mPresentation.button3 != null) && mPresentation.ready;
+ }
+ }.run();
+ assertTrue(mPresentation.button1.isFocusable() && mPresentation.button2.isFocusable() &&
+ mPresentation.button3.isFocusable());
+ // currently it is only for debugging
+ View.OnFocusChangeListener listener = new View.OnFocusChangeListener() {
+ @Override
+ public void onFocusChange(View v, boolean hasFocus) {
+ Log.d(TAG, "view " + v + " focus " + hasFocus);
+ }
+ };
+
+ // check key event focus
+ mPresentation.button1.setOnFocusChangeListener(listener);
+ mPresentation.button2.setOnFocusChangeListener(listener);
+ mPresentation.button3.setOnFocusChangeListener(listener);
+ final Window presentationWindow = mPresentation.getWindow();
+ presentationWindow.setLocalFocus(true, false);
+ new PollingCheck() {
+ @Override
+ protected boolean check() {
+ return mPresentation.button1.hasWindowFocus();
+ }
+ }.run();
+ checkPresentationButtonFocus(true, false, false);
+ assertFalse(mPresentation.button1.isInTouchMode());
+ injectKeyEvent(presentationWindow, KeyEvent.KEYCODE_TAB);
+ checkPresentationButtonFocus(false, true, false);
+ injectKeyEvent(presentationWindow, KeyEvent.KEYCODE_TAB);
+ checkPresentationButtonFocus(false, false, true);
+
+ // check touch input injection
+ presentationWindow.setLocalFocus(true, true);
+ new PollingCheck() {
+ @Override
+ protected boolean check() {
+ return mPresentation.button1.isInTouchMode();
+ }
+ }.run();
+ View.OnClickListener clickListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Log.d(TAG, "onClick " + v);
+ if (v == mPresentation.button1) {
+ waitingSemaphore.release();
+ }
+ }
+ };
+ mPresentation.button1.setOnClickListener(clickListener);
+ mPresentation.button2.setOnClickListener(clickListener);
+ mPresentation.button3.setOnClickListener(clickListener);
+ injectTouchEvent(presentationWindow, mPresentation.button1.getX() +
+ mPresentation.button1.getWidth() / 2,
+ mPresentation.button1.getY() + mPresentation.button1.getHeight() / 2);
+ assertTrue(waitingSemaphore.tryAcquire(5, TimeUnit.SECONDS));
+
+ destroyPresentation();
+ }
+
+ private void checkPresentationButtonFocus(final boolean button1Focused,
+ final boolean button2Focused, final boolean button3Focused) {
+ new PollingCheck() {
+ @Override
+ protected boolean check() {
+ return (mPresentation.button1.isFocused() == button1Focused) &&
+ (mPresentation.button2.isFocused() == button2Focused) &&
+ (mPresentation.button3.isFocused() == button3Focused);
+ }
+ }.run();
+ }
+
+ private void injectKeyEvent(Window window, int keyCode) {
+ KeyEvent downEvent = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
+ window.injectInputEvent(downEvent);
+ KeyEvent upEvent = new KeyEvent(KeyEvent.ACTION_UP, keyCode);
+ window.injectInputEvent(upEvent);
+ }
+
+ private void injectTouchEvent(Window window, float x, float y) {
+ Log.d(TAG, "injectTouchEvent " + x + "," + y);
+ long downTime = SystemClock.uptimeMillis();
+ MotionEvent downEvent = MotionEvent.obtain(downTime, downTime, MotionEvent.ACTION_DOWN,
+ x, y, 0);
+ downEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+ window.injectInputEvent(downEvent);
+ long upTime = SystemClock.uptimeMillis();
+ MotionEvent upEvent = MotionEvent.obtain(downTime, upTime, MotionEvent.ACTION_UP,
+ x, y, 0);
+ upEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+ window.injectInputEvent(upEvent);
+ }
+
+ private void createPresentation(final Surface surface, final int width,
+ final int height) {
+ Context context = getInstrumentation().getTargetContext();
+ DisplayManager displayManager =
+ (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
+ mVirtualDisplay = displayManager.createVirtualDisplay("localFocusTest",
+ width, height, 300, surface, 0);
+ mPresentation = new ProjectedPresentation(
+ context, mVirtualDisplay.getDisplay());
+ mPresentation.show();
+ }
+
+ private void destroyPresentation() {
+ if (mPresentation != null) {
+ mPresentation.dismiss();
+ }
+ if (mVirtualDisplay != null) {
+ mVirtualDisplay.release();
+ }
+ }
+
+ private class ProjectedPresentation extends Presentation {
+ public Button button1 = null;
+ public Button button2 = null;
+ public Button button3 = null;
+ public volatile boolean ready = false;
+
+ public ProjectedPresentation(Context outerContext, Display display) {
+ super(outerContext, display);
+ getWindow().setType(WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION);
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.windowstub_presentation);
+ button1 = (Button) findViewById(R.id.presentation_button1);
+ button2 = (Button) findViewById(R.id.presentation_button2);
+ button3 = (Button) findViewById(R.id.presentation_button3);
+ }
+
+ @Override
+ public void show() {
+ super.show();
+ new Handler().post(new Runnable() {
+
+ @Override
+ public void run() {
+ ready = true;
+ }
+ });
+ }
+ }
+
public class MockWindow extends Window {
public boolean mIsOnConfigurationChangedCalled = false;
public boolean mIsOnActiveCalled = false;