1/* 2 * Copyright 2018 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 */ 16package androidx.fragment.app; 17 18import static org.junit.Assert.assertEquals; 19import static org.junit.Assert.assertTrue; 20import static org.junit.Assert.fail; 21import static org.mockito.ArgumentMatchers.eq; 22import static org.mockito.ArgumentMatchers.same; 23import static org.mockito.Mockito.mock; 24import static org.mockito.Mockito.verify; 25import static org.mockito.Mockito.verifyNoMoreInteractions; 26 27import android.app.Activity; 28import android.app.PendingIntent; 29import android.content.Intent; 30import android.content.IntentSender; 31import android.support.test.InstrumentationRegistry; 32import android.support.test.filters.SmallTest; 33import android.support.test.rule.ActivityTestRule; 34import android.support.test.runner.AndroidJUnit4; 35 36import androidx.core.app.ActivityCompat; 37import androidx.fragment.app.test.FragmentResultActivity; 38import androidx.fragment.app.test.FragmentTestActivity; 39import androidx.fragment.test.R; 40 41import org.junit.Before; 42import org.junit.Rule; 43import org.junit.Test; 44import org.junit.runner.RunWith; 45 46import java.util.concurrent.CountDownLatch; 47import java.util.concurrent.TimeUnit; 48 49/** 50 * Tests for Fragment startActivityForResult and startIntentSenderForResult. 51 */ 52@RunWith(AndroidJUnit4.class) 53public class FragmentReceiveResultTest { 54 @Rule 55 public ActivityTestRule<FragmentTestActivity> mActivityRule = 56 new ActivityTestRule<FragmentTestActivity>(FragmentTestActivity.class); 57 58 private FragmentTestActivity mActivity; 59 private TestFragment mFragment; 60 61 62 @Before 63 public void setup() throws Throwable { 64 mActivity = mActivityRule.getActivity(); 65 mFragment = attachTestFragment(); 66 } 67 68 @Test 69 @SmallTest 70 public void testStartActivityForResultOk() throws Throwable { 71 startActivityForResult(10, Activity.RESULT_OK, "content 10"); 72 73 assertTrue("Fragment should receive result", mFragment.mHasResult); 74 assertEquals(10, mFragment.mRequestCode); 75 assertEquals(Activity.RESULT_OK, mFragment.mResultCode); 76 assertEquals("content 10", mFragment.mResultContent); 77 } 78 79 @Test 80 @SmallTest 81 public void testStartActivityForResultCanceled() throws Throwable { 82 startActivityForResult(20, Activity.RESULT_CANCELED, "content 20"); 83 84 assertTrue("Fragment should receive result", mFragment.mHasResult); 85 assertEquals(20, mFragment.mRequestCode); 86 assertEquals(Activity.RESULT_CANCELED, mFragment.mResultCode); 87 assertEquals("content 20", mFragment.mResultContent); 88 } 89 90 @Test 91 @SmallTest 92 public void testStartIntentSenderForResultOk() throws Throwable { 93 startIntentSenderForResult(30, Activity.RESULT_OK, "content 30"); 94 95 assertTrue("Fragment should receive result", mFragment.mHasResult); 96 assertEquals(30, mFragment.mRequestCode); 97 assertEquals(Activity.RESULT_OK, mFragment.mResultCode); 98 assertEquals("content 30", mFragment.mResultContent); 99 } 100 101 @Test 102 @SmallTest 103 public void testStartIntentSenderForResultCanceled() throws Throwable { 104 startIntentSenderForResult(40, Activity.RESULT_CANCELED, "content 40"); 105 106 assertTrue("Fragment should receive result", mFragment.mHasResult); 107 assertEquals(40, mFragment.mRequestCode); 108 assertEquals(Activity.RESULT_CANCELED, mFragment.mResultCode); 109 assertEquals("content 40", mFragment.mResultContent); 110 } 111 112 @Test 113 @SmallTest 114 public void testActivityResult_withDelegate() { 115 ActivityCompat.PermissionCompatDelegate 116 delegate = mock(ActivityCompat.PermissionCompatDelegate.class); 117 118 Intent data = new Intent(); 119 ActivityCompat.setPermissionCompatDelegate(delegate); 120 121 mActivityRule.getActivity().onActivityResult(42, 43, data); 122 123 verify(delegate).onActivityResult(same(mActivityRule.getActivity()), eq(42), eq(43), 124 same(data)); 125 126 ActivityCompat.setPermissionCompatDelegate(null); 127 mActivityRule.getActivity().onActivityResult(42, 43, data); 128 verifyNoMoreInteractions(delegate); 129 } 130 131 private TestFragment attachTestFragment() throws Throwable { 132 final TestFragment fragment = new TestFragment(); 133 mActivityRule.runOnUiThread(new Runnable() { 134 @Override 135 public void run() { 136 mActivity.getSupportFragmentManager().beginTransaction() 137 .add(R.id.content, fragment) 138 .addToBackStack(null) 139 .commitAllowingStateLoss(); 140 mActivity.getFragmentManager().executePendingTransactions(); 141 } 142 }); 143 InstrumentationRegistry.getInstrumentation().waitForIdleSync(); 144 return fragment; 145 } 146 147 private void startActivityForResult(final int requestCode, final int resultCode, 148 final String content) throws Throwable { 149 mActivityRule.runOnUiThread(new Runnable() { 150 @Override 151 public void run() { 152 Intent intent = new Intent(mActivity, FragmentResultActivity.class); 153 intent.putExtra(FragmentResultActivity.EXTRA_RESULT_CODE, resultCode); 154 intent.putExtra(FragmentResultActivity.EXTRA_RESULT_CONTENT, content); 155 156 mFragment.startActivityForResult(intent, requestCode); 157 } 158 }); 159 assertTrue(mFragment.mResultReceiveLatch.await(1, TimeUnit.SECONDS)); 160 InstrumentationRegistry.getInstrumentation().waitForIdleSync(); 161 } 162 163 private void startIntentSenderForResult(final int requestCode, final int resultCode, 164 final String content) throws Throwable { 165 mActivityRule.runOnUiThread(new Runnable() { 166 @Override 167 public void run() { 168 Intent intent = new Intent(mActivity, FragmentResultActivity.class); 169 intent.putExtra(FragmentResultActivity.EXTRA_RESULT_CODE, resultCode); 170 intent.putExtra(FragmentResultActivity.EXTRA_RESULT_CONTENT, content); 171 172 PendingIntent pendingIntent = PendingIntent.getActivity(mActivity, 173 requestCode, intent, 0); 174 175 try { 176 mFragment.startIntentSenderForResult(pendingIntent.getIntentSender(), 177 requestCode, null, 0, 0, 0, null); 178 } catch (IntentSender.SendIntentException e) { 179 fail("IntentSender failed"); 180 } 181 } 182 }); 183 assertTrue(mFragment.mResultReceiveLatch.await(1, TimeUnit.SECONDS)); 184 InstrumentationRegistry.getInstrumentation().waitForIdleSync(); 185 } 186 187 public static class TestFragment extends Fragment { 188 boolean mHasResult = false; 189 int mRequestCode = -1; 190 int mResultCode = 100; 191 String mResultContent; 192 final CountDownLatch mResultReceiveLatch = new CountDownLatch(1); 193 194 @Override 195 public void onActivityResult(int requestCode, int resultCode, Intent data) { 196 mHasResult = true; 197 mRequestCode = requestCode; 198 mResultCode = resultCode; 199 mResultContent = data.getStringExtra(FragmentResultActivity.EXTRA_RESULT_CONTENT); 200 mResultReceiveLatch.countDown(); 201 } 202 } 203} 204