leanback: fix NPE caused by late loading main fragment.

When main fragment is not created,  pressing RIGHT will NPE.
Also fixed sendKey in test.

Bug 30943877

Change-Id: I0b38de24c06a2b13206c9eede0fda857d3ab25fb
(cherry picked from commit 489c9a861b7cde47efcd5cf6351bc9696786ae41)
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java
index 6e8659b..e2cb22f8 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java
@@ -967,8 +967,10 @@
             } else if (direction == towardEnd) {
                 if (isVerticalScrolling()) {
                     return focused;
+                } else if (mMainFragment != null && mMainFragment.getView() != null) {
+                    return mMainFragment.getView();
                 }
-                return mMainFragment.getView();
+                return focused;
             } else if (direction == View.FOCUS_DOWN && mShowingHeaders) {
                 // disable focus_down moving into PageFragment.
                 return focused;
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BrowseSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BrowseSupportFragment.java
index f685469..5be65a7 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BrowseSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BrowseSupportFragment.java
@@ -969,8 +969,10 @@
             } else if (direction == towardEnd) {
                 if (isVerticalScrolling()) {
                     return focused;
+                } else if (mMainFragment != null && mMainFragment.getView() != null) {
+                    return mMainFragment.getView();
                 }
-                return mMainFragment.getView();
+                return focused;
             } else if (direction == View.FOCUS_DOWN && mShowingHeaders) {
                 // disable focus_down moving into PageFragment.
                 return focused;
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseFragmentTest.java
index e804a5a..8809861 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseFragmentTest.java
@@ -25,12 +25,14 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.espresso.action.ViewActions;
 import org.mockito.Mockito;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
@@ -53,11 +55,15 @@
 
     @Test
     public void testTwoBackKeysWithBackStack() throws Throwable {
+        final long dataLoadingDelay = 1000;
         Intent intent = new Intent();
-        intent.putExtra(BrowseFragmentTestActivity.EXTRA_LOAD_DATA_DELAY, (long) 1000);
+        intent.putExtra(BrowseFragmentTestActivity.EXTRA_LOAD_DATA_DELAY, dataLoadingDelay);
         intent.putExtra(BrowseFragmentTestActivity.EXTRA_ADD_TO_BACKSTACK , true);
         activityTestRule.launchActivity(intent);
 
+        Thread.sleep(dataLoadingDelay + TRANSITION_LENGTH);
+
+        assertNotNull(mActivity.getBrowseTestFragment().getMainFragment());
         sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
         Thread.sleep(TRANSITION_LENGTH);
         sendKeys(KeyEvent.KEYCODE_BACK, KeyEvent.KEYCODE_BACK);
@@ -65,17 +71,33 @@
 
     @Test
     public void testTwoBackKeysWithoutBackStack() throws Throwable {
+        final long dataLoadingDelay = 1000;
         Intent intent = new Intent();
-        intent.putExtra(BrowseFragmentTestActivity.EXTRA_LOAD_DATA_DELAY, (long) 1000);
+        intent.putExtra(BrowseFragmentTestActivity.EXTRA_LOAD_DATA_DELAY, dataLoadingDelay);
         intent.putExtra(BrowseFragmentTestActivity.EXTRA_ADD_TO_BACKSTACK , false);
         activityTestRule.launchActivity(intent);
 
+        Thread.sleep(dataLoadingDelay + TRANSITION_LENGTH);
+
+        assertNotNull(mActivity.getBrowseTestFragment().getMainFragment());
         sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
         Thread.sleep(TRANSITION_LENGTH);
         sendKeys(KeyEvent.KEYCODE_BACK, KeyEvent.KEYCODE_BACK);
     }
 
     @Test
+    public void testPressRightBeforeMainFragmentCreated() throws Throwable {
+        final long dataLoadingDelay = 1000;
+        Intent intent = new Intent();
+        intent.putExtra(BrowseFragmentTestActivity.EXTRA_LOAD_DATA_DELAY, dataLoadingDelay);
+        intent.putExtra(BrowseFragmentTestActivity.EXTRA_ADD_TO_BACKSTACK , false);
+        activityTestRule.launchActivity(intent);
+
+        assertNull(mActivity.getBrowseTestFragment().getMainFragment());
+        sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
+    }
+
+    @Test
     public void testSelectCardOnARow() throws Throwable {
         final int selectRow = 10;
         final int selectItem = 20;
@@ -110,7 +132,7 @@
 
     private void sendKeys(int ...keys) {
         for (int i = 0; i < keys.length; i++) {
-            ViewActions.pressKey(keys[i]);
+            InstrumentationRegistry.getInstrumentation().sendKeyDownUpSync(keys[i]);
         }
     }
 
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseSupportFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseSupportFragmentTest.java
index 1c007c6..14c5011 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseSupportFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseSupportFragmentTest.java
@@ -27,12 +27,14 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.espresso.action.ViewActions;
 import org.mockito.Mockito;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
@@ -55,11 +57,15 @@
 
     @Test
     public void testTwoBackKeysWithBackStack() throws Throwable {
+        final long dataLoadingDelay = 1000;
         Intent intent = new Intent();
-        intent.putExtra(BrowseSupportFragmentTestActivity.EXTRA_LOAD_DATA_DELAY, (long) 1000);
+        intent.putExtra(BrowseSupportFragmentTestActivity.EXTRA_LOAD_DATA_DELAY, dataLoadingDelay);
         intent.putExtra(BrowseSupportFragmentTestActivity.EXTRA_ADD_TO_BACKSTACK , true);
         activityTestRule.launchActivity(intent);
 
+        Thread.sleep(dataLoadingDelay + TRANSITION_LENGTH);
+
+        assertNotNull(mActivity.getBrowseTestSupportFragment().getMainFragment());
         sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
         Thread.sleep(TRANSITION_LENGTH);
         sendKeys(KeyEvent.KEYCODE_BACK, KeyEvent.KEYCODE_BACK);
@@ -67,17 +73,33 @@
 
     @Test
     public void testTwoBackKeysWithoutBackStack() throws Throwable {
+        final long dataLoadingDelay = 1000;
         Intent intent = new Intent();
-        intent.putExtra(BrowseSupportFragmentTestActivity.EXTRA_LOAD_DATA_DELAY, (long) 1000);
+        intent.putExtra(BrowseSupportFragmentTestActivity.EXTRA_LOAD_DATA_DELAY, dataLoadingDelay);
         intent.putExtra(BrowseSupportFragmentTestActivity.EXTRA_ADD_TO_BACKSTACK , false);
         activityTestRule.launchActivity(intent);
 
+        Thread.sleep(dataLoadingDelay + TRANSITION_LENGTH);
+
+        assertNotNull(mActivity.getBrowseTestSupportFragment().getMainFragment());
         sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
         Thread.sleep(TRANSITION_LENGTH);
         sendKeys(KeyEvent.KEYCODE_BACK, KeyEvent.KEYCODE_BACK);
     }
 
     @Test
+    public void testPressRightBeforeMainFragmentCreated() throws Throwable {
+        final long dataLoadingDelay = 1000;
+        Intent intent = new Intent();
+        intent.putExtra(BrowseSupportFragmentTestActivity.EXTRA_LOAD_DATA_DELAY, dataLoadingDelay);
+        intent.putExtra(BrowseSupportFragmentTestActivity.EXTRA_ADD_TO_BACKSTACK , false);
+        activityTestRule.launchActivity(intent);
+
+        assertNull(mActivity.getBrowseTestSupportFragment().getMainFragment());
+        sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
+    }
+
+    @Test
     public void testSelectCardOnARow() throws Throwable {
         final int selectRow = 10;
         final int selectItem = 20;
@@ -112,7 +134,7 @@
 
     private void sendKeys(int ...keys) {
         for (int i = 0; i < keys.length; i++) {
-            ViewActions.pressKey(keys[i]);
+            InstrumentationRegistry.getInstrumentation().sendKeyDownUpSync(keys[i]);
         }
     }