More jank tests - usecases from calendar, contacts, gmail, apidemo

Change-Id: Ib7df210b850c150db729e98064d05b77d4052825
diff --git a/tests/jank/jankmicrobenchmark/src/com/android/jankmicrobenchmark/janktests/ApiDemoJankTests.java b/tests/jank/jankmicrobenchmark/src/com/android/jankmicrobenchmark/janktests/ApiDemoJankTests.java
index 33f4c0a..6f357e0 100644
--- a/tests/jank/jankmicrobenchmark/src/com/android/jankmicrobenchmark/janktests/ApiDemoJankTests.java
+++ b/tests/jank/jankmicrobenchmark/src/com/android/jankmicrobenchmark/janktests/ApiDemoJankTests.java
@@ -51,11 +51,7 @@
     public void setUp() throws Exception {
         super.setUp();
         mDevice = UiDevice.getInstance(getInstrumentation());
-        try {
-            mDevice.setOrientationNatural();
-        } catch (RemoteException e) {
-            throw new RuntimeException("failed to freeze device orientaion", e);
-        }
+        mDevice.setOrientationNatural();
     }
 
     @Override
@@ -64,15 +60,18 @@
         super.tearDown();
     }
 
-    public void launchApiDemosAndSelectAnimation(String optionName)
-            throws UiObjectNotFoundException {
+    public void launchApiDemos() {
         Intent intent = getInstrumentation().getContext().getPackageManager()
                 .getLaunchIntentForPackage(PACKAGE_NAME);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         getInstrumentation().getContext().startActivity(intent);
+        mDevice.waitForIdle();
+    }
+    public void selectAnimation(String optionName) {
+        launchApiDemos();
         UiObject2 animation = mDevice.wait(Until.findObject(
                 By.res(RES_PACKAGE_NAME, "text1").text("Animation")), LONG_TIMEOUT);
-        Assert.assertNotNull("Animation is null", animation);
+        Assert.assertNotNull("Animation isn't found in ApiDemos", animation);
         animation.click();
         UiObject2 option = mDevice.wait(Until.findObject(
                 By.res(RES_PACKAGE_NAME, "text1").text(optionName)), LONG_TIMEOUT);
@@ -84,7 +83,7 @@
                     .text(optionName)), LONG_TIMEOUT);
             --maxAttempt;
         }
-        Assert.assertNotNull("Option is null", option);
+        Assert.assertNotNull("Target option in APiDemos animation for test isn't found", option);
         option.click();
     }
 
@@ -103,7 +102,7 @@
 
     // Loads the 'activity transition' animation
     public void selectActivityTransitionAnimation() throws UiObjectNotFoundException {
-         launchApiDemosAndSelectAnimation("Activity Transition");
+         selectAnimation("Activity Transition");
     }
 
     // Measures jank for activity transition animation
@@ -121,7 +120,7 @@
 
     // Loads the 'view flip' animation
     public void selectViewFlipAnimation() throws UiObjectNotFoundException {
-        launchApiDemosAndSelectAnimation("View Flip");
+        selectAnimation("View Flip");
     }
 
     // Measures jank for view flip animation
@@ -138,7 +137,7 @@
 
     // Loads the 'cloning' animation
     public void selectCloningAnimation() throws UiObjectNotFoundException {
-        launchApiDemosAndSelectAnimation("Cloning");
+        selectAnimation("Cloning");
     }
 
     // Measures jank for cloning animation
@@ -155,7 +154,7 @@
 
     // Loads the 'loading' animation
     public void selectLoadingOption() throws UiObjectNotFoundException {
-        launchApiDemosAndSelectAnimation("Loading");
+        selectAnimation("Loading");
     }
 
     // Measures jank for 'loading' animation
@@ -166,7 +165,7 @@
         UiObject2 runButton = mDevice.wait(Until.findObject(
             By.res(PACKAGE_NAME, "startButton").text("Run")), LONG_TIMEOUT);
         Assert.assertNotNull("Run button is null", runButton);
-        for(int i = 0; i < INNER_LOOP; i++) {
+        for (int i = 0; i < INNER_LOOP; i++) {
             runButton.click();
             SystemClock.sleep(SHORT_TIMEOUT * 2);
         }
@@ -174,7 +173,7 @@
 
     // Loads the 'simple transition' animation
     public void selectSimpleTransitionOption() throws UiObjectNotFoundException {
-        launchApiDemosAndSelectAnimation("Simple Transitions");
+        selectAnimation("Simple Transitions");
     }
 
     // Measures jank for 'simple transition' animation
@@ -182,16 +181,16 @@
               expectedFrames=EXPECTED_FRAMES)
     @GfxMonitor(processName=PACKAGE_NAME)
     public void testSimpleTransitionJank() {
-        for(int i = 0; i < INNER_LOOP; i++) {
+        for (int i = 0; i < INNER_LOOP; i++) {
             UiObject2 scene2 = mDevice.wait(Until.findObject(
                     By.res(PACKAGE_NAME, "scene2")), LONG_TIMEOUT);
-            Assert.assertNotNull("Scene2 is null", scene2);
+            Assert.assertNotNull("Scene2 button can't be found", scene2);
             scene2.click();
             SystemClock.sleep(SHORT_TIMEOUT);
 
             UiObject2 scene1 = mDevice.wait(Until.findObject(
                     By.res(PACKAGE_NAME, "scene1")), LONG_TIMEOUT);
-            Assert.assertNotNull("Scene1 is null", scene1);
+            Assert.assertNotNull("Scene1 button can't be found", scene1);
             scene1.click();
             SystemClock.sleep(SHORT_TIMEOUT);
         }
@@ -199,7 +198,7 @@
 
     // Loads the 'hide/show' animation
     public void selectHideShowAnimationOption() throws UiObjectNotFoundException {
-        launchApiDemosAndSelectAnimation("Hide-Show Animations");
+        selectAnimation("Hide-Show Animations");
     }
 
     // Measures jank for 'hide/show' animation
@@ -207,36 +206,133 @@
               expectedFrames=EXPECTED_FRAMES)
     @GfxMonitor(processName=PACKAGE_NAME)
     public void testHideShowAnimationJank() {
-        for(int i = 0; i < INNER_LOOP; i++) {
+        for (int i = 0; i < INNER_LOOP; i++) {
             UiObject2 showButton = mDevice.wait(Until.findObject(By.res(
                     PACKAGE_NAME, "addNewButton").text("Show Buttons")), LONG_TIMEOUT);
-            Assert.assertNotNull("Show Button is null", showButton);
+            Assert.assertNotNull("'Show Buttons' button can't be found", showButton);
             showButton.click();
             SystemClock.sleep(SHORT_TIMEOUT);
 
             UiObject2 button0 = mDevice.wait(Until.findObject(
                     By.clazz(Button.class).text("0")), LONG_TIMEOUT);
-            Assert.assertNotNull("Button0 is null", button0);
+            Assert.assertNotNull("Button0 isn't found", button0);
             button0.click();
             SystemClock.sleep(SHORT_TIMEOUT);
 
             UiObject2 button1 = mDevice.wait(Until.findObject(
                     By.clazz(Button.class).text("1")), LONG_TIMEOUT);
-            Assert.assertNotNull("Button1 is null", button1);
+            Assert.assertNotNull("Button1 isn't found", button1);
             button1.click();
             SystemClock.sleep(SHORT_TIMEOUT);
 
             UiObject2 button2 = mDevice.wait(Until.findObject(
                     By.clazz(Button.class).text("2")), LONG_TIMEOUT);
-            Assert.assertNotNull("Button2 is null", button2);
+            Assert.assertNotNull("Button2 isn't found", button2);
             button2.click();
             SystemClock.sleep(SHORT_TIMEOUT);
 
             UiObject2 button3 = mDevice.wait(Until.findObject(
                     By.clazz(Button.class).text("3")), LONG_TIMEOUT);
-            Assert.assertNotNull("Button3 is null", button3);
+            Assert.assertNotNull("Button3 isn't found", button3);
             button3.click();
             SystemClock.sleep(SHORT_TIMEOUT);
         }
     }
+
+    public void selectViews(String optionName) {
+        launchApiDemos();
+        UiObject2 views = null;
+        short maxAttempt = 4;
+        while (views == null && maxAttempt > 0) {
+            mDevice.wait(Until.findObject(By.res(RES_PACKAGE_NAME, "content")), LONG_TIMEOUT)
+                    .scroll(Direction.DOWN, 1.0f);
+            views = mDevice.wait(Until.findObject(By.res(RES_PACKAGE_NAME, "text1")
+                    .text("Views")), LONG_TIMEOUT);
+            --maxAttempt;
+        }
+        Assert.assertNotNull("Views item can't be found", views);
+        views.click();
+        // Opens selective view (provided as param) from different 'ApiDemos Views' options
+        UiObject2 option = null;
+        maxAttempt = 4;
+        while (option == null && maxAttempt > 0) {
+            mDevice.wait(Until.findObject(By.res(RES_PACKAGE_NAME, "content")), LONG_TIMEOUT)
+                    .scroll(Direction.DOWN, 1.0f);
+            option = mDevice.wait(Until.findObject(By.res(RES_PACKAGE_NAME, "text1")
+                    .text(optionName)), LONG_TIMEOUT);
+            --maxAttempt;
+        }
+        Assert.assertNotNull("Target option to be tested in ApiDemos Views can't be found", option);
+        option.click();
+    }
+
+    // Loads  simple listview
+    public void selectListsArray() throws UiObjectNotFoundException {
+        selectViews("Lists");
+        UiObject2 array = mDevice.wait(Until.findObject(
+                By.res(RES_PACKAGE_NAME, "text1").text("01. Array")), LONG_TIMEOUT);
+        Assert.assertNotNull("Array listview can't be found", array);
+        array.click();
+    }
+
+    // Measures jank for simple listview fling
+    @JankTest(beforeTest="selectLists_Array", afterTest="goBackHome",
+              expectedFrames=EXPECTED_FRAMES)
+    @GfxMonitor(processName=PACKAGE_NAME)
+    public void testListViewJank() {
+        for (int i = 0; i < INNER_LOOP; i++) {
+            UiObject2 listView = mDevice.wait(Until.findObject(By.res(
+                    RES_PACKAGE_NAME, "content")), LONG_TIMEOUT);
+            Assert.assertNotNull("Content pane isn't found to move up", listView);
+            listView.fling(Direction.DOWN);
+            SystemClock.sleep(SHORT_TIMEOUT);
+            listView.fling(Direction.UP);
+            SystemClock.sleep(SHORT_TIMEOUT);
+        }
+    }
+
+    // Loads simple expandable list view
+    public void selectExpandableLists_SimpleAdapter() throws UiObjectNotFoundException {
+        selectViews("Expandable Lists");
+        UiObject2 simpleAdapter = mDevice.wait(Until.findObject(
+                By.res(RES_PACKAGE_NAME, "text1").text("3. Simple Adapter")), LONG_TIMEOUT);
+        Assert.assertNotNull("Simple adapter can't be found", simpleAdapter);
+        simpleAdapter.click();
+    }
+
+    // Measures jank for simple expandable list view expansion
+    // Expansion group1, group3 and group4 arbitrarily selected
+    @JankTest(beforeTest="selectExpandableLists_SimpleAdapter", afterTest="goBackHome",
+              expectedFrames=EXPECTED_FRAMES)
+    @GfxMonitor(processName=PACKAGE_NAME)
+    public void testExapandableListViewJank() {
+        for (int i = 0; i < INNER_LOOP; i++) {
+          UiObject2 group1 = mDevice.wait(Until.findObject(By.res(
+                  RES_PACKAGE_NAME, "text1").text("Group 1")), LONG_TIMEOUT);
+          Assert.assertNotNull("Group 1 isn't found to be expanded", group1);
+          group1.click();
+          SystemClock.sleep(SHORT_TIMEOUT);
+          group1.click();
+          SystemClock.sleep(SHORT_TIMEOUT);
+          UiObject2 group3 = mDevice.wait(Until.findObject(By.res(
+                  RES_PACKAGE_NAME, "text1").text("Group 3")), LONG_TIMEOUT);
+          Assert.assertNotNull("Group 3 isn't found to be expanded", group3);
+          group3.click();
+          SystemClock.sleep(SHORT_TIMEOUT);
+          group3.click();
+          SystemClock.sleep(SHORT_TIMEOUT);
+          UiObject2 group4 = mDevice.wait(Until.findObject(By.res(
+                  RES_PACKAGE_NAME, "text1").text("Group 4")), LONG_TIMEOUT);
+          Assert.assertNotNull("Group 4 isn't found to be expanded", group4);
+          group4.click();
+          SystemClock.sleep(SHORT_TIMEOUT);
+          group4.click();
+          SystemClock.sleep(SHORT_TIMEOUT);
+          UiObject2 content = mDevice.wait(Until.findObject(By.res(
+                  RES_PACKAGE_NAME, "content")), LONG_TIMEOUT);
+          Assert.assertNotNull("Content pane isn't found to move up", content);
+          content.fling(Direction.UP);
+          SystemClock.sleep(SHORT_TIMEOUT);
+        }
+    }
 }
diff --git a/tests/jank/sysapp/AndroidManifest.xml b/tests/jank/sysapp/AndroidManifest.xml
index 99e3178..1468a8e 100644
--- a/tests/jank/sysapp/AndroidManifest.xml
+++ b/tests/jank/sysapp/AndroidManifest.xml
@@ -17,6 +17,9 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.sysapp.janktests">
 
+    <uses-sdk android:minSdkVersion="21" />
+    <uses-permission android:name="android.permission.READ_CONTACTS" />
+
     <application>
         <uses-library android:name="android.test.runner" />
     </application>
diff --git a/tests/jank/sysapp/src/com/android/sysapp/janktests/CalendarJankTests.java b/tests/jank/sysapp/src/com/android/sysapp/janktests/CalendarJankTests.java
new file mode 100644
index 0000000..b80d224
--- /dev/null
+++ b/tests/jank/sysapp/src/com/android/sysapp/janktests/CalendarJankTests.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2015 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.sysapp.janktests;
+
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.support.test.jank.GfxMonitor;
+import android.support.test.jank.JankTest;
+import android.support.test.jank.JankTestBase;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.Direction;
+import android.support.test.uiautomator.StaleObjectException;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.support.test.uiautomator.Until;
+import junit.framework.Assert;
+
+/**
+ * Jank test for Calendar
+ * open and fling
+ * cal.jank.test1@gmail
+ */
+
+public class CalendarJankTests extends JankTestBase {
+    private static final int LONG_TIMEOUT = 2000;
+    private static final int SHORT_TIMEOUT = 100;
+    private static final int INNER_LOOP = 5;
+    private static final int EXPECTED_FRAMES = 100;
+    private static final String PACKAGE_NAME = "com.google.android.calendar";
+    private static final String RES_PACKAGE_NAME = "com.android.calendar";
+    private UiDevice mDevice;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mDevice = UiDevice.getInstance(getInstrumentation());
+        mDevice.setOrientationNatural();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mDevice.unfreezeRotation();
+        super.tearDown();
+    }
+
+    public void launchApp(String packageName) throws UiObjectNotFoundException{
+        PackageManager pm = getInstrumentation().getContext().getPackageManager();
+        Intent appIntent = pm.getLaunchIntentForPackage(packageName);
+        appIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        getInstrumentation().getContext().startActivity(appIntent);
+        SystemClock.sleep(SHORT_TIMEOUT * 10);
+    }
+
+    public void launchCalendar () throws UiObjectNotFoundException {
+        launchApp(PACKAGE_NAME);
+        mDevice.waitForIdle();
+        dismissCling();
+        Assert.assertNotNull("Calendar can't be found",
+            mDevice.wait(Until.findObject(By.res(RES_PACKAGE_NAME, "timely_list")), LONG_TIMEOUT));
+    }
+
+    // Measures jank of flinging calendar items
+    @JankTest(beforeTest="launchCalendar", expectedFrames=EXPECTED_FRAMES)
+    @GfxMonitor(processName=PACKAGE_NAME)
+    public void testCalendarItemsFling() {
+        UiObject2 timelyList = mDevice.wait(
+                Until.findObject(By.res(RES_PACKAGE_NAME, "timely_list")), LONG_TIMEOUT);
+        for (int i = 0; i < INNER_LOOP; i++) {
+            timelyList.fling(Direction.DOWN);
+            SystemClock.sleep(SHORT_TIMEOUT);
+            timelyList.fling(Direction.UP);
+            SystemClock.sleep(SHORT_TIMEOUT);
+        }
+    }
+
+    private void dismissCling(){
+        UiObject2 rightArrow = null;
+        short counter = 8;
+        while ((rightArrow = mDevice.wait(Until.findObject(By.res(
+                RES_PACKAGE_NAME, "right_arrow_touch")), LONG_TIMEOUT)) != null && counter > 0) {
+            rightArrow.click();
+            --counter;
+        }
+        UiObject2 gotIt = mDevice.wait(Until.findObject(
+                By.res(RES_PACKAGE_NAME, "done_button").text("Got it")), LONG_TIMEOUT);
+        if (gotIt != null) {
+            gotIt.click();
+        }
+    }
+}
diff --git a/tests/jank/sysapp/src/com/android/sysapp/janktests/ContactsJankTests.java b/tests/jank/sysapp/src/com/android/sysapp/janktests/ContactsJankTests.java
new file mode 100644
index 0000000..c83de69
--- /dev/null
+++ b/tests/jank/sysapp/src/com/android/sysapp/janktests/ContactsJankTests.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2015 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.sysapp.janktests;
+
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.provider.ContactsContract;
+import android.support.test.jank.GfxMonitor;
+import android.support.test.jank.JankTest;
+import android.support.test.jank.JankTestBase;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.Direction;
+import android.support.test.uiautomator.StaleObjectException;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.support.test.uiautomator.Until;
+import android.widget.TextView;
+
+import junit.framework.Assert;
+
+/**
+ * Jank test for Contacts
+ * open contact list and fling
+ */
+
+public class ContactsJankTests extends JankTestBase {
+    private static final int TIMEOUT = 5000;
+    private static final int SHORT_TIMEOUT = 1000;
+    private static final int INNER_LOOP = 5;
+    private static final int EXPECTED_FRAMES = 100;
+    private static final int MIN_CONTACT_COUNT = 75;
+    private static final String PACKAGE_NAME = "com.google.android.contacts";
+    private static final String RES_PACKAGE_NAME = "com.android.contacts";
+    private static final String PM_PACKAGE_NAME = "com.android.packageinstaller";
+    private UiDevice mDevice;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mDevice = UiDevice.getInstance(getInstrumentation());
+        mDevice.setOrientationNatural();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mDevice.unfreezeRotation();
+        super.tearDown();
+    }
+
+    public void launchApp(String packageName) throws UiObjectNotFoundException{
+        PackageManager pm = getInstrumentation().getContext().getPackageManager();
+        Intent appIntent = pm.getLaunchIntentForPackage(packageName);
+        appIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        getInstrumentation().getContext().startActivity(appIntent);
+        SystemClock.sleep(SHORT_TIMEOUT);
+    }
+
+    public void launchContacts () throws UiObjectNotFoundException {
+        launchApp(PACKAGE_NAME);
+        mDevice.waitForIdle();
+        // To infer that test is ready to be executed
+        Assert.assertNotNull("'All Contacts' not selected",
+                mDevice.wait(Until.findObject(By.clazz(TextView.class).selected(true)), TIMEOUT));
+        Assert.assertNotNull("Contacts list is not populated", mDevice.wait(Until.findObject(
+                By.res(RES_PACKAGE_NAME, "pinned_header_list_layout")), TIMEOUT));
+        Cursor cursor =  getInstrumentation().getContext().getContentResolver().query(
+                ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
+        Assert.assertTrue("There are not enough contacts", cursor.getCount() > MIN_CONTACT_COUNT);
+    }
+
+    // Measures jank while flinging contacts list
+    @JankTest(beforeTest="launchContacts", expectedFrames=EXPECTED_FRAMES)
+    @GfxMonitor(processName=PACKAGE_NAME)
+    public void testAllContactsFling() {
+        UiObject2 contactList = null;
+        for (int i = 0; i < INNER_LOOP; i++) {
+            contactList = mDevice.wait(Until.findObject(
+                    By.res(RES_PACKAGE_NAME, "pinned_header_list_layout")), TIMEOUT);
+            contactList.fling(Direction.DOWN);
+            SystemClock.sleep(100);
+            contactList.fling(Direction.UP);
+            SystemClock.sleep(100);
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/jank/sysapp/src/com/android/sysapp/janktests/GMailJankTests.java b/tests/jank/sysapp/src/com/android/sysapp/janktests/GMailJankTests.java
index c132a86..6bebc4f 100644
--- a/tests/jank/sysapp/src/com/android/sysapp/janktests/GMailJankTests.java
+++ b/tests/jank/sysapp/src/com/android/sysapp/janktests/GMailJankTests.java
@@ -26,10 +26,13 @@
 import android.support.test.uiautomator.By;
 import android.support.test.uiautomator.BySelector;
 import android.support.test.uiautomator.Direction;
+import android.support.test.uiautomator.StaleObjectException;
 import android.support.test.uiautomator.UiDevice;
 import android.support.test.uiautomator.UiObject2;
 import android.support.test.uiautomator.UiObjectNotFoundException;
 import android.support.test.uiautomator.Until;
+import android.widget.ImageButton;
+
 import junit.framework.Assert;
 
 /**
@@ -38,21 +41,19 @@
 
 public class GMailJankTests extends JankTestBase {
     private static final int SHORT_TIMEOUT = 1000;
-    private static final int LONG_TIMEOUT = 30000;
+    private static final int LONG_TIMEOUT = 5000;
     private static final int INNER_LOOP = 5;
     private static final int EXPECTED_FRAMES = 100;
+    private static final int TAB_MIN_WIDTH = 600;
     private static final String PACKAGE_NAME = "com.google.android.gm";
+    private static final String RES_PACKAGE_NAME = "android";
     private UiDevice mDevice;
 
     @Override
     public void setUp() throws Exception {
         super.setUp();
         mDevice = UiDevice.getInstance(getInstrumentation());
-        try {
-            mDevice.setOrientationNatural();
-        } catch (RemoteException e) {
-            throw new RuntimeException("failed to freeze device orientaion", e);
-        }
+        mDevice.setOrientationNatural();
     }
 
     @Override
@@ -76,28 +77,79 @@
         waitForEmailSync();
     }
 
+    public void prepGMailInboxFling() throws UiObjectNotFoundException {
+      launchGMail();
+      // Ensure test is ready to be executed
+      UiObject2 list = mDevice.wait(
+              Until.findObject(By.res(PACKAGE_NAME, "conversation_list_view")), SHORT_TIMEOUT);
+      Assert.assertNotNull("Failed to locate 'conversation_list_view'", list);
+    }
+
     // Measures jank while scrolling gmail inbox
-    @JankTest(beforeTest="launchGMail", expectedFrames=EXPECTED_FRAMES)
+    @JankTest(beforeTest="prepGMailInboxFling", expectedFrames=EXPECTED_FRAMES)
     @GfxMonitor(processName=PACKAGE_NAME)
     public void testGMailInboxFling() {
         UiObject2 list = mDevice.wait(
-                Until.findObject(By.res(PACKAGE_NAME, "conversation_list_view")), 5000);
-        Assert.assertNotNull("Failed to locate 'conversation_list_view", list);
+                Until.findObject(By.res(PACKAGE_NAME, "conversation_list_view")), LONG_TIMEOUT);
+        Assert.assertNotNull("Failed to locate 'conversation_list_view'", list);
         for (int i = 0; i < INNER_LOOP; i++) {
-          list.scroll(Direction.DOWN, 1.0f);
-          SystemClock.sleep(SHORT_TIMEOUT);
-          list.scroll(Direction.UP, 1.0f);
+            list.scroll(Direction.DOWN, 1.0f);
+            SystemClock.sleep(SHORT_TIMEOUT);
+            list.scroll(Direction.UP, 1.0f);
+            SystemClock.sleep(SHORT_TIMEOUT);
+        }
+    }
+
+    public void prepOpenNavDrawer() throws UiObjectNotFoundException {
+      launchGMail();
+      // Ensure test is ready to be executed
+      Assert.assertNotNull("Failed to locate Nav Drawer Openner", openNavigationDrawer());
+    }
+
+    // Measures jank while opening Navigation Drawer
+    @JankTest(beforeTest="prepOpenNavDrawer", expectedFrames=EXPECTED_FRAMES)
+    @GfxMonitor(processName=PACKAGE_NAME)
+    public void testOpenNavDrawer() {
+        UiObject2 navDrawer = openNavigationDrawer();
+        for (int i = 0; i < INNER_LOOP; i++) {
+            navDrawer.click();
+            SystemClock.sleep(SHORT_TIMEOUT);
+            mDevice.pressBack();
+            SystemClock.sleep(SHORT_TIMEOUT);
+        }
+    }
+
+    public void prepFlingNavDrawer() throws UiObjectNotFoundException{
+        launchGMail();
+        UiObject2 navDrawer = openNavigationDrawer();
+        Assert.assertNotNull("Failed to locate Nav Drawer Openner", navDrawer);
+        navDrawer.click();
+        // Ensure test is ready to be executed
+        UiObject2 container = getNavigationDrawerContainer();
+        Assert.assertNotNull("Failed to locate Nav drawer container", container);
+    }
+
+    // Measures jank while flinging Navigation Drawer
+    @JankTest(beforeTest="prepFlingNavDrawer", expectedFrames=EXPECTED_FRAMES)
+    @GfxMonitor(processName=PACKAGE_NAME)
+    public void testFlingNavDrawer() {
+        UiObject2 container = getNavigationDrawerContainer();
+        for (int i = 0; i < INNER_LOOP; i++) {
+            container.fling(Direction.DOWN);
+            SystemClock.sleep(SHORT_TIMEOUT);
+            container.fling(Direction.UP);
+            SystemClock.sleep(SHORT_TIMEOUT);
         }
     }
 
     private void dismissClings() {
         UiObject2 welcomeScreenGotIt = mDevice.wait(
-            Until.findObject(By.res(PACKAGE_NAME, "welcome_tour_got_it")), 2000);
+            Until.findObject(By.res(PACKAGE_NAME, "welcome_tour_got_it")), SHORT_TIMEOUT);
         if (welcomeScreenGotIt != null) {
             welcomeScreenGotIt.clickAndWait(Until.newWindow(), SHORT_TIMEOUT);
         }
         UiObject2 welcomeScreenSkip = mDevice.wait(
-            Until.findObject(By.res(PACKAGE_NAME, "welcome_tour_skip")), 2000);
+            Until.findObject(By.res(PACKAGE_NAME, "welcome_tour_skip")), SHORT_TIMEOUT);
         if (welcomeScreenSkip != null) {
           welcomeScreenSkip.clickAndWait(Until.newWindow(), SHORT_TIMEOUT);
         }
@@ -118,8 +170,32 @@
         mDevice.wait(Until.hasObject(By.text("Waiting for sync")), 2 * SHORT_TIMEOUT);
         // Wait until any "waiting" messages are gone
         Assert.assertTrue("'Waiting for sync' timed out",
-                mDevice.wait(Until.gone(By.text("Waiting for sync")), LONG_TIMEOUT));
+                mDevice.wait(Until.gone(By.text("Waiting for sync")), LONG_TIMEOUT * 6));
         Assert.assertTrue("'Loading' timed out",
-                mDevice.wait(Until.gone(By.text("Loading")), LONG_TIMEOUT));
+                mDevice.wait(Until.gone(By.text("Loading")), LONG_TIMEOUT * 6));
     }
-}
+
+    public UiObject2 openNavigationDrawer() {
+        UiObject2 navDrawer = null;
+        if (mDevice.getDisplaySizeDp().x < TAB_MIN_WIDTH) {
+            navDrawer = mDevice.wait(Until.findObject(
+                    By.clazz(ImageButton.class).desc("Navigate up")), SHORT_TIMEOUT);
+        } else {
+            navDrawer = mDevice.wait(Until.findObject(
+                    By.clazz(ImageButton.class).desc("Open navigation drawer")), SHORT_TIMEOUT);
+        }
+        return navDrawer;
+    }
+
+    public UiObject2 getNavigationDrawerContainer() {
+        UiObject2 container = null;
+        if (mDevice.getDisplaySizeDp().x < TAB_MIN_WIDTH) {
+            container = mDevice.wait(
+                    Until.findObject(By.res(RES_PACKAGE_NAME, "content_pane")), SHORT_TIMEOUT);
+        } else {
+            container = mDevice.wait(
+                    Until.findObject(By.res(RES_PACKAGE_NAME, "list")), SHORT_TIMEOUT);
+        }
+        return container;
+    }
+}
\ No newline at end of file