Commit beb10501 authored by Scott Violet's avatar Scott Violet Committed by Commit Bot

weblayer: merge browser control related tests

This renames BottomControlsTest to BrowserControlsTest and
adds the top-control ones. Given how finicky these are it seems
best to conslidate them and share as much code as possible.

BUG=1074438,1077825
TEST=test only changes

Change-Id: I4f6544e93921688da78028e212c9ed3f530082b4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2216383Reviewed-by: default avatarBo <boliu@chromium.org>
Commit-Queue: Scott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#771967}
parent ea1c1a76
...@@ -61,7 +61,7 @@ android_library("weblayer_java_tests") { ...@@ -61,7 +61,7 @@ android_library("weblayer_java_tests") {
android_library("weblayer_private_java_tests") { android_library("weblayer_private_java_tests") {
testonly = true testonly = true
sources = [ sources = [
"src/org/chromium/weblayer/test/BottomControlsTest.java", "src/org/chromium/weblayer/test/BrowserControlsTest.java",
"src/org/chromium/weblayer/test/GeolocationTest.java", "src/org/chromium/weblayer/test/GeolocationTest.java",
"src/org/chromium/weblayer/test/MediaCaptureTest.java", "src/org/chromium/weblayer/test/MediaCaptureTest.java",
"src/org/chromium/weblayer/test/NetworkChangeNotifierTest.java", "src/org/chromium/weblayer/test/NetworkChangeNotifierTest.java",
......
...@@ -11,14 +11,14 @@ import android.view.View; ...@@ -11,14 +11,14 @@ import android.view.View;
import android.widget.TextView; import android.widget.TextView;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.chromium.base.test.util.CallbackHelper;
import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.MinAndroidSdkLevel; import org.chromium.base.test.util.MinAndroidSdkLevel;
import org.chromium.base.test.util.UrlUtils;
import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.Criteria;
import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.content_public.browser.test.util.CriteriaHelper;
import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils;
...@@ -30,15 +30,15 @@ import org.chromium.weblayer.shell.InstrumentationActivity; ...@@ -30,15 +30,15 @@ import org.chromium.weblayer.shell.InstrumentationActivity;
*/ */
@RunWith(WebLayerJUnit4ClassRunner.class) @RunWith(WebLayerJUnit4ClassRunner.class)
@CommandLineFlags.Add("enable-features=ImmediatelyHideBrowserControlsForTest") @CommandLineFlags.Add("enable-features=ImmediatelyHideBrowserControlsForTest")
public class BottomControlsTest { public class BrowserControlsTest {
@Rule @Rule
public InstrumentationActivityTestRule mActivityTestRule = public InstrumentationActivityTestRule mActivityTestRule =
new InstrumentationActivityTestRule(); new InstrumentationActivityTestRule();
private int mMaxControlsHeight; // Height of the top-view. Set in setUp().
private int mTopControlsHeight; private int mTopViewHeight;
private int mBottomControlsHeight; // Height from the page (obtained using getVisiblePageHeight()) with the top-controls.
private int mInitialVisiblePageHeight; private int mPageHeightWithTopView;
/** /**
* Returns the visible height of the page as determined by JS. The returned value is in CSS * Returns the visible height of the page as determined by JS. The returned value is in CSS
...@@ -58,40 +58,43 @@ public class BottomControlsTest { ...@@ -58,40 +58,43 @@ public class BottomControlsTest {
// See TestWebLayer.waitForBrowserControlsMetadataState() for details on this. // See TestWebLayer.waitForBrowserControlsMetadataState() for details on this.
private void waitForBrowserControlsMetadataState( private void waitForBrowserControlsMetadataState(
InstrumentationActivity activity, int top, int bottom) throws Exception { InstrumentationActivity activity, int top, int bottom) throws Exception {
BoundedCountDownLatch latch = new BoundedCountDownLatch(1); CallbackHelper helper = new CallbackHelper();
TestThreadUtils.runOnUiThreadBlocking(() -> { TestThreadUtils.runOnUiThreadBlocking(() -> {
try { try {
TestWebLayer.getTestWebLayer(activity.getApplicationContext()) TestWebLayer.getTestWebLayer(activity.getApplicationContext())
.waitForBrowserControlsMetadataState(activity.getBrowser().getActiveTab(), .waitForBrowserControlsMetadataState(activity.getBrowser().getActiveTab(),
top, bottom, () -> { latch.countDown(); }); top, bottom, () -> { helper.notifyCalled(); });
} catch (RemoteException e) { } catch (RemoteException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
}); });
latch.timedAwait(); helper.waitForCallback(0);
} }
// Disabled on L bots due to unexplained flakes. See crbug.com/1035894. @Before
@MinAndroidSdkLevel(Build.VERSION_CODES.M) public void setUp() throws Throwable {
@Test
@SmallTest
public void testBasic() throws Exception {
final String url = mActivityTestRule.getTestDataURL("tall_page.html"); final String url = mActivityTestRule.getTestDataURL("tall_page.html");
InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl(url); InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl(url);
// Poll until the top view becomes visible. // Poll until the top view becomes visible.
waitForBrowserControlsViewToBeVisible(activity.getTopContentsContainer()); waitForBrowserControlsViewToBeVisible(activity.getTopContentsContainer());
TestThreadUtils.runOnUiThreadBlocking(() -> { TestThreadUtils.runOnUiThreadBlocking(() -> {
mMaxControlsHeight = mTopControlsHeight = mTopViewHeight = activity.getTopContentsContainer().getHeight();
activity.getTopContentsContainer().getHeight(); Assert.assertTrue(mTopViewHeight > 0);
Assert.assertTrue(mMaxControlsHeight > 0);
}); });
// Wait for cc to see the top-controls height. // Wait for cc to see the top-controls height.
waitForBrowserControlsMetadataState(activity, mTopControlsHeight, 0); waitForBrowserControlsMetadataState(activity, mTopViewHeight, 0);
int pageHeightWithTopView = getVisiblePageHeight(); mPageHeightWithTopView = getVisiblePageHeight();
}
// Disabled on L bots due to unexplained flakes. See crbug.com/1035894.
@MinAndroidSdkLevel(Build.VERSION_CODES.M)
@Test
@SmallTest
public void testTopAndBottom() throws Exception {
InstrumentationActivity activity = mActivityTestRule.getActivity();
View bottomView = TestThreadUtils.runOnUiThreadBlocking(() -> { View bottomView = TestThreadUtils.runOnUiThreadBlocking(() -> {
TextView view = new TextView(activity); TextView view = new TextView(activity);
view.setText("BOTTOM"); view.setText("BOTTOM");
...@@ -101,37 +104,36 @@ public class BottomControlsTest { ...@@ -101,37 +104,36 @@ public class BottomControlsTest {
waitForBrowserControlsViewToBeVisible(bottomView); waitForBrowserControlsViewToBeVisible(bottomView);
TestThreadUtils.runOnUiThreadBlocking(() -> { int bottomViewHeight =
// The amount necessary to scroll is the sum of the two views. This is because the page TestThreadUtils.runOnUiThreadBlocking(() -> { return bottomView.getHeight(); });
// height is reduced by the sum of these two. Assert.assertTrue(bottomViewHeight > 0);
mBottomControlsHeight = bottomView.getHeight(); // The amount necessary to scroll is the sum of the two views. This is because the page
Assert.assertTrue(mBottomControlsHeight > 0); // height is reduced by the sum of these two.
mMaxControlsHeight += mBottomControlsHeight; int maxViewsHeight = mTopViewHeight + bottomViewHeight;
});
// Wait for cc to see the bottom height. This is very important, as scrolling is gated by // Wait for cc to see the bottom height. This is very important, as scrolling is gated by
// cc getting the bottom height. // cc getting the bottom height.
waitForBrowserControlsMetadataState(activity, mTopControlsHeight, mBottomControlsHeight); waitForBrowserControlsMetadataState(activity, mTopViewHeight, bottomViewHeight);
// Adding a bottom view should change the page height. // Adding a bottom view should change the page height.
CriteriaHelper.pollInstrumentationThread( CriteriaHelper.pollInstrumentationThread(
() -> Assert.assertNotEquals(getVisiblePageHeight(), pageHeightWithTopView)); () -> Assert.assertNotEquals(getVisiblePageHeight(), mPageHeightWithTopView));
int pageHeightWithTopAndBottomViews = getVisiblePageHeight(); int pageHeightWithTopAndBottomViews = getVisiblePageHeight();
Assert.assertTrue(pageHeightWithTopAndBottomViews < pageHeightWithTopView); Assert.assertTrue(pageHeightWithTopAndBottomViews < mPageHeightWithTopView);
// Move by the size of the controls. // Move by the size of the controls.
EventUtils.simulateDragFromCenterOfView( EventUtils.simulateDragFromCenterOfView(
activity.getWindow().getDecorView(), 0, -mMaxControlsHeight); activity.getWindow().getDecorView(), 0, -maxViewsHeight);
// Moving should hide the bottom View. // Moving should hide the bottom View.
CriteriaHelper.pollUiThread( CriteriaHelper.pollUiThread(
Criteria.equals(View.INVISIBLE, () -> bottomView.getVisibility())); Criteria.equals(View.INVISIBLE, () -> bottomView.getVisibility()));
CriteriaHelper.pollInstrumentationThread( CriteriaHelper.pollInstrumentationThread(
Criteria.equals(true, () -> getVisiblePageHeight() > pageHeightWithTopView)); Criteria.equals(true, () -> getVisiblePageHeight() > mPageHeightWithTopView));
// Move so top and bottom-controls are shown again. // Move so top and bottom-controls are shown again.
EventUtils.simulateDragFromCenterOfView( EventUtils.simulateDragFromCenterOfView(
activity.getWindow().getDecorView(), 0, mMaxControlsHeight); activity.getWindow().getDecorView(), 0, maxViewsHeight);
waitForBrowserControlsViewToBeVisible(bottomView); waitForBrowserControlsViewToBeVisible(bottomView);
CriteriaHelper.pollInstrumentationThread( CriteriaHelper.pollInstrumentationThread(
...@@ -142,30 +144,16 @@ public class BottomControlsTest { ...@@ -142,30 +144,16 @@ public class BottomControlsTest {
@MinAndroidSdkLevel(Build.VERSION_CODES.M) @MinAndroidSdkLevel(Build.VERSION_CODES.M)
@Test @Test
@SmallTest @SmallTest
@DisabledTest public void testBottomOnly() throws Exception {
public void testNoTopControl() throws Exception { InstrumentationActivity activity = mActivityTestRule.getActivity();
final String url = UrlUtils.encodeHtmlDataUri("<body><p style='height:5000px'>"); // Remove the top-view.
InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl(url);
// Poll until the top view becomes visible.
CriteriaHelper.pollUiThread(Criteria.equals(
View.VISIBLE, () -> activity.getTopContentsContainer().getVisibility()));
// Get the size of the page.
mInitialVisiblePageHeight = getVisiblePageHeight();
Assert.assertTrue(mInitialVisiblePageHeight > 0);
// Swap out the top-view.
TestThreadUtils.runOnUiThreadBlocking(() -> { activity.getBrowser().setTopView(null); }); TestThreadUtils.runOnUiThreadBlocking(() -> { activity.getBrowser().setTopView(null); });
// Wait for the size of the page to change. Don't attempt to correlate the size as the // Wait for cc to see the top-controls height change.
// page doesn't see pixels, and to attempt to compare may result in rounding errors. Poll waitForBrowserControlsMetadataState(activity, 0, 0);
// for this value as there is no good way to detect when done.
CriteriaHelper.pollInstrumentationThread(
() -> Assert.assertNotEquals(mInitialVisiblePageHeight, getVisiblePageHeight()));
// Reset mInitialVisiblePageHeight as the top-view is no longer present. int pageHeightWithNoTopView = getVisiblePageHeight();
mInitialVisiblePageHeight = getVisiblePageHeight(); Assert.assertNotEquals(pageHeightWithNoTopView, mPageHeightWithTopView);
// Add in the bottom-view. // Add in the bottom-view.
View bottomView = TestThreadUtils.runOnUiThreadBlocking(() -> { View bottomView = TestThreadUtils.runOnUiThreadBlocking(() -> {
...@@ -175,41 +163,89 @@ public class BottomControlsTest { ...@@ -175,41 +163,89 @@ public class BottomControlsTest {
return view; return view;
}); });
// Poll until the bottom view becomes visible. waitForBrowserControlsViewToBeVisible(bottomView);
CriteriaHelper.pollUiThread( int bottomViewHeight =
Criteria.equals(View.VISIBLE, () -> bottomView.getVisibility())); TestThreadUtils.runOnUiThreadBlocking(() -> { return bottomView.getHeight(); });
TestThreadUtils.runOnUiThreadBlocking(() -> { Assert.assertTrue(bottomViewHeight > 0);
mMaxControlsHeight = bottomView.getHeight(); // Wait for cc to see the bottom-controls height change.
Assert.assertTrue(mMaxControlsHeight > 0); waitForBrowserControlsMetadataState(activity, 0, bottomViewHeight);
});
CriteriaHelper.pollInstrumentationThread( int pageHeightWithBottomView = getVisiblePageHeight();
() -> Assert.assertNotEquals(mInitialVisiblePageHeight, getVisiblePageHeight())); Assert.assertNotEquals(pageHeightWithNoTopView, pageHeightWithBottomView);
// Move by the size of the bottom-controls. // Move by the size of the bottom-controls.
EventUtils.simulateDragFromCenterOfView( EventUtils.simulateDragFromCenterOfView(
activity.getWindow().getDecorView(), 0, -mMaxControlsHeight); activity.getWindow().getDecorView(), 0, -bottomViewHeight);
// Moving should hide the bottom-controls View. // Moving should hide the bottom-controls View.
CriteriaHelper.pollUiThread( CriteriaHelper.pollUiThread(
Criteria.equals(View.INVISIBLE, () -> bottomView.getVisibility())); Criteria.equals(View.INVISIBLE, () -> bottomView.getVisibility()));
// Moving should change the size of the page. Don't attempt to correlate the size as the
// page doesn't see pixels, and to attempt to compare may result in rounding errors. Poll
// for this value as there is no good way to detect when done.
CriteriaHelper.pollInstrumentationThread( CriteriaHelper.pollInstrumentationThread(
Criteria.equals(mInitialVisiblePageHeight, this::getVisiblePageHeight)); Criteria.equals(pageHeightWithNoTopView, () -> getVisiblePageHeight()));
// Move so bottom-controls are shown again. // Move so bottom-controls are shown again.
EventUtils.simulateDragFromCenterOfView( EventUtils.simulateDragFromCenterOfView(
activity.getWindow().getDecorView(), 0, mMaxControlsHeight); activity.getWindow().getDecorView(), 0, bottomViewHeight);
// bottom-controls are shown async. waitForBrowserControlsViewToBeVisible(bottomView);
CriteriaHelper.pollUiThread( CriteriaHelper.pollInstrumentationThread(
Criteria.equals(View.VISIBLE, () -> bottomView.getVisibility())); () -> Assert.assertEquals(getVisiblePageHeight(), pageHeightWithBottomView));
}
// Disabled on L bots due to unexplained flakes. See crbug.com/1035894.
@MinAndroidSdkLevel(Build.VERSION_CODES.M)
@Test
@SmallTest
public void testTopOnly() throws Exception {
InstrumentationActivity activity = mActivityTestRule.getActivity();
View topView = activity.getTopContentsContainer();
// Move by the size of the top-controls.
EventUtils.simulateDragFromCenterOfView(
activity.getWindow().getDecorView(), 0, -mTopViewHeight);
// Moving should hide the top-controls and change the page height.
CriteriaHelper.pollUiThread(Criteria.equals(View.INVISIBLE, () -> topView.getVisibility()));
CriteriaHelper.pollInstrumentationThread(
() -> Assert.assertNotEquals(getVisiblePageHeight(), mPageHeightWithTopView));
// Move so top-controls are shown again.
EventUtils.simulateDragFromCenterOfView(
activity.getWindow().getDecorView(), 0, mTopViewHeight);
// Wait for the page height to match initial height. // Wait for the page height to match initial height.
waitForBrowserControlsViewToBeVisible(topView);
CriteriaHelper.pollInstrumentationThread( CriteriaHelper.pollInstrumentationThread(
() -> Assert.assertNotEquals(mInitialVisiblePageHeight, getVisiblePageHeight())); () -> Assert.assertEquals(getVisiblePageHeight(), mPageHeightWithTopView));
}
/**
* Makes sure that the top controls are shown when a js dialog is shown.
*
* Regression test for https://crbug.com/1078181.
*
* Disabled on L bots due to unexplained flakes. See crbug.com/1035894.
*/
@MinAndroidSdkLevel(Build.VERSION_CODES.M)
@Test
@SmallTest
public void testAlertShowsTopControls() throws Exception {
InstrumentationActivity activity = mActivityTestRule.getActivity();
// Move by the size of the top-controls.
EventUtils.simulateDragFromCenterOfView(
activity.getWindow().getDecorView(), 0, -mTopViewHeight);
// Wait till top controls are invisible.
CriteriaHelper.pollUiThread(Criteria.equals(
View.INVISIBLE, () -> activity.getTopContentsContainer().getVisibility()));
// Trigger an alert dialog.
mActivityTestRule.executeScriptSync(
"window.setTimeout(function() { alert('alert'); }, 1);", false);
// Top controls are shown.
CriteriaHelper.pollUiThread(Criteria.equals(
View.VISIBLE, () -> activity.getTopContentsContainer().getVisibility()));
} }
} }
...@@ -4,25 +4,18 @@ ...@@ -4,25 +4,18 @@
package org.chromium.weblayer.test; package org.chromium.weblayer.test;
import android.os.Build;
import android.support.test.filters.SmallTest; import android.support.test.filters.SmallTest;
import android.view.View;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import org.junit.Assert;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CallbackHelper;
import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.FlakyTest;
import org.chromium.base.test.util.MinAndroidSdkLevel;
import org.chromium.base.test.util.UrlUtils; import org.chromium.base.test.util.UrlUtils;
import org.chromium.content_public.browser.test.util.Criteria;
import org.chromium.content_public.browser.test.util.CriteriaHelper;
import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.weblayer.Browser; import org.chromium.weblayer.Browser;
import org.chromium.weblayer.Tab; import org.chromium.weblayer.Tab;
...@@ -39,19 +32,9 @@ public class TopControlsTest { ...@@ -39,19 +32,9 @@ public class TopControlsTest {
public InstrumentationActivityTestRule mActivityTestRule = public InstrumentationActivityTestRule mActivityTestRule =
new InstrumentationActivityTestRule(); new InstrumentationActivityTestRule();
private int mTopControlsHeight;
private int mInitialVisiblePageHeight;
private Tab mTab; private Tab mTab;
private Browser mBrowser; private Browser mBrowser;
/**
* Returns the visible height of the page as determined by JS. The returned value is in CSS
* pixels (which are most likely not the same as device pixels).
*/
private int getVisiblePageHeight() {
return mActivityTestRule.executeScriptAndExtractInt("window.innerHeight");
}
@Test @Test
@SmallTest @SmallTest
public void testZeroHeight() throws Exception { public void testZeroHeight() throws Exception {
...@@ -77,92 +60,4 @@ public class TopControlsTest { ...@@ -77,92 +60,4 @@ public class TopControlsTest {
helper.waitForCallback(0); helper.waitForCallback(0);
} }
// Disabled on L bots due to unexplained flakes. See crbug.com/1035894.
@FlakyTest(message = "https://crbug.com/1074438")
@MinAndroidSdkLevel(Build.VERSION_CODES.M)
@Test
@SmallTest
public void testBasic() throws Exception {
final String url = UrlUtils.encodeHtmlDataUri("<body><p style='height:5000px'>");
InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl(url);
// Poll until the top view becomes visible.
CriteriaHelper.pollUiThread(Criteria.equals(
View.VISIBLE, () -> activity.getTopContentsContainer().getVisibility()));
TestThreadUtils.runOnUiThreadBlocking(() -> {
mTopControlsHeight = activity.getTopContentsContainer().getHeight();
Assert.assertTrue(mTopControlsHeight > 0);
});
// Get the size of the page.
mInitialVisiblePageHeight = getVisiblePageHeight();
Assert.assertTrue(mInitialVisiblePageHeight > 0);
// Move by the size of the top-controls.
EventUtils.simulateDragFromCenterOfView(
activity.getWindow().getDecorView(), 0, -mTopControlsHeight);
// Moving should change the size of the page. Don't attempt to correlate the size as the
// page doesn't see pixels, and to attempt to compare may result in rounding errors. Poll
// for this value as there is no good way to detect when done.
CriteriaHelper.pollInstrumentationThread(
() -> Assert.assertNotEquals(mInitialVisiblePageHeight, getVisiblePageHeight()));
// Moving should also hide the top-controls View.
TestThreadUtils.runOnUiThreadBlocking(() -> {
Assert.assertEquals(View.INVISIBLE, activity.getTopContentsContainer().getVisibility());
});
// Move so top-controls are shown again.
EventUtils.simulateDragFromCenterOfView(
activity.getWindow().getDecorView(), 0, mTopControlsHeight);
// Wait for the page height to match initial height.
CriteriaHelper.pollInstrumentationThread(
Criteria.equals(mInitialVisiblePageHeight, this::getVisiblePageHeight));
// top-controls are shown async.
CriteriaHelper.pollUiThread(Criteria.equals(
View.VISIBLE, () -> activity.getTopContentsContainer().getVisibility()));
}
/**
* Makes sure that the top controls are shown when a js dialog is shown.
*
* Regression test for https://crbug.com/1078181.
*
* Disabled on L bots due to unexplained flakes. See crbug.com/1035894.
*/
@FlakyTest(message = "https://crbug.com/1074438")
@MinAndroidSdkLevel(Build.VERSION_CODES.M)
@Test
@SmallTest
public void testAlertShowsTopControls() throws Exception {
final String url = UrlUtils.encodeHtmlDataUri("<body><p style='height:5000px'>");
InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl(url);
// Poll until the top view becomes visible.
CriteriaHelper.pollUiThread(Criteria.equals(
View.VISIBLE, () -> activity.getTopContentsContainer().getVisibility()));
TestThreadUtils.runOnUiThreadBlocking(() -> {
mTopControlsHeight = activity.getTopContentsContainer().getHeight();
Assert.assertTrue(mTopControlsHeight > 0);
});
// Move by the size of the top-controls.
EventUtils.simulateDragFromCenterOfView(
activity.getWindow().getDecorView(), 0, -mTopControlsHeight);
// Wait till top controls are invisible.
CriteriaHelper.pollUiThread(Criteria.equals(
View.INVISIBLE, () -> activity.getTopContentsContainer().getVisibility()));
// Trigger an alert dialog.
mActivityTestRule.executeScriptSync(
"window.setTimeout(function() { alert('alert'); }, 1);", false);
// Top controls are shown.
CriteriaHelper.pollUiThread(Criteria.equals(
View.VISIBLE, () -> activity.getTopContentsContainer().getVisibility()));
}
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment