blob: 527f444ccba0a107b0eb0b4bd26379d5154613c2 [file] [log] [blame]
/*
* Copyright (C) 2008 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 android.view.cts;
import com.android.cts.stub.R;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
import dalvik.annotation.ToBeFixed;
import android.app.Instrumentation;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
import android.test.ActivityInstrumentationTestCase2;
import android.util.DisplayMetrics;
import android.view.accessibility.AccessibilityEvent;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
@TestTargetClass(Window.class)
public class WindowTest extends ActivityInstrumentationTestCase2<WindowStubActivity> {
private Window mWindow;
private Context mContext;
private Instrumentation mInstrumentation;
private WindowStubActivity mActivity;
private static final int VIEWGROUP_LAYOUT_HEIGHT = 100;
private static final int VIEWGROUP_LAYOUT_WIDTH = 200;
public WindowTest() {
super("com.android.cts.stub", WindowStubActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
mInstrumentation = getInstrumentation();
mContext = mInstrumentation.getContext();
mActivity = getActivity();
mWindow = mActivity.getWindow();
}
@Override
protected void tearDown() throws Exception {
if (mActivity != null) {
mActivity.setFlagFalse();
}
super.tearDown();
}
@TestTargets({
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "Window",
args = {android.content.Context.class}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "getContext",
args = {}
)
})
public void testConstructor() throws Exception {
mWindow = new MockWindow(mContext);
assertSame(mContext, mWindow.getContext());
}
/**
* Test flags related methods:
* 1. addFlags: add the given flag to WindowManager.LayoutParams.flags, if add more than one
* in sequence, flags will be set to formerFlag | latterFlag.
* 2. setFlags: _1. set the flags of the window.
* _2. test invocation of Window.Callback#onWindowAttributesChanged.
* 3. clearFlags: clear the flag bits as specified in flags.
*/
@TestTargets({
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "addFlags",
args = {int.class}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "clearFlags",
args = {int.class}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "setFlags",
args = {int.class, int.class}
)
})
public void testOpFlags() throws Exception {
mWindow = new MockWindow(mContext);
final WindowManager.LayoutParams attrs = mWindow.getAttributes();
assertEquals(0, attrs.flags);
mWindow.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
assertEquals(WindowManager.LayoutParams.FLAG_FULLSCREEN, attrs.flags);
mWindow.addFlags(WindowManager.LayoutParams.FLAG_DITHER);
assertEquals(WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_DITHER, attrs.flags);
mWindow.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
assertEquals(WindowManager.LayoutParams.FLAG_DITHER, attrs.flags);
mWindow.clearFlags(WindowManager.LayoutParams.FLAG_DITHER);
assertEquals(0, attrs.flags);
MockWindowCallback callback = new MockWindowCallback();
mWindow.setCallback(callback);
assertFalse(callback.isOnWindowAttributesChangedCalled());
// mask == flag, no bit of flag need to be modified.
mWindow.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
assertEquals(WindowManager.LayoutParams.FLAG_FULLSCREEN, attrs.flags);
// Test if the callback method is called by system
assertTrue(callback.isOnWindowAttributesChangedCalled());
mWindow.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
mWindow.clearFlags(WindowManager.LayoutParams.FLAG_DITHER);
}
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "findViewById",
args = {int.class}
)
public void testFindViewById() throws Exception {
TextView v = (TextView) mWindow.findViewById(R.id.listview_window);
assertNotNull(v);
assertEquals(R.id.listview_window, v.getId());
}
/**
* getAttributes: Retrieve the current window attributes associated with this panel.
* Return is 1.the existing window attributes object.
* 2.a freshly created one if there is none.
* setAttributes: Specify custom window attributes.
* Here we just set some parameters to test if it can set, and the window is just
* available in this method. But it's not proper to setAttributes arbitrarily.
* setCallback: Set the Callback interface for this window. In Window.java,
* there is just one method, onWindowAttributesChanged, used.
* getCallback: Return the current Callback interface for this window.
*/
@TestTargets({
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "getAttributes",
args = {}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "setCallback",
args = {android.view.Window.Callback.class}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "getCallback",
args = {}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "setAttributes",
args = {android.view.WindowManager.LayoutParams.class}
)
})
public void testAccessAttributes() throws Exception {
mWindow = new MockWindow(mContext);
// default attributes
WindowManager.LayoutParams attr = mWindow.getAttributes();
assertEquals(WindowManager.LayoutParams.MATCH_PARENT, attr.width);
assertEquals(WindowManager.LayoutParams.MATCH_PARENT, attr.height);
assertEquals(WindowManager.LayoutParams.TYPE_APPLICATION, attr.type);
assertEquals(PixelFormat.OPAQUE, attr.format);
int width = 200;
int height = 300;
WindowManager.LayoutParams param = new WindowManager.LayoutParams(width, height,
WindowManager.LayoutParams.TYPE_BASE_APPLICATION,
WindowManager.LayoutParams.FLAG_DITHER, PixelFormat.RGBA_8888);
MockWindowCallback callback = new MockWindowCallback();
mWindow.setCallback(callback);
assertSame(callback, mWindow.getCallback());
assertFalse(callback.isOnWindowAttributesChangedCalled());
mWindow.setAttributes(param);
attr = mWindow.getAttributes();
assertEquals(width, attr.width);
assertEquals(height, attr.height);
assertEquals(WindowManager.LayoutParams.TYPE_BASE_APPLICATION, attr.type);
assertEquals(PixelFormat.RGBA_8888, attr.format);
assertEquals(WindowManager.LayoutParams.FLAG_DITHER, attr.flags);
assertTrue(callback.isOnWindowAttributesChangedCalled());
}
/**
* If not set container, the DecorWindow operates as a top-level window, the mHasChildren of
* container is false;
* Otherwise, it will display itself meanwhile container's mHasChildren is true.
*/
@TestTargets({
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "getContainer",
args = {}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "setContainer",
args = {android.view.Window.class}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "hasChildren",
args = {}
)
})
public void testAccessContainer() throws Exception {
mWindow = new MockWindow(mContext);
assertNull(mWindow.getContainer());
assertFalse(mWindow.hasChildren());
MockWindow container = new MockWindow(mContext);
mWindow.setContainer(container);
assertSame(container, mWindow.getContainer());
assertTrue(container.hasChildren());
}
/**
* addContentView: add an additional content view to the screen.
* 1.Added after any existing ones in the screen.
* 2.Existing views are NOT removed.
* getLayoutInflater: Quick access to the {@link LayoutInflater} instance that this Window
* retrieved from its Context.
*/
@TestTargets({
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "addContentView",
args = {android.view.View.class, android.view.ViewGroup.LayoutParams.class}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "getLayoutInflater",
args = {}
)
})
public void testAddContentView() throws Throwable {
final ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(VIEWGROUP_LAYOUT_WIDTH,
VIEWGROUP_LAYOUT_HEIGHT);
// The LayoutInflater instance will be inflated to a view and used by
// addContentView,
// id of this view should be same with inflated id.
final LayoutInflater inflater = mActivity.getLayoutInflater();
runTestOnUiThread(new Runnable() {
public void run() {
TextView addedView = (TextView) mWindow.findViewById(R.id.listview_addwindow);
assertNull(addedView);
mWindow.addContentView(inflater.inflate(R.layout.windowstub_addlayout, null), lp);
TextView view = (TextView) mWindow.findViewById(R.id.listview_window);
addedView = (TextView) mWindow.findViewById(R.id.listview_addwindow);
assertNotNull(view);
assertNotNull(addedView);
assertEquals(R.id.listview_window, view.getId());
assertEquals(R.id.listview_addwindow, addedView.getId());
}
});
mInstrumentation.waitForIdleSync();
}
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "closeAllPanels",
args = {}
)
public void testCloseAllPanels() throws Throwable {
}
@TestTargets({
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "closePanel",
args = {int.class}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "openPanel",
args = {int.class, android.view.KeyEvent.class}
)
})
public void testOpPanel() throws Throwable {
runTestOnUiThread(new Runnable() {
public void run() {
mWindow.openPanel(Window.FEATURE_OPTIONS_PANEL, null);
assertTrue(mActivity.isOnCreateOptionsMenuCalled());
mWindow.closePanel(Window.FEATURE_OPTIONS_PANEL);
assertTrue(mActivity.isOnOptionsMenuClosedCalled());
}
});
mInstrumentation.waitForIdleSync();
}
/**
* togglePanel: When the panel is closing, open it; when open, close it.
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "togglePanel",
args = {int.class, android.view.KeyEvent.class}
)
public void testTogglePanelClose() throws Throwable {
runTestOnUiThread(new Runnable() {
public void run() {
mWindow.openPanel(Window.FEATURE_OPTIONS_PANEL, null);
assertTrue(mActivity.isOnCreateOptionsMenuCalled());
// close panel
mWindow.togglePanel(Window.FEATURE_OPTIONS_PANEL, null);
assertTrue(mActivity.isOnOptionsMenuClosedCalled());
}
});
mInstrumentation.waitForIdleSync();
}
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "togglePanel",
args = {int.class, android.view.KeyEvent.class}
)
public void testTogglePanelOpen() throws Throwable {
runTestOnUiThread(new Runnable() {
public void run() {
// open panel
mWindow.togglePanel(Window.FEATURE_OPTIONS_PANEL, null);
assertTrue(mActivity.isOnCreateOptionsMenuCalled());
mWindow.closePanel(Window.FEATURE_OPTIONS_PANEL);
assertTrue(mActivity.isOnOptionsMenuClosedCalled());
}
});
mInstrumentation.waitForIdleSync();
}
/**
* getCurrentFocus: Return the view in this Window that currently has focus, or null if
* there are none.
* The test will be:
* 1. Set focus view to null, get current focus, it should be null
* 2. Set listview_window as focus view, get it and compare.
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "getCurrentFocus",
args = {}
)
public void testGetCurrentFocus() throws Throwable {
runTestOnUiThread(new Runnable() {
public void run() {
TextView v = (TextView) mWindow.findViewById(R.id.listview_window);
v.clearFocus();
assertNull(mWindow.getCurrentFocus());
v.setFocusable(true);
assertTrue(v.isFocusable());
assertTrue(v.requestFocus());
View focus = mWindow.getCurrentFocus();
assertNotNull(focus);
assertEquals(R.id.listview_window, focus.getId());
}
});
mInstrumentation.waitForIdleSync();
}
/**
* 1. getDecorView() retrieves the top-level window decor view, which contains the standard
* window frame/decorations and the client's content inside of that, we should check the
* primary components of this view which have no relationship concrete realization of Window.
* Therefore we should check if the size of this view equals to the screen size and the
* ontext is same as Window's context.
* 2. Return null if decor view is not created, else the same with detDecorView.
*/
@TestTargets({
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "getDecorView",
args = {}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "peekDecorView",
args = {}
)
})
public void testDecorView() throws Exception {
mInstrumentation.waitForIdleSync();
View decor = mWindow.getDecorView();
assertNotNull(decor);
checkDecorView(decor);
decor = mWindow.peekDecorView();
if (decor != null) {
checkDecorView(decor);
}
}
private void checkDecorView(View decor) {
DisplayMetrics dm = new DisplayMetrics();
mActivity.getWindowManager().getDefaultDisplay().getMetrics(dm);
int screenWidth = dm.widthPixels;
int screenHeight = dm.heightPixels;
assertEquals(screenWidth, decor.getWidth());
assertEquals(screenHeight, decor.getHeight());
assertSame(mWindow.getContext(), decor.getContext());
}
/**
* setVolumeControlStream: Suggests an audio stream whose volume should be changed by
* the hardware volume controls.
* getVolumeControlStream: Gets the suggested audio stream whose volume should be changed by
* the harwdare volume controls.
*/
@TestTargets({
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "getVolumeControlStream",
args = {}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "setVolumeControlStream",
args = {int.class}
)
})
public void testAccessVolumeControlStream() throws Exception {
// Default value is AudioManager.USE_DEFAULT_STREAM_TYPE, see javadoc of
// {@link Activity#setVolumeControlStream}.
assertEquals(AudioManager.USE_DEFAULT_STREAM_TYPE, mWindow.getVolumeControlStream());
mWindow.setVolumeControlStream(AudioManager.STREAM_MUSIC);
assertEquals(AudioManager.STREAM_MUSIC, mWindow.getVolumeControlStream());
}
/**
* setWindowManager: Set the window manager for use by this Window.
* getWindowManager: Return the window manager allowing this Window to display its own
* windows.
*/
@TestTargets({
@TestTargetNew(
level = TestLevel.NOT_FEASIBLE,
method = "getWindowManager",
args = {}
),
@TestTargetNew(
level = TestLevel.NOT_FEASIBLE,
method = "setWindowManager",
args = {android.view.WindowManager.class, android.os.IBinder.class,
java.lang.String.class}
)
})
public void testAccessWindowManager() throws Exception {
mWindow = new MockWindow(getActivity());
WindowManager expected = (WindowManager) getActivity().getSystemService(
Context.WINDOW_SERVICE);
assertNull(mWindow.getWindowManager());
mWindow.setWindowManager(expected, null, getName());
// No way to compare the expected and actual directly, they are
// different object
assertNotNull(mWindow.getWindowManager());
}
/**
* Return the {@link android.R.styleable#Window} attributes from this
* window's theme. It's invisible.
*/
@TestTargetNew(
level = TestLevel.NOT_FEASIBLE,
notes = "the windowStyle is obtained from com.android.internal.R.styleable.Window whose"
+ " details are invisible for user",
method = "getWindowStyle",
args = {}
)
public void testGetWindowStyle() throws Exception {
mWindow = new MockWindow(mContext);
final TypedArray windowStyle = mWindow.getWindowStyle();
// the windowStyle is obtained from
// com.android.internal.R.styleable.Window whose details
// are invisible for user.
assertNotNull(windowStyle);
}
@TestTargets({
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "isActive",
args = {}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "makeActive",
args = {}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "onActive",
args = {}
)
})
public void testIsActive() throws Exception {
MockWindow window = new MockWindow(mContext);
assertFalse(window.isActive());
window.makeActive();
assertTrue(window.isActive());
assertTrue(window.mIsOnActiveCalled);
}
/**
* isFloating: Return whether this window is being displayed with a floating style
* (based on the {@link android.R.attr#windowIsFloating} attribute in the style/theme).
*/
@TestTargetNew(
level = TestLevel.PARTIAL,
notes = "Now can only get the unfloating status",
method = "isFloating",
args = {}
)
public void testIsFloating() throws Exception {
// Default system theme defined by themes.xml, the windowIsFloating is set false.
assertFalse(mWindow.isFloating());
}
/**
* isShortcutKey: check if a key is the shortcut key for this window
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "We set 'q' & 'a' key as shortcut key in WindowStubActivity.java,"
+ " other keys are not shortcut key",
method = "isShortcutKey",
args = {int.class, android.view.KeyEvent.class}
)
public void testIsShortcutKey() throws Throwable {
runTestOnUiThread(new Runnable() {
public void run() {
mActivity.openOptionsMenu();
}
});
mInstrumentation.waitForIdleSync();
assertTrue(mWindow.isShortcutKey(KeyEvent.KEYCODE_Q, new KeyEvent(KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_Q)));
assertFalse(mWindow.isShortcutKey(KeyEvent.KEYCODE_F, new KeyEvent(KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_F)));
}
@TestTargets({
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "performContextMenuIdentifierAction",
args = {int.class, int.class}
),
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "performPanelIdentifierAction",
args = {int.class, int.class, int.class}
),
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "performPanelShortcut",
args = {int.class, int.class, android.view.KeyEvent.class, int.class}
)
})
@ToBeFixed(bug = "1695243", explanation = "miss javadoc, hard to get known about its"
+ " functionality")
public void testPerformMethods() throws Exception {
}
@TestTargets({
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "restoreHierarchyState",
args = {android.os.Bundle.class}
),
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "saveHierarchyState",
args = {}
)
})
public void testKeepHierarchyState() throws Exception {
}
/**
* Change the background of this window to a custom Drawable.
* Setting the background to null will make the window be opaque(No way to get the window
* attribute of PixelFormat to check if the window is opaque). To make the window
* transparent, you can use an empty drawable(eg. ColorDrawable with the color 0).
*/
@TestTargets({
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "setBackgroundDrawable",
args = {android.graphics.drawable.Drawable.class}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "setBackgroundDrawableResource",
args = {int.class}
)
})
public void testSetBackgroundDrawable() throws Throwable {
// DecorView holds the background
View decor = mWindow.getDecorView();
assertEquals(PixelFormat.OPAQUE, decor.getBackground().getOpacity());
runTestOnUiThread(new Runnable() {
public void run() {
// setBackgroundDrawableResource(int resId) has the same
// functionality with
// setBackgroundDrawable(Drawable drawable), just different in
// parameter.
mWindow.setBackgroundDrawableResource(R.drawable.faces);
}
});
mInstrumentation.waitForIdleSync();
runTestOnUiThread(new Runnable() {
public void run() {
ColorDrawable drawable = new ColorDrawable(0);
mWindow.setBackgroundDrawable(drawable);
}
});
mInstrumentation.waitForIdleSync();
decor = mWindow.getDecorView();
// Color 0 with one alpha bit
assertEquals(PixelFormat.TRANSPARENT, decor.getBackground().getOpacity());
runTestOnUiThread(new Runnable() {
public void run() {
mWindow.setBackgroundDrawable(null);
}
});
mInstrumentation.waitForIdleSync();
decor = mWindow.getDecorView();
assertNull(decor.getBackground());
}
@TestTargets({
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "setChildDrawable",
args = {int.class, android.graphics.drawable.Drawable.class}
),
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "setChildInt",
args = {int.class, int.class}
)
})
@ToBeFixed(bug = "1695243", explanation = "miss javadoc, hard to get known about its"
+ " functionality")
public void testSetChild() throws Exception {
}
/**
* setContentView(int): set the screen content from a layout resource.
* setContentView(View): set the screen content to an explicit view.
* setContentView(View, LayoutParams): Set the screen content to an explicit view.
*
* Note that calling this function "locks in" various characteristics
* of the window that can not, from this point forward, be changed: the
* features that have been requested with {@link #requestFeature(int)},
* and certain window flags as described in {@link #setFlags(int, int)}.
* This functionality point is hard to test:
* 1. can't get the features requested because the getter is protected final.
* 2. certain window flags are not clear to concrete one.
*/
@TestTargets({
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "setContentView",
args = {int.class}
),
@TestTargetNew(
level = TestLevel.PARTIAL,
method = "setContentView",
args = {android.view.View.class}
),
@TestTargetNew(
level = TestLevel.PARTIAL,
method = "setContentView",
args = {android.view.View.class, android.view.ViewGroup.LayoutParams.class}
)
})
public void testSetContentView() throws Throwable {
final ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(VIEWGROUP_LAYOUT_WIDTH,
VIEWGROUP_LAYOUT_HEIGHT);
final LayoutInflater inflate = mActivity.getLayoutInflater();
runTestOnUiThread(new Runnable() {
public void run() {
TextView view;
View setView;
// Test setContentView(int layoutResID)
mWindow.setContentView(R.layout.windowstub_layout);
view = (TextView) mWindow.findViewById(R.id.listview_window);
assertNotNull(view);
assertEquals(R.id.listview_window, view.getId());
// Test setContentView(View view)
setView = inflate.inflate(R.layout.windowstub_addlayout, null);
mWindow.setContentView(setView);
view = (TextView) mWindow.findViewById(R.id.listview_addwindow);
assertNotNull(view);
assertEquals(R.id.listview_addwindow, view.getId());
// Test setContentView(View view, ViewGroup.LayoutParams params)
setView = inflate.inflate(R.layout.windowstub_layout, null);
mWindow.setContentView(setView, lp);
assertEquals(VIEWGROUP_LAYOUT_WIDTH, setView.getLayoutParams().width);
assertEquals(VIEWGROUP_LAYOUT_HEIGHT, setView.getLayoutParams().height);
view = (TextView) mWindow.findViewById(R.id.listview_window);
assertNotNull(view);
assertEquals(R.id.listview_window, view.getId());
}
});
mInstrumentation.waitForIdleSync();
}
/**
* setFeatureDrawable: Set an explicit Drawable value for feature of this window.
* setFeatureDrawableAlpha: Set a custom alpha value for the given drawale feature,
* controlling how much the background is visible through it.
* setFeatureDrawableResource: Set the value for a drawable feature of this window, from
* a resource identifier.
* setFeatureDrawableUri: Set the value for a drawable feature of this window, from a URI.
* setFeatureInt: Set the integer value for a feature. The range of the value depends on
* the feature being set. For FEATURE_PROGRESSS, it should go from 0 to
* 10000. At 10000 the progress is complete and the indicator hidden
*
* the set views exist, and no getter way to check.
*/
@TestTargets({
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "setFeatureDrawable",
args = {int.class, android.graphics.drawable.Drawable.class}
),
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "setFeatureDrawableAlpha",
args = {int.class, int.class}
),
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "setFeatureDrawableResource",
args = {int.class, int.class}
),
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "setFeatureDrawableUri",
args = {int.class, android.net.Uri.class}
),
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "setFeatureInt",
args = {int.class, int.class}
)
})
public void testSetFeature() throws Throwable {
}
@TestTargets({
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "setTitle",
args = {java.lang.CharSequence.class}
),
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "setTitleColor",
args = {int.class}
)
})
public void testSetTitle() throws Throwable {
final String title = "Android Window Test";
runTestOnUiThread(new Runnable() {
public void run() {
mWindow.setTitle(title);
mWindow.setTitleColor(Color.BLUE);
}
});
mInstrumentation.waitForIdleSync();
// No way to get title and title color
}
/**
* These 3 methods: Used by custom windows, such as Dialog, to pass the key press event
* further down the view hierarchy. Application developers should not need to implement or
* call this.
*/
@TestTargets({
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "superDispatchTouchEvent",
args = {android.view.MotionEvent.class}
),
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "superDispatchTrackballEvent",
args = {android.view.MotionEvent.class}
),
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "superDispatchKeyEvent",
args = {android.view.KeyEvent.class}
)
})
@ToBeFixed(bug = "1719667", explanation = "In javadoc, it is not recommended for developer"
+ " to call these methods, they are used by custom windows.")
public void testSuperDispatchEvent() throws Exception {
}
/**
* takeKeyEvents: Request that key events come to this activity. Use this if your activity
* has no views with focus, but the activity still wants a chance to process key events.
*/
@TestTargetNew(
level = TestLevel.PARTIAL,
method = "takeKeyEvents",
args = {boolean.class}
)
@ToBeFixed(bug = "1728604", explanation = "Clear all focused view, use takeKeyEvents(false)"
+ " It's expected that the activity can't process key events, But when we send a key,"
+ " Acitivity#onKeyDown is still called by system.")
public void testTakeKeyEvents() throws Throwable {
runTestOnUiThread(new Runnable() {
public void run() {
View v = mWindow.findViewById(R.id.listview_window);
v.clearFocus();
assertNull(mWindow.getCurrentFocus());
mWindow.takeKeyEvents(false);
}
});
mInstrumentation.waitForIdleSync();
// sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
// assertFalse(mActivity.isOnKeyDownCalled());
}
/**
* onConfigurationChanged: Should be called when the configuration is changed.
*/
@TestTargetNew(
level = TestLevel.NOT_FEASIBLE,
notes = "Test onConfigurationChanged, because the Window#onConfigurationChanged is"
+ " abstract and we can't let system call our own MockWindow#onConfigurationChanged"
+ " and can't check if the system call this callback method",
method = "onConfigurationChanged",
args = {android.content.res.Configuration.class}
)
public void testOnConfigurationChanged() throws Exception {
}
/**
* requestFeature: Enable extended screen features.
*/
@TestTargetNew(
level = TestLevel.NOT_FEASIBLE,
notes = "Because getFeatures is final protected, we can't get the request Features and"
+ " no way to check the request result.",
method = "requestFeature",
args = {int.class}
)
public void testRequestFeature() throws Exception {
}
/**
* setDefaultWindowFormat: Set the format of window, as per the PixelFormat types. This
* is the format that will be used unless the client specifies in explicit format with
* setFormat().
* setFormat: Set the format of window, as per the PixelFormat types.
* param format: The new window format (see PixelFormat). Use
* PixelFormat.UNKNOWN to allow the Window to select
* the format.
*/
@TestTargets({
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "setDefaultWindowFormat",
args = {int.class}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "setFormat",
args = {int.class}
)
})
public void testSetDefaultWindowFormat() throws Exception {
MockWindowCallback callback;
MockWindow window = new MockWindow(mContext);
// mHaveWindowFormat will be true after set PixelFormat.OPAQUE and
// setDefaultWindowFormat is invalid
window.setFormat(PixelFormat.OPAQUE);
callback = new MockWindowCallback();
window.setCallback(callback);
assertFalse(callback.isOnWindowAttributesChangedCalled());
window.setDefaultWindowFormat(PixelFormat.JPEG);
assertEquals(PixelFormat.OPAQUE, window.getAttributes().format);
assertFalse(callback.isOnWindowAttributesChangedCalled());
// mHaveWindowFormat will be false after set PixelFormat.UNKNOWN and
// setDefaultWindowFormat is valid
window.setFormat(PixelFormat.UNKNOWN);
callback = new MockWindowCallback();
window.setCallback(callback);
assertFalse(callback.isOnWindowAttributesChangedCalled());
window.setDefaultWindowFormat(PixelFormat.JPEG);
assertEquals(PixelFormat.JPEG, window.getAttributes().format);
assertTrue(callback.isOnWindowAttributesChangedCalled());
}
/**
* Set the gravity of the window
*/
@TestTargetNew(
level = TestLevel.PARTIAL,
notes = "Lack of getter to obtain the gravity of window manager positioned in window",
method = "setGravity",
args = {int.class}
)
public void testSetGravity() throws Exception {
mWindow = new MockWindow(mContext);
WindowManager.LayoutParams attrs = mWindow.getAttributes();
assertEquals(0, attrs.gravity);
MockWindowCallback callback = new MockWindowCallback();
mWindow.setCallback(callback);
assertFalse(callback.isOnWindowAttributesChangedCalled());
mWindow.setGravity(Gravity.TOP);
attrs = mWindow.getAttributes();
assertEquals(Gravity.TOP, attrs.gravity);
assertTrue(callback.isOnWindowAttributesChangedCalled());
}
/**
* Set the width and height layout parameters of the window.
* 1.The default for both of these is MATCH_PARENT;
* 2.You can change them to WRAP_CONTENT to make a window that is not full-screen.
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "setLayout",
args = {int.class, int.class}
)
public void testSetLayout() throws Exception {
mWindow = new MockWindow(mContext);
WindowManager.LayoutParams attrs = mWindow.getAttributes();
assertEquals(WindowManager.LayoutParams.MATCH_PARENT, attrs.width);
assertEquals(WindowManager.LayoutParams.MATCH_PARENT, attrs.height);
MockWindowCallback callback = new MockWindowCallback();
mWindow.setCallback(callback);
assertFalse(callback.isOnWindowAttributesChangedCalled());
mWindow.setLayout(WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT);
attrs = mWindow.getAttributes();
assertEquals(WindowManager.LayoutParams.WRAP_CONTENT, attrs.width);
assertEquals(WindowManager.LayoutParams.WRAP_CONTENT, attrs.height);
assertTrue(callback.isOnWindowAttributesChangedCalled());
}
/**
* Set the type of the window, as per the WindowManager.LayoutParams types.
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "setType",
args = {int.class}
)
public void testSetType() throws Exception {
mWindow = new MockWindow(mContext);
WindowManager.LayoutParams attrs = mWindow.getAttributes();
assertEquals(WindowManager.LayoutParams.TYPE_APPLICATION, attrs.type);
MockWindowCallback callback = new MockWindowCallback();
mWindow.setCallback(callback);
assertFalse(callback.isOnWindowAttributesChangedCalled());
mWindow.setType(WindowManager.LayoutParams.TYPE_BASE_APPLICATION);
attrs = mWindow.getAttributes();
assertEquals(WindowManager.LayoutParams.TYPE_BASE_APPLICATION, mWindow.getAttributes().type);
assertTrue(callback.isOnWindowAttributesChangedCalled());
}
/**
* Specify an explicit soft input mode to use for the window, as per
* WindowManager.LayoutParams#softInputMode.
* 1.Providing "unspecified" here will NOT override the input mode the window.
* 2.Providing "unspecified" here will override the input mode the window.
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "setSoftInputMode",
args = {int.class}
)
public void testSetSoftInputMode() throws Exception {
mWindow = new MockWindow(mContext);
assertEquals(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED,
mWindow.getAttributes().softInputMode);
mWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
assertEquals(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE,
mWindow.getAttributes().softInputMode);
mWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED);
assertEquals(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE,
mWindow.getAttributes().softInputMode);
}
/**
* Specify custom animations to use for the window, as per
* WindowManager.LayoutParams#windowAnimations.
* 1.Providing 0 here will NOT override the animations the window(But here we can't check
* it because the getter is in WindowManagerService and is private)
* 2.Providing 0 here will override the animations the window.
*/
@TestTargetNew(
level = TestLevel.PARTIAL,
method = "setWindowAnimations",
args = {int.class}
)
public void testSetWindowAnimations() throws Exception {
mWindow = new MockWindow(mContext);
MockWindowCallback callback = new MockWindowCallback();
mWindow.setCallback(callback);
assertFalse(callback.isOnWindowAttributesChangedCalled());
mWindow.setWindowAnimations(R.anim.alpha);
WindowManager.LayoutParams attrs = mWindow.getAttributes();
assertEquals(R.anim.alpha, attrs.windowAnimations);
assertTrue(callback.isOnWindowAttributesChangedCalled());
}
@TestTargets({
@TestTargetNew(
level = TestLevel.NOT_FEASIBLE,
notes = "Test getFeatures, protected final method, can't call it",
method = "getFeatures",
args = {}
),
@TestTargetNew(
level = TestLevel.NOT_FEASIBLE,
notes = "Test getLocalFeatures, protected final method, can't call it",
method = "getLocalFeatures",
args = {}
),
@TestTargetNew(
level = TestLevel.NOT_FEASIBLE,
notes = "Test getForcedWindowFlags, protected final method, can't call it",
method = "getForcedWindowFlags",
args = {}
),
@TestTargetNew(
level = TestLevel.NOT_FEASIBLE,
notes = "Test hasSoftInputMode, protected final method, can't call it",
method = "hasSoftInputMode",
args = {}
)
})
public void testFinalMethod() throws Exception {
// No way to test protected final method
}
public class MockWindow extends Window {
public boolean mIsOnConfigurationChangedCalled = false;
public boolean mIsOnActiveCalled = false;
public MockWindow(Context context) {
super(context);
}
public boolean isFloating() {
return false;
}
public void setContentView(int layoutResID) {
}
public void setContentView(View view) {
}
public void setContentView(View view, ViewGroup.LayoutParams params) {
}
public void addContentView(View view, ViewGroup.LayoutParams params) {
}
public View getCurrentFocus() {
return null;
}
public LayoutInflater getLayoutInflater() {
return null;
}
public void setTitle(CharSequence title) {
}
public void setTitleColor(int textColor) {
}
public void openPanel(int featureId, KeyEvent event) {
}
public void closePanel(int featureId) {
}
public void togglePanel(int featureId, KeyEvent event) {
}
public boolean performPanelShortcut(int featureId, int keyCode, KeyEvent event, int flags) {
return true;
}
public boolean performPanelIdentifierAction(int featureId, int id, int flags) {
return true;
}
public void closeAllPanels() {
}
public boolean performContextMenuIdentifierAction(int id, int flags) {
return true;
}
public void onConfigurationChanged(Configuration newConfig) {
mIsOnConfigurationChangedCalled = true;
}
public void setBackgroundDrawable(Drawable drawable) {
}
public void setFeatureDrawableResource(int featureId, int resId) {
}
public void setFeatureDrawableUri(int featureId, Uri uri) {
}
public void setFeatureDrawable(int featureId, Drawable drawable) {
}
public void setFeatureDrawableAlpha(int featureId, int alpha) {
}
public void setFeatureInt(int featureId, int value) {
}
public void takeKeyEvents(boolean get) {
}
public boolean superDispatchKeyEvent(KeyEvent event) {
return true;
}
public boolean superDispatchTouchEvent(MotionEvent event) {
return true;
}
public boolean superDispatchTrackballEvent(MotionEvent event) {
return true;
}
public View getDecorView() {
return null;
}
public View peekDecorView() {
return null;
}
public Bundle saveHierarchyState() {
return null;
}
public void restoreHierarchyState(Bundle savedInstanceState) {
}
protected void onActive() {
mIsOnActiveCalled = true;
}
public void setChildDrawable(int featureId, Drawable drawable) {
}
public void setChildInt(int featureId, int value) {
}
public boolean isShortcutKey(int keyCode, KeyEvent event) {
return false;
}
public void setVolumeControlStream(int streamType) {
}
public int getVolumeControlStream() {
return 0;
}
public void setDefaultWindowFormatFake(int format) {
super.setDefaultWindowFormat(format);
}
@Override
public void setDefaultWindowFormat(int format) {
super.setDefaultWindowFormat(format);
}
}
private class MockWindowCallback implements Window.Callback {
private boolean mIsOnWindowAttributesChangedCalled;
private boolean mIsOnPanelClosedCalled;
public boolean dispatchKeyEvent(KeyEvent event) {
return true;
}
public boolean dispatchTouchEvent(MotionEvent event) {
return true;
}
public boolean dispatchTrackballEvent(MotionEvent event) {
return true;
}
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
return true;
}
public View onCreatePanelView(int featureId) {
return null;
}
public boolean onCreatePanelMenu(int featureId, Menu menu) {
return false;
}
public boolean onPreparePanel(int featureId, View view, Menu menu) {
return false;
}
public boolean onMenuOpened(int featureId, Menu menu) {
return false;
}
public boolean onMenuItemSelected(int featureId, MenuItem item) {
return true;
}
public void onWindowAttributesChanged(WindowManager.LayoutParams attrs) {
mIsOnWindowAttributesChangedCalled = true;
}
public boolean isOnWindowAttributesChangedCalled() {
return mIsOnWindowAttributesChangedCalled;
}
public void onContentChanged() {
}
public void onWindowFocusChanged(boolean hasFocus) {
}
public void onDetachedFromWindow() {
}
public void onAttachedToWindow() {
}
public void onPanelClosed(int featureId, Menu menu) {
mIsOnPanelClosedCalled = true;
}
public boolean isOnPanelClosedCalled() {
return mIsOnPanelClosedCalled;
}
public boolean onSearchRequested() {
return false;
}
}
}