WindowTestsBase.java revision 26c0dfed7a0cd54abafdd0ccbb5b757506d51c76
144fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale/* 244fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale * Copyright (C) 2016 The Android Open Source Project 344fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale * 444fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale * Licensed under the Apache License, Version 2.0 (the "License"); 544fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale * you may not use this file except in compliance with the License. 644fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale * You may obtain a copy of the License at 744fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale * 844fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale * http://www.apache.org/licenses/LICENSE-2.0 944fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale * 1044fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale * Unless required by applicable law or agreed to in writing, software 1144fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale * distributed under the License is distributed on an "AS IS" BASIS, 1244fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1344fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale * See the License for the specific language governing permissions and 1444fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale * limitations under the License 1544fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale */ 1644fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale 1744fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwalepackage com.android.server.wm; 1844fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale 1944fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwaleimport org.junit.Assert; 2044fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwaleimport org.junit.Before; 2144fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale 2244fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwaleimport android.content.Context; 2344fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwaleimport android.os.IBinder; 2444fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwaleimport android.support.test.InstrumentationRegistry; 2544fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwaleimport android.view.IWindow; 2644fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwaleimport android.view.WindowManager; 2744fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale 2844fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwaleimport static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID; 2944fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwaleimport static android.app.AppOpsManager.OP_NONE; 3044fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwaleimport static android.content.res.Configuration.EMPTY; 3144fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwaleimport static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; 3244fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwaleimport static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; 333c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwaleimport static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; 343c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwaleimport static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY; 353c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwaleimport static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; 363c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwaleimport static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; 373c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwaleimport static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; 383c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwaleimport static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; 393c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwaleimport static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; 403c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwaleimport static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; 413c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwaleimport static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; 4244fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwaleimport static org.mockito.Mockito.mock; 4344fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale 4444fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale/** 4544fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale * Common base class for window manager unit test classes. 4644fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale */ 4726c0dfed7a0cd54abafdd0ccbb5b757506d51c76Wale Ogunwaleclass WindowTestsBase { 4844fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale static WindowManagerService sWm = null; 4944fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale private final IWindow mIWindow = new TestIWindow(); 5044fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale private final Session mMockSession = mock(Session.class); 5144fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale private static int sNextStackId = FIRST_DYNAMIC_STACK_ID; 5244fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale private static int sNextTaskId = 0; 5344fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale 543c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwale private static boolean sOneTimeSetupDone = false; 5526c0dfed7a0cd54abafdd0ccbb5b757506d51c76Wale Ogunwale static DisplayContent sDisplayContent; 5626c0dfed7a0cd54abafdd0ccbb5b757506d51c76Wale Ogunwale static WindowLayersController sLayersController; 5726c0dfed7a0cd54abafdd0ccbb5b757506d51c76Wale Ogunwale static WindowState sWallpaperWindow; 5826c0dfed7a0cd54abafdd0ccbb5b757506d51c76Wale Ogunwale static WindowState sImeWindow; 5926c0dfed7a0cd54abafdd0ccbb5b757506d51c76Wale Ogunwale static WindowState sImeDialogWindow; 6026c0dfed7a0cd54abafdd0ccbb5b757506d51c76Wale Ogunwale static WindowState sStatusBarWindow; 6126c0dfed7a0cd54abafdd0ccbb5b757506d51c76Wale Ogunwale static WindowState sDockedDividerWindow; 6226c0dfed7a0cd54abafdd0ccbb5b757506d51c76Wale Ogunwale static WindowState sNavBarWindow; 6326c0dfed7a0cd54abafdd0ccbb5b757506d51c76Wale Ogunwale static WindowState sAppWindow; 6426c0dfed7a0cd54abafdd0ccbb5b757506d51c76Wale Ogunwale static WindowState sChildAppWindowAbove; 6526c0dfed7a0cd54abafdd0ccbb5b757506d51c76Wale Ogunwale static WindowState sChildAppWindowBelow; 663c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwale 6744fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale @Before 6844fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale public void setUp() throws Exception { 693c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwale if (sOneTimeSetupDone) { 703c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwale return; 713c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwale } 723c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwale sOneTimeSetupDone = true; 7344fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale final Context context = InstrumentationRegistry.getTargetContext(); 7444fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale sWm = TestWindowManagerPolicy.getWindowManagerService(context); 753c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwale sLayersController = new WindowLayersController(sWm); 763c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwale sDisplayContent = new DisplayContent(context.getDisplay(), sWm, sLayersController, 773c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwale new WallpaperController(sWm)); 78d276563b38907647ce70940e1e90603826df6ab4Andrii Kulian sWm.mRoot.addChild(sDisplayContent, 0); 793c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwale 803c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwale // Set-up some common windows. 813c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwale sWallpaperWindow = createWindow(null, TYPE_WALLPAPER, sDisplayContent, "wallpaperWindow"); 823c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwale sImeWindow = createWindow(null, TYPE_INPUT_METHOD, sDisplayContent, "sImeWindow"); 833c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwale sImeDialogWindow = 843c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwale createWindow(null, TYPE_INPUT_METHOD_DIALOG, sDisplayContent, "sImeDialogWindow"); 853c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwale sStatusBarWindow = createWindow(null, TYPE_STATUS_BAR, sDisplayContent, "sStatusBarWindow"); 863c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwale sNavBarWindow = 876ce0fb8ddbdc726d55c81a4bf797f028e441e448Wale Ogunwale createWindow(null, TYPE_NAVIGATION_BAR, sDisplayContent, "sNavBarWindow"); 883c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwale sDockedDividerWindow = 896ce0fb8ddbdc726d55c81a4bf797f028e441e448Wale Ogunwale createWindow(null, TYPE_DOCK_DIVIDER, sDisplayContent, "sDockedDividerWindow"); 903c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwale sAppWindow = createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "sAppWindow"); 913c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwale sChildAppWindowAbove = createWindow(sAppWindow, 923c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwale TYPE_APPLICATION_ATTACHED_DIALOG, sAppWindow.mToken, "sChildAppWindowAbove"); 933c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwale sChildAppWindowBelow = createWindow(sAppWindow, 943c1170d849dc0af79623dc0f67eda0fbc66a724fWale Ogunwale TYPE_APPLICATION_MEDIA_OVERLAY, sAppWindow.mToken, "sChildAppWindowBelow"); 9544fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale } 9644fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale 9744fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale /** Asserts that the first entry is greater than the second entry. */ 9844fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale void assertGreaterThan(int first, int second) throws Exception { 9944fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale Assert.assertTrue("Excepted " + first + " to be greater than " + second, first > second); 10044fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale } 10144fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale 1023d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale private WindowToken createWindowToken(DisplayContent dc, int type) { 10344fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale if (type < FIRST_APPLICATION_WINDOW || type > LAST_APPLICATION_WINDOW) { 1043d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale return new TestWindowToken(type, dc); 10544fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale } 10644fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale 107d276563b38907647ce70940e1e90603826df6ab4Andrii Kulian final TaskStack stack = createTaskStackOnDisplay(dc); 108d276563b38907647ce70940e1e90603826df6ab4Andrii Kulian final Task task = createTaskInStack(stack, 0 /* userId */); 1093d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale final TestAppWindowToken token = new TestAppWindowToken(dc); 11072919d2c310db04fdb860e926ccb0bfe6e3aef08Wale Ogunwale task.addChild(token, 0); 11144fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale return token; 11244fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale } 11344fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale 114805d9ecc476134ffafc85a07b05e94a14b1d398cWale Ogunwale WindowState createWindow(WindowState parent, int type, String name) { 115805d9ecc476134ffafc85a07b05e94a14b1d398cWale Ogunwale return (parent == null) 116805d9ecc476134ffafc85a07b05e94a14b1d398cWale Ogunwale ? createWindow(parent, type, sDisplayContent, name) 117805d9ecc476134ffafc85a07b05e94a14b1d398cWale Ogunwale : createWindow(parent, type, parent.mToken, name); 118805d9ecc476134ffafc85a07b05e94a14b1d398cWale Ogunwale } 119805d9ecc476134ffafc85a07b05e94a14b1d398cWale Ogunwale 12044fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name) { 12144fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale final WindowToken token = createWindowToken(dc, type); 12244fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale return createWindow(parent, type, token, name); 12344fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale } 12444fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale 12544fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale WindowState createWindow(WindowState parent, int type, WindowToken token, String name) { 12644fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type); 12744fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale attrs.setTitle(name); 12844fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale 12944fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale final WindowState w = new WindowState(sWm, mMockSession, mIWindow, token, parent, OP_NONE, 13044fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale 0, attrs, 0, 0); 13144fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale // TODO: Probably better to make this call in the WindowState ctor to avoid errors with 13244fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale // adding it to the token... 13344fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale token.addWindow(w); 13444fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale return w; 13544fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale } 1363d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale 137d276563b38907647ce70940e1e90603826df6ab4Andrii Kulian /** Creates a {@link TaskStack} and adds it to the specified {@link DisplayContent}. */ 138d276563b38907647ce70940e1e90603826df6ab4Andrii Kulian TaskStack createTaskStackOnDisplay(DisplayContent dc) { 139d276563b38907647ce70940e1e90603826df6ab4Andrii Kulian final int stackId = sNextStackId++; 140d276563b38907647ce70940e1e90603826df6ab4Andrii Kulian dc.addStackToDisplay(stackId, true); 141d276563b38907647ce70940e1e90603826df6ab4Andrii Kulian return sWm.mStackIdToStack.get(stackId); 142d276563b38907647ce70940e1e90603826df6ab4Andrii Kulian } 143d276563b38907647ce70940e1e90603826df6ab4Andrii Kulian 144d276563b38907647ce70940e1e90603826df6ab4Andrii Kulian /**Creates a {@link Task} and adds it to the specified {@link TaskStack}. */ 145d276563b38907647ce70940e1e90603826df6ab4Andrii Kulian Task createTaskInStack(TaskStack stack, int userId) { 146d276563b38907647ce70940e1e90603826df6ab4Andrii Kulian final Task newTask = new Task(sNextTaskId++, stack, userId, sWm, null, EMPTY, false, 0, 147d276563b38907647ce70940e1e90603826df6ab4Andrii Kulian false); 148d276563b38907647ce70940e1e90603826df6ab4Andrii Kulian stack.addTask(newTask, true); 149d276563b38907647ce70940e1e90603826df6ab4Andrii Kulian return newTask; 150d276563b38907647ce70940e1e90603826df6ab4Andrii Kulian } 151d276563b38907647ce70940e1e90603826df6ab4Andrii Kulian 1523d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale /* Used so we can gain access to some protected members of the {@link WindowToken} class */ 1533d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale class TestWindowToken extends WindowToken { 1543d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale 1553d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale TestWindowToken(int type, DisplayContent dc) { 1563d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale this(type, dc, false /* persistOnEmpty */); 1573d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale } 1583d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale 1593d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty) { 1603d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale super(sWm, mock(IBinder.class), type, persistOnEmpty, dc); 1613d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale } 1623d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale 1633d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale int getWindowsCount() { 1643d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale return mChildren.size(); 1653d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale } 1663d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale 1673d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale boolean hasWindow(WindowState w) { 1683d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale return mChildren.contains(w); 1693d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale } 1703d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale } 1713d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale 1723d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale /* Used so we can gain access to some protected members of the {@link AppWindowToken} class */ 1733d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale class TestAppWindowToken extends AppWindowToken { 1743d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale 1753d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale TestAppWindowToken(DisplayContent dc) { 1763d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale super(sWm, null, false, dc); 1773d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale } 1783d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale 1793d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale int getWindowsCount() { 1803d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale return mChildren.size(); 1813d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale } 1823d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale 1833d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale boolean hasWindow(WindowState w) { 1843d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale return mChildren.contains(w); 1853d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale } 1863d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale 1873d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale WindowState getFirstChild() { 1883d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale return mChildren.getFirst(); 1893d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale } 1903d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale 1913d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale WindowState getLastChild() { 1923d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale return mChildren.getLast(); 1933d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale } 1943d0bfd9530bc51c52aec027eaf6d0dba918efc99Wale Ogunwale } 19544fbdf5b1e13398e35d4bafb7236d194a51ee7afWale Ogunwale} 196