TestUtils.java revision b86bef286718da421268bc52cf4fab7cccb3104c
1b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets/* 264db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar * Copyright (C) 2017 The Android Open Source Project 3b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets * 4b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets * Licensed under the Apache License, Version 2.0 (the "License"); 5b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets * you may not use this file except in compliance with the License. 6b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets * You may obtain a copy of the License at 7b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets * 8b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets * http://www.apache.org/licenses/LICENSE-2.0 9b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets * 10b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets * Unless required by applicable law or agreed to in writing, software 11b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets * distributed under the License is distributed on an "AS IS" BASIS, 12b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets * See the License for the specific language governing permissions and 14b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets * limitations under the License. 15b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets */ 16b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets 1764db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarpackage android.arch.lifecycle; 18b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets 191f52c94781fdc0d8aefbaa697bb8b52e18badcd5Sergey Vasilinetsimport android.app.Activity; 20b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinetsimport android.app.Instrumentation; 21b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinetsimport android.app.Instrumentation.ActivityMonitor; 22b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinetsimport android.support.test.InstrumentationRegistry; 23450ed382339544eaf6b7886bc765522fc3446148Yigit Boyarimport android.support.test.rule.ActivityTestRule; 24b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets 258524c13c97e2c80d270b03f97f8eac5fbd585c5aSergey Vasilinetsimport java.util.concurrent.CountDownLatch; 268524c13c97e2c80d270b03f97f8eac5fbd585c5aSergey Vasilinets 27b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinetspublic class TestUtils { 28b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets 29b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets private static final long TIMEOUT_MS = 2000; 30b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets 311f52c94781fdc0d8aefbaa697bb8b52e18badcd5Sergey Vasilinets @SuppressWarnings("unchecked") 32450ed382339544eaf6b7886bc765522fc3446148Yigit Boyar public static <T extends Activity> T recreateActivity(final T activity, ActivityTestRule rule) 33b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets throws Throwable { 34b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets ActivityMonitor monitor = new ActivityMonitor( 351f52c94781fdc0d8aefbaa697bb8b52e18badcd5Sergey Vasilinets activity.getClass().getCanonicalName(), null, false); 36b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); 37b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets instrumentation.addMonitor(monitor); 381f52c94781fdc0d8aefbaa697bb8b52e18badcd5Sergey Vasilinets rule.runOnUiThread(activity::recreate); 391f52c94781fdc0d8aefbaa697bb8b52e18badcd5Sergey Vasilinets T result; 40ede4592947eadcab982f71b186dd9debd52e84ccSergey Vasilinets 41ede4592947eadcab982f71b186dd9debd52e84ccSergey Vasilinets // this guarantee that we will reinstall monitor between notifications about onDestroy 42ede4592947eadcab982f71b186dd9debd52e84ccSergey Vasilinets // and onCreate 431f52c94781fdc0d8aefbaa697bb8b52e18badcd5Sergey Vasilinets //noinspection SynchronizationOnLocalVariableOrMethodParameter 44ede4592947eadcab982f71b186dd9debd52e84ccSergey Vasilinets synchronized (monitor) { 45ede4592947eadcab982f71b186dd9debd52e84ccSergey Vasilinets do { 46ede4592947eadcab982f71b186dd9debd52e84ccSergey Vasilinets // the documetation says "Block until an Activity is created 47ede4592947eadcab982f71b186dd9debd52e84ccSergey Vasilinets // that matches this monitor." This statement is true, but there are some other 48ede4592947eadcab982f71b186dd9debd52e84ccSergey Vasilinets // true statements like: "Block until an Activity is destoyed" or 49ede4592947eadcab982f71b186dd9debd52e84ccSergey Vasilinets // "Block until an Activity is resumed"... 50ede4592947eadcab982f71b186dd9debd52e84ccSergey Vasilinets 51ede4592947eadcab982f71b186dd9debd52e84ccSergey Vasilinets // this call will release synchronization monitor's monitor 521f52c94781fdc0d8aefbaa697bb8b52e18badcd5Sergey Vasilinets result = (T) monitor.waitForActivityWithTimeout(TIMEOUT_MS); 53ede4592947eadcab982f71b186dd9debd52e84ccSergey Vasilinets if (result == null) { 54ede4592947eadcab982f71b186dd9debd52e84ccSergey Vasilinets throw new RuntimeException("Timeout. Failed to recreate an activity"); 55ede4592947eadcab982f71b186dd9debd52e84ccSergey Vasilinets } 56ede4592947eadcab982f71b186dd9debd52e84ccSergey Vasilinets } while (result == activity); 57b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets } 58b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets return result; 59b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets } 608524c13c97e2c80d270b03f97f8eac5fbd585c5aSergey Vasilinets 618524c13c97e2c80d270b03f97f8eac5fbd585c5aSergey Vasilinets static void waitTillResumed(final LifecycleActivity a, ActivityTestRule<?> activityRule) 628524c13c97e2c80d270b03f97f8eac5fbd585c5aSergey Vasilinets throws Throwable { 638524c13c97e2c80d270b03f97f8eac5fbd585c5aSergey Vasilinets final CountDownLatch latch = new CountDownLatch(1); 648524c13c97e2c80d270b03f97f8eac5fbd585c5aSergey Vasilinets activityRule.runOnUiThread(() -> { 658524c13c97e2c80d270b03f97f8eac5fbd585c5aSergey Vasilinets int currentState = a.getLifecycle().getCurrentState(); 668524c13c97e2c80d270b03f97f8eac5fbd585c5aSergey Vasilinets if (currentState == Lifecycle.RESUMED) { 678524c13c97e2c80d270b03f97f8eac5fbd585c5aSergey Vasilinets latch.countDown(); 688524c13c97e2c80d270b03f97f8eac5fbd585c5aSergey Vasilinets } 698524c13c97e2c80d270b03f97f8eac5fbd585c5aSergey Vasilinets a.getLifecycle().addObserver(new LifecycleObserver() { 70b86bef286718da421268bc52cf4fab7cccb3104cSergey Vasilinets @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) 71e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets public void onStateChanged(LifecycleOwner provider) { 728524c13c97e2c80d270b03f97f8eac5fbd585c5aSergey Vasilinets latch.countDown(); 738524c13c97e2c80d270b03f97f8eac5fbd585c5aSergey Vasilinets provider.getLifecycle().removeObserver(this); 748524c13c97e2c80d270b03f97f8eac5fbd585c5aSergey Vasilinets } 758524c13c97e2c80d270b03f97f8eac5fbd585c5aSergey Vasilinets }); 768524c13c97e2c80d270b03f97f8eac5fbd585c5aSergey Vasilinets }); 778524c13c97e2c80d270b03f97f8eac5fbd585c5aSergey Vasilinets latch.await(); 788524c13c97e2c80d270b03f97f8eac5fbd585c5aSergey Vasilinets } 798524c13c97e2c80d270b03f97f8eac5fbd585c5aSergey Vasilinets 80b085e34beddf631062d0e2503911ef4a33152c06Sergey Vasilinets} 81