blob: 2551bb32dec28792be451a207651c938f01daa06 [file] [log] [blame]
/*
* Copyright 2019 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 androidx.camera.integration.core;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.isEnabled;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static junit.framework.TestCase.assertNotNull;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assume.assumeNotNull;
import static org.junit.Assume.assumeTrue;
import android.content.Intent;
import androidx.camera.core.CameraInfo;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.TorchState;
import androidx.camera.integration.core.idlingresource.ElapsedTimeIdlingResource;
import androidx.camera.integration.core.idlingresource.WaitForViewToShow;
import androidx.camera.testing.CameraUtil;
import androidx.camera.testing.CoreAppTestUtil;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.espresso.Espresso;
import androidx.test.espresso.IdlingRegistry;
import androidx.test.espresso.IdlingResource;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;
import androidx.test.rule.GrantPermissionRule;
import androidx.test.uiautomator.UiDevice;
import junit.framework.AssertionFailedError;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
/** Test toggle buttons in CoreTestApp. */
@RunWith(AndroidJUnit4.class)
@LargeTest
public final class ToggleButtonUITest {
private static final int IDLE_TIMEOUT_MS = 1000;
private static final String BASIC_SAMPLE_PACKAGE = "androidx.camera.integration.core";
private final UiDevice mDevice =
UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
private final Intent mIntent = ApplicationProvider.getApplicationContext().getPackageManager()
.getLaunchIntentForPackage(BASIC_SAMPLE_PACKAGE);
@Rule
public ActivityTestRule<CameraXActivity> mActivityRule =
new ActivityTestRule<>(CameraXActivity.class, true,
false);
@Rule
public TestRule mUseCamera = CameraUtil.grantCameraPermissionAndPreTest();
@Rule
public GrantPermissionRule mStoragePermissionRule =
GrantPermissionRule.grant(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
@Rule
public GrantPermissionRule mAudioPermissionRule =
GrantPermissionRule.grant(android.Manifest.permission.RECORD_AUDIO);
public static void waitFor(IdlingResource idlingResource) {
IdlingRegistry.getInstance().register(idlingResource);
Espresso.onIdle();
IdlingRegistry.getInstance().unregister(idlingResource);
}
@Before
public void setUp() throws CoreAppTestUtil.ForegroundOccupiedError {
assumeTrue(CameraUtil.deviceHasCamera());
CoreAppTestUtil.assumeCompatibleDevice();
// Clear the device UI and check if there is no dialog or lock screen on the top of the
// window before start the test.
CoreAppTestUtil.prepareDeviceUI(InstrumentationRegistry.getInstrumentation());
// Launch Activity
mActivityRule.launchActivity(mIntent);
}
@After
public void tearDown() {
// Idles Espresso thread and make activity complete each action.
waitFor(new ElapsedTimeIdlingResource(IDLE_TIMEOUT_MS));
mActivityRule.finishActivity();
// Returns to Home to restart next test.
mDevice.pressHome();
mDevice.waitForIdle(IDLE_TIMEOUT_MS);
}
@Test
public void testFlashToggleButton() {
waitFor(new WaitForViewToShow(R.id.constraintLayout));
assumeTrue(isButtonEnabled(R.id.flash_toggle));
ImageCapture useCase = mActivityRule.getActivity().getImageCapture();
assertNotNull(useCase);
// There are 3 different states of flash mode: ON, OFF and AUTO.
// By pressing flash mode toggle button, the flash mode would switch to the next state.
// The flash mode would loop in following sequence: OFF -> AUTO -> ON -> OFF.
@ImageCapture.FlashMode int mode1 = useCase.getFlashMode();
onView(withId(R.id.flash_toggle)).perform(click());
@ImageCapture.FlashMode int mode2 = useCase.getFlashMode();
// After the switch, the mode2 should be different from mode1.
assertNotEquals(mode2, mode1);
onView(withId(R.id.flash_toggle)).perform(click());
@ImageCapture.FlashMode int mode3 = useCase.getFlashMode();
// The mode3 should be different from first and second time.
assertNotEquals(mode3, mode2);
assertNotEquals(mode3, mode1);
}
@Test
public void testTorchToggleButton() {
waitFor(new WaitForViewToShow(R.id.constraintLayout));
assumeTrue(isButtonEnabled(R.id.torch_toggle));
CameraInfo cameraInfo = mActivityRule.getActivity().getCameraInfo();
assertNotNull(cameraInfo);
boolean isTorchOn = isTorchOn(cameraInfo);
onView(withId(R.id.torch_toggle)).perform(click());
assertNotEquals(isTorchOn(cameraInfo), isTorchOn);
// By pressing the torch toggle button two times, it should switch back to original state.
onView(withId(R.id.torch_toggle)).perform(click());
assertEquals(isTorchOn(cameraInfo), isTorchOn);
}
@Test
public void testSwitchCameraToggleButton() {
assumeTrue(CameraUtil.hasCameraWithLensFacing(CameraSelector.LENS_FACING_FRONT));
waitFor(new WaitForViewToShow(R.id.direction_toggle));
assumeNotNull(mActivityRule.getActivity().getPreview());
for (int i = 0; i < 5; i++) {
// Wait for preview update.
mActivityRule.getActivity().resetViewIdlingResource();
IdlingRegistry.getInstance().register(
mActivityRule.getActivity().getViewIdlingResource());
onView(withId(R.id.viewFinder)).check(matches(isDisplayed()));
IdlingRegistry.getInstance().unregister(
mActivityRule.getActivity().getViewIdlingResource());
onView(withId(R.id.direction_toggle)).perform(click());
}
}
private boolean isTorchOn(CameraInfo cameraInfo) {
return cameraInfo.getTorchState().getValue() == TorchState.ON;
}
private boolean isButtonEnabled(int resource) {
try {
onView(withId(resource)).check(matches(isEnabled()));
// View is in hierarchy
return true;
} catch (AssertionFailedError e) {
// View is not in hierarchy
return false;
} catch (Exception e) {
// View is not in hierarchy
return false;
}
}
}