1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.gallery3d.ui; 18 19import android.graphics.Rect; 20import android.test.suitebuilder.annotation.SmallTest; 21import android.view.MotionEvent; 22 23import junit.framework.TestCase; 24 25@SmallTest 26public class GLViewTest extends TestCase { 27 @SuppressWarnings("unused") 28 private static final String TAG = "GLViewTest"; 29 30 @SmallTest 31 public void testVisibility() { 32 GLViewMock a = new GLViewMock(); 33 assertEquals(GLView.VISIBLE, a.getVisibility()); 34 assertEquals(0, a.mOnVisibilityChangedCalled); 35 a.setVisibility(GLView.INVISIBLE); 36 assertEquals(GLView.INVISIBLE, a.getVisibility()); 37 assertEquals(1, a.mOnVisibilityChangedCalled); 38 a.setVisibility(GLView.VISIBLE); 39 assertEquals(GLView.VISIBLE, a.getVisibility()); 40 assertEquals(2, a.mOnVisibilityChangedCalled); 41 } 42 43 @SmallTest 44 public void testComponents() { 45 GLView view = new GLView(); 46 assertEquals(0, view.getComponentCount()); 47 try { 48 view.getComponent(0); 49 fail(); 50 } catch (IndexOutOfBoundsException ex) { 51 // expected 52 } 53 54 GLView x = new GLView(); 55 GLView y = new GLView(); 56 view.addComponent(x); 57 view.addComponent(y); 58 assertEquals(2, view.getComponentCount()); 59 assertSame(x, view.getComponent(0)); 60 assertSame(y, view.getComponent(1)); 61 view.removeComponent(x); 62 assertSame(y, view.getComponent(0)); 63 try { 64 view.getComponent(1); 65 fail(); 66 } catch (IndexOutOfBoundsException ex) { 67 // expected 68 } 69 try { 70 view.addComponent(y); 71 fail(); 72 } catch (IllegalStateException ex) { 73 // expected 74 } 75 view.addComponent(x); 76 view.removeAllComponents(); 77 assertEquals(0, view.getComponentCount()); 78 } 79 80 @SmallTest 81 public void testBounds() { 82 GLView view = new GLView(); 83 84 assertEquals(0, view.getWidth()); 85 assertEquals(0, view.getHeight()); 86 87 Rect b = view.bounds(); 88 assertEquals(0, b.left); 89 assertEquals(0, b.top); 90 assertEquals(0, b.right); 91 assertEquals(0, b.bottom); 92 93 view.layout(10, 20, 30, 100); 94 assertEquals(20, view.getWidth()); 95 assertEquals(80, view.getHeight()); 96 97 b = view.bounds(); 98 assertEquals(10, b.left); 99 assertEquals(20, b.top); 100 assertEquals(30, b.right); 101 assertEquals(100, b.bottom); 102 } 103 104 @SmallTest 105 public void testPaddings() { 106 GLView view = new GLView(); 107 108 Rect p = view.getPaddings(); 109 assertEquals(0, p.left); 110 assertEquals(0, p.top); 111 assertEquals(0, p.right); 112 assertEquals(0, p.bottom); 113 114 view.setPaddings(10, 20, 30, 100); 115 p = view.getPaddings(); 116 assertEquals(10, p.left); 117 assertEquals(20, p.top); 118 assertEquals(30, p.right); 119 assertEquals(100, p.bottom); 120 121 p = new Rect(11, 22, 33, 104); 122 view.setPaddings(p); 123 p = view.getPaddings(); 124 assertEquals(11, p.left); 125 assertEquals(22, p.top); 126 assertEquals(33, p.right); 127 assertEquals(104, p.bottom); 128 } 129 130 @SmallTest 131 public void testParent() { 132 GLView a = new GLView(); 133 GLView b = new GLView(); 134 assertNull(b.mParent); 135 a.addComponent(b); 136 assertSame(a, b.mParent); 137 a.removeComponent(b); 138 assertNull(b.mParent); 139 } 140 141 @SmallTest 142 public void testRoot() { 143 GLViewMock a = new GLViewMock(); 144 GLViewMock b = new GLViewMock(); 145 GLRoot r = new GLRootStub(); 146 GLRoot r2 = new GLRootStub(); 147 a.addComponent(b); 148 149 // Attach to root r 150 assertEquals(0, a.mOnAttachCalled); 151 assertEquals(0, b.mOnAttachCalled); 152 a.attachToRoot(r); 153 assertEquals(1, a.mOnAttachCalled); 154 assertEquals(1, b.mOnAttachCalled); 155 assertSame(r, a.getGLRoot()); 156 assertSame(r, b.getGLRoot()); 157 158 // Detach from r 159 assertEquals(0, a.mOnDetachCalled); 160 assertEquals(0, b.mOnDetachCalled); 161 a.detachFromRoot(); 162 assertEquals(1, a.mOnDetachCalled); 163 assertEquals(1, b.mOnDetachCalled); 164 165 // Attach to another root r2 166 assertEquals(1, a.mOnAttachCalled); 167 assertEquals(1, b.mOnAttachCalled); 168 a.attachToRoot(r2); 169 assertEquals(2, a.mOnAttachCalled); 170 assertEquals(2, b.mOnAttachCalled); 171 assertSame(r2, a.getGLRoot()); 172 assertSame(r2, b.getGLRoot()); 173 174 // Detach from r2 175 assertEquals(1, a.mOnDetachCalled); 176 assertEquals(1, b.mOnDetachCalled); 177 a.detachFromRoot(); 178 assertEquals(2, a.mOnDetachCalled); 179 assertEquals(2, b.mOnDetachCalled); 180 } 181 182 @SmallTest 183 public void testRoot2() { 184 GLView a = new GLViewMock(); 185 GLViewMock b = new GLViewMock(); 186 GLRoot r = new GLRootStub(); 187 188 a.attachToRoot(r); 189 190 assertEquals(0, b.mOnAttachCalled); 191 a.addComponent(b); 192 assertEquals(1, b.mOnAttachCalled); 193 194 assertEquals(0, b.mOnDetachCalled); 195 a.removeComponent(b); 196 assertEquals(1, b.mOnDetachCalled); 197 } 198 199 @SmallTest 200 public void testInvalidate() { 201 GLView a = new GLView(); 202 GLRootMock r = new GLRootMock(); 203 a.attachToRoot(r); 204 assertEquals(0, r.mRequestRenderCalled); 205 a.invalidate(); 206 assertEquals(1, r.mRequestRenderCalled); 207 } 208 209 @SmallTest 210 public void testRequestLayout() { 211 GLView a = new GLView(); 212 GLView b = new GLView(); 213 GLRootMock r = new GLRootMock(); 214 a.attachToRoot(r); 215 a.addComponent(b); 216 assertEquals(0, r.mRequestLayoutContentPaneCalled); 217 b.requestLayout(); 218 assertEquals(1, r.mRequestLayoutContentPaneCalled); 219 } 220 221 @SmallTest 222 public void testLayout() { 223 GLViewMock a = new GLViewMock(); 224 GLViewMock b = new GLViewMock(); 225 GLViewMock c = new GLViewMock(); 226 GLRootMock r = new GLRootMock(); 227 228 a.attachToRoot(r); 229 a.addComponent(b); 230 a.addComponent(c); 231 232 assertEquals(0, a.mOnLayoutCalled); 233 a.layout(10, 20, 60, 100); 234 assertEquals(1, a.mOnLayoutCalled); 235 assertEquals(1, b.mOnLayoutCalled); 236 assertEquals(1, c.mOnLayoutCalled); 237 assertTrue(a.mOnLayoutChangeSize); 238 assertTrue(b.mOnLayoutChangeSize); 239 assertTrue(c.mOnLayoutChangeSize); 240 241 // same size should not trigger onLayout 242 a.layout(10, 20, 60, 100); 243 assertEquals(1, a.mOnLayoutCalled); 244 245 // unless someone requested it, but only those on the path 246 // to the requester. 247 assertEquals(0, r.mRequestLayoutContentPaneCalled); 248 b.requestLayout(); 249 a.layout(10, 20, 60, 100); 250 assertEquals(1, r.mRequestLayoutContentPaneCalled); 251 assertEquals(2, a.mOnLayoutCalled); 252 assertEquals(2, b.mOnLayoutCalled); 253 assertEquals(1, c.mOnLayoutCalled); 254 } 255 256 @SmallTest 257 public void testRender() { 258 GLViewMock a = new GLViewMock(); 259 GLViewMock b = new GLViewMock(); 260 261 a.addComponent(b); 262 GLCanvasStub canvas = new GLCanvasStub(); 263 assertEquals(0, a.mRenderBackgroundCalled); 264 assertEquals(0, b.mRenderBackgroundCalled); 265 a.render(canvas); 266 assertEquals(1, a.mRenderBackgroundCalled); 267 assertEquals(1, b.mRenderBackgroundCalled); 268 } 269 270 @SmallTest 271 public void testMeasure() { 272 GLViewMock a = new GLViewMock(); 273 GLViewMock b = new GLViewMock(); 274 GLViewMock c = new GLViewMock(); 275 GLRootMock r = new GLRootMock(); 276 277 a.addComponent(b); 278 a.addComponent(c); 279 a.attachToRoot(r); 280 281 assertEquals(0, a.mOnMeasureCalled); 282 a.measure(100, 200); 283 assertEquals(1, a.mOnMeasureCalled); 284 assertEquals(1, b.mOnMeasureCalled); 285 assertEquals(100, a.mOnMeasureWidthSpec); 286 assertEquals(200, a.mOnMeasureHeightSpec); 287 assertEquals(100, b.mOnMeasureWidthSpec); 288 assertEquals(200, b.mOnMeasureHeightSpec); 289 assertEquals(100, a.getMeasuredWidth()); 290 assertEquals(200, b.getMeasuredHeight()); 291 292 // same spec should not trigger onMeasure 293 a.measure(100, 200); 294 assertEquals(1, a.mOnMeasureCalled); 295 296 // unless someone requested it, but only those on the path 297 // to the requester. 298 b.requestLayout(); 299 a.measure(100, 200); 300 assertEquals(2, a.mOnMeasureCalled); 301 assertEquals(2, b.mOnMeasureCalled); 302 assertEquals(1, c.mOnMeasureCalled); 303 } 304 305 class MyGLView extends GLView { 306 private int mWidth; 307 int mOnTouchCalled; 308 int mOnTouchX; 309 int mOnTouchY; 310 int mOnTouchAction; 311 312 public MyGLView(int width) { 313 mWidth = width; 314 } 315 316 @Override 317 protected void onLayout(boolean changeSize, int left, int top, 318 int right, int bottom) { 319 // layout children from left to right 320 // call children's layout. 321 int x = 0; 322 for (int i = 0, n = getComponentCount(); i < n; ++i) { 323 GLView item = getComponent(i); 324 item.measure(0, 0); 325 int w = item.getMeasuredWidth(); 326 int h = item.getMeasuredHeight(); 327 item.layout(x, 0, x + w, h); 328 x += w; 329 } 330 } 331 332 @Override 333 protected void onMeasure(int widthSpec, int heightSpec) { 334 setMeasuredSize(mWidth, 100); 335 } 336 337 @Override 338 protected boolean onTouch(MotionEvent event) { 339 mOnTouchCalled++; 340 mOnTouchX = (int) event.getX(); 341 mOnTouchY = (int) event.getY(); 342 mOnTouchAction = event.getAction(); 343 return true; 344 } 345 } 346 347 private MotionEvent NewMotionEvent(int action, int x, int y) { 348 return MotionEvent.obtain(0, 0, action, x, y, 0); 349 } 350 351 @SmallTest 352 public void testTouchEvent() { 353 // We construct a tree with four nodes. Only the x coordinate is used: 354 // A = [0..............................300) 355 // B = [0......100) 356 // C = [100......200) 357 // D = [100..150) 358 359 MyGLView a = new MyGLView(300); 360 MyGLView b = new MyGLView(100); 361 MyGLView c = new MyGLView(100); 362 MyGLView d = new MyGLView(50); 363 GLRoot r = new GLRootStub(); 364 365 a.addComponent(b); 366 a.addComponent(c); 367 c.addComponent(d); 368 a.attachToRoot(r); 369 a.layout(0, 0, 300, 100); 370 371 int DOWN = MotionEvent.ACTION_DOWN; 372 int UP = MotionEvent.ACTION_UP; 373 int MOVE = MotionEvent.ACTION_MOVE; 374 int CANCEL = MotionEvent.ACTION_CANCEL; 375 376 // simple case 377 assertEquals(0, a.mOnTouchCalled); 378 a.dispatchTouchEvent(NewMotionEvent(DOWN, 250, 0)); 379 assertEquals(DOWN, a.mOnTouchAction); 380 a.dispatchTouchEvent(NewMotionEvent(UP, 250, 0)); 381 assertEquals(UP, a.mOnTouchAction); 382 assertEquals(2, a.mOnTouchCalled); 383 384 // pass to a child, check the location is offseted. 385 assertEquals(0, c.mOnTouchCalled); 386 a.dispatchTouchEvent(NewMotionEvent(DOWN, 175, 0)); 387 a.dispatchTouchEvent(NewMotionEvent(UP, 175, 0)); 388 assertEquals(75, c.mOnTouchX); 389 assertEquals(0, c.mOnTouchY); 390 assertEquals(2, c.mOnTouchCalled); 391 assertEquals(2, a.mOnTouchCalled); 392 393 // motion target cancel event 394 assertEquals(0, d.mOnTouchCalled); 395 a.dispatchTouchEvent(NewMotionEvent(DOWN, 125, 0)); 396 assertEquals(1, d.mOnTouchCalled); 397 a.dispatchTouchEvent(NewMotionEvent(MOVE, 250, 0)); 398 assertEquals(2, d.mOnTouchCalled); 399 a.dispatchTouchEvent(NewMotionEvent(MOVE, 50, 0)); 400 assertEquals(3, d.mOnTouchCalled); 401 a.dispatchTouchEvent(NewMotionEvent(DOWN, 175, 0)); 402 assertEquals(4, d.mOnTouchCalled); 403 assertEquals(CANCEL, d.mOnTouchAction); 404 assertEquals(3, c.mOnTouchCalled); 405 assertEquals(DOWN, c.mOnTouchAction); 406 a.dispatchTouchEvent(NewMotionEvent(UP, 175, 0)); 407 408 // motion target is removed 409 assertEquals(4, d.mOnTouchCalled); 410 a.dispatchTouchEvent(NewMotionEvent(DOWN, 125, 0)); 411 assertEquals(5, d.mOnTouchCalled); 412 a.removeComponent(c); 413 assertEquals(6, d.mOnTouchCalled); 414 assertEquals(CANCEL, d.mOnTouchAction); 415 416 // invisible component should not get events 417 assertEquals(2, a.mOnTouchCalled); 418 assertEquals(0, b.mOnTouchCalled); 419 b.setVisibility(GLView.INVISIBLE); 420 a.dispatchTouchEvent(NewMotionEvent(DOWN, 50, 0)); 421 assertEquals(3, a.mOnTouchCalled); 422 assertEquals(0, b.mOnTouchCalled); 423 } 424} 425