OSDN Git Service

Added View#dispatchViewVisibilityChanged and View#onDispatchVisibilityChanged; update...
authorAdam Powell <adamp@google.com>
Wed, 9 Dec 2009 23:10:07 +0000 (15:10 -0800)
committerAdam Powell <adamp@google.com>
Thu, 10 Dec 2009 22:49:14 +0000 (14:49 -0800)
Reverted a change to InstrumentationTestCase that would have allowed @UiThreadTest on setUp() methods of tests.

api/current.xml
core/java/android/test/InstrumentationTestCase.java
core/java/android/view/View.java
core/java/android/view/ViewGroup.java
tests/FrameworkTest/AndroidManifest.xml
tests/FrameworkTest/res/layout/visibility_callback.xml [new file with mode: 0644]
tests/FrameworkTest/src/com/android/frameworktest/view/VisibilityCallback.java [new file with mode: 0644]
tests/FrameworkTest/tests/src/com/android/frameworktest/view/VisibilityCallbackTest.java [new file with mode: 0644]

index af12f9d..13edee3 100644 (file)
 <method name="glPointSizePointerOES"
  return="void"
  abstract="false"
- native="true"
+ native="false"
  synchronized="false"
  static="true"
  final="false"
 <method name="glMatrixIndexPointerOES"
  return="void"
  abstract="false"
- native="true"
+ native="false"
  synchronized="false"
  static="true"
  final="false"
 <method name="glWeightPointerOES"
  return="void"
  abstract="false"
- native="true"
+ native="false"
  synchronized="false"
  static="true"
  final="false"
 <parameter name="direction" type="int">
 </parameter>
 </method>
+<method name="dispatchVisibilityChanged"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="changedView" type="android.view.View">
+</parameter>
+<parameter name="visibility" type="int">
+</parameter>
+</method>
 <method name="dispatchWindowFocusChanged"
  return="void"
  abstract="false"
 <parameter name="event" type="android.view.MotionEvent">
 </parameter>
 </method>
+<method name="onVisibilityChanged"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="changedView" type="android.view.View">
+</parameter>
+<parameter name="visibility" type="int">
+</parameter>
+</method>
 <method name="onWindowFocusChanged"
  return="void"
  abstract="false"
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="array" type="short[]">
+<parameter name="array" type="java.lang.Object[]">
 </parameter>
 </method>
 <method name="sort"
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="array" type="short[]">
+<parameter name="array" type="java.lang.Object[]">
 </parameter>
 <parameter name="start" type="int">
 </parameter>
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="array" type="java.lang.Object[]">
+<parameter name="array" type="T[]">
+</parameter>
+<parameter name="start" type="int">
+</parameter>
+<parameter name="end" type="int">
+</parameter>
+<parameter name="comparator" type="java.util.Comparator&lt;? super T&gt;">
 </parameter>
 </method>
 <method name="sort"
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="array" type="java.lang.Object[]">
-</parameter>
-<parameter name="start" type="int">
+<parameter name="array" type="T[]">
 </parameter>
-<parameter name="end" type="int">
+<parameter name="comparator" type="java.util.Comparator&lt;? super T&gt;">
 </parameter>
 </method>
 <method name="sort"
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="array" type="T[]">
-</parameter>
-<parameter name="start" type="int">
-</parameter>
-<parameter name="end" type="int">
-</parameter>
-<parameter name="comparator" type="java.util.Comparator&lt;? super T&gt;">
+<parameter name="array" type="short[]">
 </parameter>
 </method>
 <method name="sort"
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="array" type="T[]">
+<parameter name="array" type="short[]">
 </parameter>
-<parameter name="comparator" type="java.util.Comparator&lt;? super T&gt;">
+<parameter name="start" type="int">
+</parameter>
+<parameter name="end" type="int">
 </parameter>
 </method>
 <method name="toString"
index 3290c96..22d95d1 100644 (file)
@@ -147,42 +147,6 @@ public class InstrumentationTestCase extends TestCase {
         }
     }
 
-    @Override
-    public void runBare() throws Throwable {
-        runMethod("setUp");
-
-        try {
-            runTest();
-        } finally {
-            runMethod("tearDown");            
-        }
-    }
-
-    private Throwable[] runMethod(String name) throws Throwable {
-        final Throwable[] exceptions = new Throwable[1];
-        final Method m = getClass().getMethod(name, (Class[]) null);
-
-        if (m.isAnnotationPresent(UiThreadTest.class)) {
-            getInstrumentation().runOnMainSync(new Runnable() {
-                public void run() {
-                    try {
-                        m.invoke(InstrumentationTestCase.this);                        
-                    } catch (Throwable throwable) {
-                        exceptions[0] = throwable;
-                    }
-                }
-            });
-            if (exceptions[0] != null) {
-                throw exceptions[0];
-            }
-            exceptions[0] = null;
-        } else {
-            m.invoke(this);
-        }
-
-        return exceptions;
-    }
-
     /**
      * Runs the current unit test. If the unit test is annotated with
      * {@link android.test.UiThreadTest}, the test is run on the UI thread.
index d3f46b8..7f5d254 100644 (file)
@@ -3771,6 +3771,26 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
     }
 
     /**
+     * Dispatch a view visibility change down the view hierarchy.
+     * ViewGroups should override to route to their children.
+     * @param changedView The view whose visibility changed. Could be 'this' or
+     * an ancestor view.
+     * @param visibility The new visibility of changedView.
+     */
+    protected void dispatchVisibilityChanged(View changedView, int visibility) {
+        onVisibilityChanged(changedView, visibility);
+    }
+
+    /**
+     * Called when the visibility of the view or an ancestor of the view is changed.
+     * @param changedView The view whose visibility changed. Could be 'this' or
+     * an ancestor view.
+     * @param visibility The new visibility of changedView.
+     */
+    protected void onVisibilityChanged(View changedView, int visibility) {
+    }
+
+    /**
      * Dispatch a window visibility change down the view hierarchy.
      * ViewGroups should override to route to their children.
      *
@@ -4349,6 +4369,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
             }
         }
 
+        if ((changed & VISIBILITY_MASK) != 0) {
+            dispatchVisibilityChanged(this, (flags & VISIBILITY_MASK));
+        }
+
         if ((changed & WILL_NOT_CACHE_DRAWING) != 0) {
             destroyDrawingCache();
         }
index e2f15c7..6646136 100644 (file)
@@ -684,6 +684,19 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
      * {@inheritDoc}
      */
     @Override
+    protected void dispatchVisibilityChanged(View changedView, int visibility) {
+        super.dispatchVisibilityChanged(changedView, visibility);
+        final int count = mChildrenCount;
+        final View[] children = mChildren;
+        for (int i = 0; i < count; i++) {
+            children[i].dispatchVisibilityChanged(changedView, visibility);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
     public void dispatchWindowVisibilityChanged(int visibility) {
         super.dispatchWindowVisibilityChanged(visibility);
         final int count = mChildrenCount;
index a906149..3030c06 100644 (file)
             </intent-filter>
         </activity>
 
+        <activity android:name=".view.VisibilityCallback" android:label="VisibilityCallback">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
         <activity android:name=".view.BigCache" android:label="BigCache">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/tests/FrameworkTest/res/layout/visibility_callback.xml b/tests/FrameworkTest/res/layout/visibility_callback.xml
new file mode 100644 (file)
index 0000000..8fd7c8f
--- /dev/null
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2007, 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.
+*/
+-->
+
+<!-- Demonstrates changing view visibility. See corresponding Java code. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <LinearLayout
+      android:orientation="vertical"
+      android:background="@drawable/box"
+      android:layout_width="fill_parent"
+      android:layout_height="wrap_content">
+
+      <TextView android:id="@+id/refUp"
+          android:background="@drawable/red"
+          android:layout_width="fill_parent"
+          android:layout_height="wrap_content"
+          android:text="@string/visibility_1_view_1"/>
+
+      <FrameLayout android:id="@+id/parent"
+                   android:layout_width="fill_parent"
+                   android:layout_height="wrap_content">
+          <view class="com.android.frameworktest.view.VisibilityCallback$MonitoredTextView"
+                android:id="@+id/victim"
+                android:background="@drawable/green"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/visibility_1_view_2"/>
+      </FrameLayout>
+
+      <TextView android:id="@+id/refDown"
+          android:background="@drawable/blue"
+          android:layout_width="fill_parent"
+          android:layout_height="wrap_content"
+          android:text="@string/visibility_1_view_3"/>
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+
+        <Button android:id="@+id/vis"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/visibility_1_vis"/>
+
+        <Button android:id="@+id/invis"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/visibility_1_invis"/>
+
+        <Button android:id="@+id/gone"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/visibility_1_gone"/>
+
+    </LinearLayout>
+</LinearLayout>
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/view/VisibilityCallback.java b/tests/FrameworkTest/src/com/android/frameworktest/view/VisibilityCallback.java
new file mode 100644 (file)
index 0000000..c601f10
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2007 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.frameworktest.view;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.widget.TextView;
+import com.android.frameworktest.R;
+
+import android.os.Bundle;
+import android.widget.Button;
+import android.view.View;
+import android.app.Activity;
+
+/**
+ * Exercise View's ability to change their visibility: GONE, INVISIBLE and
+ * VISIBLE. 
+ */
+public class VisibilityCallback extends Activity {
+    private static final boolean DEBUG = false;
+
+    private MonitoredTextView mVictim;
+    
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        setContentView(R.layout.visibility_callback);
+
+        // Find the view whose visibility will change
+        mVictim = (MonitoredTextView)findViewById(R.id.victim);
+
+        // Find our buttons
+        Button visibleButton = (Button) findViewById(R.id.vis);
+        Button invisibleButton = (Button) findViewById(R.id.invis);
+        Button goneButton = (Button) findViewById(R.id.gone);
+
+        // Wire each button to a click listener
+        visibleButton.setOnClickListener(mVisibleListener);
+        invisibleButton.setOnClickListener(mInvisibleListener);
+        goneButton.setOnClickListener(mGoneListener);
+    }
+
+
+    View.OnClickListener mVisibleListener = new View.OnClickListener() {
+        public void onClick(View v) {
+            mVictim.setVisibility(View.VISIBLE);
+        }
+    };
+
+    View.OnClickListener mInvisibleListener = new View.OnClickListener() {
+        public void onClick(View v) {
+            mVictim.setVisibility(View.INVISIBLE);
+        }
+    };
+
+    View.OnClickListener mGoneListener = new View.OnClickListener() {
+        public void onClick(View v) {
+            mVictim.setVisibility(View.GONE);
+        }
+    };
+
+    public static class MonitoredTextView extends TextView {
+        private View mLastVisChangedView;
+        private int mLastChangedVisibility;
+
+        public MonitoredTextView(Context context) {
+            super(context);
+        }
+
+        public MonitoredTextView(Context context, AttributeSet attrs) {
+            super(context, attrs);
+        }
+
+        public MonitoredTextView(Context context, AttributeSet attrs, int defStyle) {
+            super(context, attrs, defStyle);
+        }
+
+        public View getLastVisChangedView() {
+            return mLastVisChangedView;
+        }
+
+        public int getLastChangedVisibility() {
+            return mLastChangedVisibility;
+        }
+
+        @Override
+        protected void onVisibilityChanged(View changedView, int visibility) {
+            mLastVisChangedView = changedView;
+            mLastChangedVisibility = visibility;
+
+            if (DEBUG) {
+                Log.d("viewVis", "visibility: " + visibility);
+            }
+        }
+    }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/view/VisibilityCallbackTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/VisibilityCallbackTest.java
new file mode 100644 (file)
index 0000000..6bef230
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2007 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.frameworktest.view;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TextView;
+import com.android.frameworktest.R;
+
+/**
+ * Exercises {@link android.view.View}'s ability to change visibility between
+ * GONE, VISIBLE and INVISIBLE.
+ */
+public class VisibilityCallbackTest extends ActivityInstrumentationTestCase2<VisibilityCallback> {
+    private TextView mRefUp;
+    private TextView mRefDown;
+    private VisibilityCallback.MonitoredTextView mVictim;
+    private ViewGroup mParent;
+    private Button mVisible;
+    private Button mInvisible;
+    private Button mGone;
+
+    public VisibilityCallbackTest() {
+        super("com.android.frameworktest", VisibilityCallback.class);
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        final VisibilityCallback a = getActivity();
+        mRefUp = (TextView) a.findViewById(R.id.refUp);
+        mRefDown = (TextView) a.findViewById(R.id.refDown);
+        mVictim = (VisibilityCallback.MonitoredTextView) a.findViewById(R.id.victim);
+        mParent = (ViewGroup) a.findViewById(R.id.parent);
+        mVisible = (Button) a.findViewById(R.id.vis);
+        mInvisible = (Button) a.findViewById(R.id.invis);
+        mGone = (Button) a.findViewById(R.id.gone);
+
+        mVictim.post(new Runnable() {
+            public void run() {
+                mVictim.setVisibility(View.INVISIBLE);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+     }
+
+    @MediumTest
+    @UiThreadTest
+    public void testSetUpConditions() throws Exception {
+        assertNotNull(mRefUp);
+        assertNotNull(mRefDown);
+        assertNotNull(mVictim);
+        assertNotNull(mVisible);
+        assertNotNull(mInvisible);
+        assertNotNull(mGone);
+
+        assertTrue(mVisible.hasFocus());
+        assertEquals(View.INVISIBLE, mVictim.getVisibility());
+        assertEquals(View.VISIBLE, mParent.getVisibility());
+    }
+
+    @MediumTest
+    @UiThreadTest
+    public void testDirect() throws Exception {
+        mVictim.setVisibility(View.VISIBLE);
+        assertEquals(View.VISIBLE, mVictim.getLastChangedVisibility());
+        assertEquals(mVictim, mVictim.getLastVisChangedView());
+
+        mVictim.setVisibility(View.INVISIBLE);
+        assertEquals(View.INVISIBLE, mVictim.getLastChangedVisibility());
+        assertEquals(mVictim, mVictim.getLastVisChangedView());
+
+        mVictim.setVisibility(View.GONE);
+        assertEquals(View.GONE, mVictim.getLastChangedVisibility());
+        assertEquals(mVictim, mVictim.getLastVisChangedView());
+    }
+
+    @MediumTest
+    @UiThreadTest
+    public void testChild() throws Exception {
+        mParent.setVisibility(View.INVISIBLE);
+        assertEquals(View.INVISIBLE, mVictim.getLastChangedVisibility());
+        assertEquals(mParent, mVictim.getLastVisChangedView());
+
+        mParent.setVisibility(View.GONE);
+        assertEquals(View.GONE, mVictim.getLastChangedVisibility());
+        assertEquals(mParent, mVictim.getLastVisChangedView());
+
+        mParent.setVisibility(View.VISIBLE);
+        assertEquals(View.VISIBLE, mVictim.getLastChangedVisibility());
+        assertEquals(mParent, mVictim.getLastVisChangedView());
+    }
+}