diff --git a/app/build.gradle b/app/build.gradle index caa723a8a..43592c3ea 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -39,7 +39,7 @@ android { testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' minSdkVersion 23 //noinspection ExpiredTargetSdkVersion - targetSdkVersion 29 + targetSdkVersion 30 /* The Android Testing Support Library collects analytics to continuously improve the testing experience. More specifically, it uploads a hash of the package name of the application diff --git a/app/src/androidTest/java/org/fdroid/fdroid/MainActivityEspressoTest.java b/app/src/androidTest/java/org/fdroid/fdroid/MainActivityEspressoTest.java index 5f6ada3ad..0d9097ebd 100644 --- a/app/src/androidTest/java/org/fdroid/fdroid/MainActivityEspressoTest.java +++ b/app/src/androidTest/java/org/fdroid/fdroid/MainActivityEspressoTest.java @@ -219,28 +219,9 @@ public class MainActivityEspressoTest { onView(withText(R.string.main_menu__updates)).check(matches(isDisplayed())); } - @LargeTest - @Test - public void startSwap() { - if (!BuildConfig.FLAVOR.startsWith("full")) { - return; - } - ViewInteraction nearbyBottonNavButton = onView( - allOf(withText(R.string.main_menu__swap_nearby), isDisplayed())); - nearbyBottonNavButton.perform(click()); - ViewInteraction findPeopleButton = onView( - allOf(withId(R.id.find_people_button), withText(R.string.nearby_splash__find_people_button), - isDisplayed())); - findPeopleButton.perform(click()); - onView(withText(R.string.swap_send_fdroid)).check(matches(isDisplayed())); - } - @LargeTest @Test public void showCategories() { - if (!BuildConfig.FLAVOR.startsWith("full")) { - return; - } onView(allOf(withText(R.string.menu_settings), isDisplayed())).perform(click()); onView(allOf(withText(R.string.main_menu__categories), isDisplayed())).perform(click()); onView(allOf(withId(R.id.swipe_to_refresh), isDisplayed())) @@ -264,9 +245,6 @@ public class MainActivityEspressoTest { @LargeTest @Test public void showLatest() { - if (!BuildConfig.FLAVOR.startsWith("full")) { - return; - } onView(Matchers.instanceOf(StatusBanner.class)).check(matches(not(isDisplayed()))); onView(allOf(withText(R.string.menu_settings), isDisplayed())).perform(click()); onView(allOf(withText(R.string.main_menu__latest_apps), isDisplayed())).perform(click()); @@ -289,9 +267,6 @@ public class MainActivityEspressoTest { public void showSearch() { onView(allOf(withText(R.string.menu_settings), isDisplayed())).perform(click()); onView(withId(R.id.fab_search)).check(doesNotExist()); - if (!BuildConfig.FLAVOR.startsWith("full")) { - return; - } onView(allOf(withText(R.string.main_menu__latest_apps), isDisplayed())).perform(click()); onView(allOf(withId(R.id.fab_search), isDisplayed())).perform(click()); onView(withId(R.id.sort)).check(matches(isDisplayed())); @@ -300,4 +275,4 @@ public class MainActivityEspressoTest { .perform(typeText("test")); onView(allOf(withId(R.id.sort), isDisplayed())).perform(click()); } -} \ No newline at end of file +} diff --git a/app/src/androidTest/proguard-rules.pro b/app/src/androidTest/proguard-rules.pro index 6331efee6..4f9d494bc 100644 --- a/app/src/androidTest/proguard-rules.pro +++ b/app/src/androidTest/proguard-rules.pro @@ -1,6 +1,7 @@ -dontoptimize -dontwarn -dontobfuscate +-dontshrink -dontwarn android.test.** -dontwarn android.support.test.** diff --git a/app/src/androidTestFull/java/org/fdroid/fdroid/MainActivityEspressoTestFull.java b/app/src/androidTestFull/java/org/fdroid/fdroid/MainActivityEspressoTestFull.java new file mode 100644 index 000000000..56ab7e5f4 --- /dev/null +++ b/app/src/androidTestFull/java/org/fdroid/fdroid/MainActivityEspressoTestFull.java @@ -0,0 +1,303 @@ +package org.fdroid.fdroid; + +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.action.ViewActions.click; +import static androidx.test.espresso.action.ViewActions.swipeDown; +import static androidx.test.espresso.action.ViewActions.swipeLeft; +import static androidx.test.espresso.action.ViewActions.swipeRight; +import static androidx.test.espresso.action.ViewActions.swipeUp; +import static androidx.test.espresso.action.ViewActions.typeText; +import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription; +import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static androidx.test.espresso.matcher.ViewMatchers.withText; +import static org.hamcrest.CoreMatchers.allOf; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; + +import android.Manifest; +import android.app.ActivityManager; +import android.app.Instrumentation; +import android.content.Context; +import android.os.Build; +import android.util.Log; + +import androidx.core.content.ContextCompat; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.espresso.IdlingPolicies; +import androidx.test.espresso.ViewInteraction; +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 androidx.test.uiautomator.UiObject; +import androidx.test.uiautomator.UiObjectNotFoundException; +import androidx.test.uiautomator.UiSelector; + +import org.fdroid.fdroid.views.StatusBanner; +import org.fdroid.fdroid.views.main.MainActivity; +import org.hamcrest.Matchers; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +@LargeTest +@RunWith(AndroidJUnit4.class) +public class MainActivityEspressoTestFull { + public static final String TAG = "MainActivityEspressoTestFull"; + + /** + * Emulators older than {@code android-25} seem to fail at running Espresso tests. + *

+ * ARM emulators are too slow to run these tests in a useful way. The sad + * thing is that it would probably work if Android didn't put up the ANR + * "Process system isn't responding" on boot each time. There seems to be no + * way to increase the ANR timeout. + */ + private static boolean canRunEspresso() { + if (Build.VERSION.SDK_INT < 25 + || Build.SUPPORTED_ABIS[0].startsWith("arm") && isEmulator()) { + Log.e(TAG, "SKIPPING TEST: ARM emulators are too slow to run these tests in a useful way"); + return false; + } + return true; + } + + @BeforeClass + public static void classSetUp() { + IdlingPolicies.setIdlingResourceTimeout(10, TimeUnit.MINUTES); + IdlingPolicies.setMasterPolicyTimeout(10, TimeUnit.MINUTES); + if (!canRunEspresso()) { + return; + } + Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); + try { + UiDevice.getInstance(instrumentation) + .executeShellCommand("pm grant " + + instrumentation.getTargetContext().getPackageName() + + " android.permission.SET_ANIMATION_SCALE"); + } catch (IOException e) { + e.printStackTrace(); + } + SystemAnimations.disableAll(ApplicationProvider.getApplicationContext()); + + // dismiss the ANR or any other system dialogs that might be there + UiObject button = new UiObject(new UiSelector().text("Wait").enabled(true)); + try { + button.click(); + } catch (UiObjectNotFoundException e) { + Log.d(TAG, e.getLocalizedMessage()); + } + new UiWatchers().registerAnrAndCrashWatchers(); + + Context context = instrumentation.getTargetContext(); + ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo(); + ActivityManager activityManager = ContextCompat.getSystemService(context, ActivityManager.class); + activityManager.getMemoryInfo(mi); + long percentAvail = mi.availMem / mi.totalMem; + Log.i(TAG, "RAM: " + mi.availMem + " / " + mi.totalMem + " = " + percentAvail); + } + + @AfterClass + public static void classTearDown() { + SystemAnimations.enableAll(ApplicationProvider.getApplicationContext()); + } + + public static boolean isEmulator() { + return Build.FINGERPRINT.startsWith("generic") + || Build.FINGERPRINT.startsWith("unknown") + || Build.MODEL.contains("google_sdk") + || Build.MODEL.contains("Emulator") + || Build.MODEL.contains("Android SDK built for x86") + || Build.MANUFACTURER.contains("Genymotion") + || Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic") + || "google_sdk".equals(Build.PRODUCT); + } + + @Before + public void setUp() { + assumeTrue(canRunEspresso()); + } + + /** + * Placate {@link android.os.StrictMode} + * + * @see Run finalizers before counting for StrictMode + */ + @After + public void tearDown() { + System.gc(); + System.runFinalization(); + System.gc(); + } + + @Rule + public ActivityTestRule activityTestRule = + new ActivityTestRule<>(MainActivity.class); + + @Rule + public GrantPermissionRule accessCoarseLocationPermissionRule = GrantPermissionRule.grant( + Manifest.permission.ACCESS_COARSE_LOCATION); + + @Rule + public GrantPermissionRule readExternalStoragePermissionRule = GrantPermissionRule.grant( + Manifest.permission.READ_EXTERNAL_STORAGE); + + @Test + public void bottomNavFlavorCheck() { + onView(withText(R.string.main_menu__updates)).check(matches(isDisplayed())); + onView(withText(R.string.menu_settings)).check(matches(isDisplayed())); + onView(withText("THIS SHOULD NOT SHOW UP ANYWHERE!!!")).check(doesNotExist()); + + assertTrue(BuildConfig.FLAVOR.startsWith("full") || BuildConfig.FLAVOR.startsWith("basic")); + + if (BuildConfig.FLAVOR.startsWith("basic")) { + onView(withText(R.string.main_menu__latest_apps)).check(matches(isDisplayed())); + onView(withText(R.string.main_menu__categories)).check(doesNotExist()); + onView(withText(R.string.main_menu__swap_nearby)).check(doesNotExist()); + } + + if (BuildConfig.FLAVOR.startsWith("full")) { + onView(withText(R.string.main_menu__latest_apps)).check(matches(isDisplayed())); + onView(withText(R.string.main_menu__categories)).check(matches(isDisplayed())); + onView(withText(R.string.main_menu__swap_nearby)).check(matches(isDisplayed())); + } + } + + @LargeTest + @Test + public void showSettings() { + ViewInteraction settingsBottonNavButton = onView( + allOf(withText(R.string.menu_settings), isDisplayed())); + settingsBottonNavButton.perform(click()); + onView(withText(R.string.preference_manage_installed_apps)).check(matches(isDisplayed())); + if (BuildConfig.FLAVOR.startsWith("basic") && BuildConfig.APPLICATION_ID.endsWith(".debug")) { + // TODO fix me by sorting out the flavor applicationId for debug builds in app/build.gradle + Log.i(TAG, "Skipping the remainder of showSettings test because it just crashes on basic .debug builds"); + return; + } + ViewInteraction manageInstalledAppsButton = onView( + allOf(withText(R.string.preference_manage_installed_apps), isDisplayed())); + manageInstalledAppsButton.perform(click()); + onView(withText(R.string.installed_apps__activity_title)).check(matches(isDisplayed())); + onView(withContentDescription(androidx.appcompat.R.string.abc_action_bar_up_description)).perform(click()); + + onView(withText(R.string.menu_manage)).perform(click()); + onView(withContentDescription(androidx.appcompat.R.string.abc_action_bar_up_description)).perform(click()); + + manageInstalledAppsButton.perform(click()); + onView(withText(R.string.installed_apps__activity_title)).check(matches(isDisplayed())); + onView(withContentDescription(androidx.appcompat.R.string.abc_action_bar_up_description)).perform(click()); + + onView(withText(R.string.menu_manage)).perform(click()); + onView(withContentDescription(androidx.appcompat.R.string.abc_action_bar_up_description)).perform(click()); + + onView(withText(R.string.about_title)).perform(click()); + onView(withId(R.id.version)).check(matches(isDisplayed())); + onView(withId(R.id.ok_button)).perform(click()); + + onView(withId(android.R.id.list_container)).perform(swipeUp()).perform(swipeUp()).perform(swipeUp()); + } + + @LargeTest + @Test + public void showUpdates() { + ViewInteraction updatesBottonNavButton = onView(allOf(withText(R.string.main_menu__updates), isDisplayed())); + updatesBottonNavButton.perform(click()); + onView(withText(R.string.main_menu__updates)).check(matches(isDisplayed())); + } + + @LargeTest + @Test + public void startSwap() { + if (!BuildConfig.FLAVOR.startsWith("full")) { + return; + } + ViewInteraction nearbyBottonNavButton = onView( + allOf(withText(R.string.main_menu__swap_nearby), isDisplayed())); + nearbyBottonNavButton.perform(click()); + ViewInteraction findPeopleButton = onView( + allOf(withId(R.id.find_people_button), withText(R.string.nearby_splash__find_people_button), + isDisplayed())); + findPeopleButton.perform(click()); + onView(withText(R.string.swap_send_fdroid)).check(matches(isDisplayed())); + } + + @LargeTest + @Test + public void showCategories() { + if (!BuildConfig.FLAVOR.startsWith("full")) { + return; + } + onView(allOf(withText(R.string.menu_settings), isDisplayed())).perform(click()); + onView(allOf(withText(R.string.main_menu__categories), isDisplayed())).perform(click()); + onView(allOf(withId(R.id.swipe_to_refresh), isDisplayed())) + .perform(swipeDown()) + .perform(swipeUp()) + .perform(swipeUp()) + .perform(swipeUp()) + .perform(swipeUp()) + .perform(swipeUp()) + .perform(swipeUp()) + .perform(swipeDown()) + .perform(swipeDown()) + .perform(swipeRight()) + .perform(swipeLeft()) + .perform(swipeLeft()) + .perform(swipeLeft()) + .perform(swipeLeft()) + .perform(click()); + } + + @LargeTest + @Test + public void showLatest() { + if (!BuildConfig.FLAVOR.startsWith("full")) { + return; + } + onView(Matchers.instanceOf(StatusBanner.class)).check(matches(not(isDisplayed()))); + onView(allOf(withText(R.string.menu_settings), isDisplayed())).perform(click()); + onView(allOf(withText(R.string.main_menu__latest_apps), isDisplayed())).perform(click()); + onView(allOf(withId(R.id.swipe_to_refresh), isDisplayed())) + .perform(swipeDown()) + .perform(swipeUp()) + .perform(swipeUp()) + .perform(swipeUp()) + .perform(swipeDown()) + .perform(swipeUp()) + .perform(swipeDown()) + .perform(swipeDown()) + .perform(swipeDown()) + .perform(swipeDown()) + .perform(click()); + } + + @LargeTest + @Test + public void showSearch() { + onView(allOf(withText(R.string.menu_settings), isDisplayed())).perform(click()); + onView(withId(R.id.fab_search)).check(doesNotExist()); + if (!BuildConfig.FLAVOR.startsWith("full")) { + return; + } + onView(allOf(withText(R.string.main_menu__latest_apps), isDisplayed())).perform(click()); + onView(allOf(withId(R.id.fab_search), isDisplayed())).perform(click()); + onView(withId(R.id.sort)).check(matches(isDisplayed())); + onView(allOf(withId(R.id.search), isDisplayed())) + .perform(click()) + .perform(typeText("test")); + onView(allOf(withId(R.id.sort), isDisplayed())).perform(click()); + } +} diff --git a/app/src/androidTest/java/org/fdroid/fdroid/nearby/BonjourManagerTest.java b/app/src/androidTestFull/java/org/fdroid/fdroid/nearby/BonjourManagerTest.java similarity index 100% rename from app/src/androidTest/java/org/fdroid/fdroid/nearby/BonjourManagerTest.java rename to app/src/androidTestFull/java/org/fdroid/fdroid/nearby/BonjourManagerTest.java diff --git a/app/src/androidTest/java/org/fdroid/fdroid/nearby/LocalHTTPDManagerTest.java b/app/src/androidTestFull/java/org/fdroid/fdroid/nearby/LocalHTTPDManagerTest.java similarity index 100% rename from app/src/androidTest/java/org/fdroid/fdroid/nearby/LocalHTTPDManagerTest.java rename to app/src/androidTestFull/java/org/fdroid/fdroid/nearby/LocalHTTPDManagerTest.java diff --git a/app/src/androidTest/java/org/fdroid/fdroid/nearby/PublicSourceDirProviderTest.java b/app/src/androidTestFull/java/org/fdroid/fdroid/nearby/PublicSourceDirProviderTest.java similarity index 100% rename from app/src/androidTest/java/org/fdroid/fdroid/nearby/PublicSourceDirProviderTest.java rename to app/src/androidTestFull/java/org/fdroid/fdroid/nearby/PublicSourceDirProviderTest.java diff --git a/app/src/androidTest/java/org/fdroid/fdroid/updater/SwapRepoEmulatorTest.java b/app/src/androidTestFull/java/org/fdroid/fdroid/updater/SwapRepoEmulatorTest.java similarity index 100% rename from app/src/androidTest/java/org/fdroid/fdroid/updater/SwapRepoEmulatorTest.java rename to app/src/androidTestFull/java/org/fdroid/fdroid/updater/SwapRepoEmulatorTest.java diff --git a/app/src/main/java/org/fdroid/fdroid/views/InstallHistoryActivity.java b/app/src/main/java/org/fdroid/fdroid/views/InstallHistoryActivity.java index fcd97a71d..edf22e222 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/InstallHistoryActivity.java +++ b/app/src/main/java/org/fdroid/fdroid/views/InstallHistoryActivity.java @@ -31,6 +31,7 @@ import android.view.MenuItem; import android.widget.TextView; import android.widget.Toast; +import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ShareCompat; @@ -66,6 +67,7 @@ public class InstallHistoryActivity extends AppCompatActivity { fdroidApp.setSecureWindow(this); fdroidApp.applyPureBlackBackgroundInDarkTheme(this); + EdgeToEdge.enable(this); super.onCreate(savedInstanceState); setContentView(R.layout.activity_install_history); diff --git a/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewayAddActivity.kt b/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewayAddActivity.kt index 7a6336d61..5408e59ce 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewayAddActivity.kt +++ b/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewayAddActivity.kt @@ -3,6 +3,7 @@ package org.fdroid.fdroid.views import android.net.Uri import android.os.Bundle import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -46,6 +47,7 @@ import org.fdroid.fdroid.ui.theme.FDroidContent class IpfsGatewayAddActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { + enableEdgeToEdge() super.onCreate(savedInstanceState) setContent { FDroidContent { diff --git a/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewaySettingsActivity.kt b/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewaySettingsActivity.kt index 887e1b983..1bc51d8d0 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewaySettingsActivity.kt +++ b/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewaySettingsActivity.kt @@ -4,6 +4,7 @@ import android.annotation.SuppressLint import android.content.Intent import android.os.Bundle import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -50,6 +51,7 @@ import org.fdroid.fdroid.ui.theme.FDroidContent class IpfsGatewaySettingsActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { + enableEdgeToEdge() super.onCreate(savedInstanceState) val prefs = Preferences.get() setContent { diff --git a/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoActivity.kt b/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoActivity.kt index 73e406a88..317e2b005 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoActivity.kt +++ b/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoActivity.kt @@ -8,6 +8,7 @@ import android.util.Log import android.widget.Toast import androidx.activity.compose.BackHandler import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity import androidx.compose.runtime.collectAsState import androidx.core.content.ContextCompat @@ -36,6 +37,7 @@ class AddRepoActivity : AppCompatActivity() { private val repoManager: RepoManager get() = FDroidApp.getRepoManager(this) override fun onCreate(savedInstanceState: Bundle?) { + enableEdgeToEdge() super.onCreate(savedInstanceState) lifecycleScope.launch { repeatOnLifecycle(STARTED) { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8c82f7a49..4902305b5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ mavenPublish = "0.18.0" jlleitschuhKtlint = "12.1.1" kotlinxSerializationJson = "1.4.1" # 1.4.1 because https://github.com/Kotlin/kotlinx.serialization/issues/2231 -kotlinxCoroutinesTest = "1.7.3" +kotlinxCoroutinesTest = "1.8.1" ktor = "2.3.12" okhttp = "4.12.0" @@ -20,22 +20,22 @@ androidxAppcompat = "1.7.0" androidxPreferenceKtx = "1.2.1" androidxLifecycleLivedataKtx = "2.8.7" androidxWork = "2.10.0" -androidxRecyclerview = "1.3.2" -androidxConstraintlayout = "2.2.0" +androidxRecyclerview = "1.4.0" +androidxConstraintlayout = "2.2.1" androidxCardview = "1.0.0" androidxPaletteKtx = "1.0.0" androidxVectordrawable = "1.2.0" androidxGridlayout = "1.0.0" -androidxComposeBom = "2024.11.00" -androidxActivityCompose = "1.9.3" -accompanistThemeadapterMaterial = "0.30.1" +androidxComposeBom = "2025.03.00" +androidxActivityCompose = "1.10.1" accompanistDrawablepainter = "0.36.0" material = "1.12.0" -zxingCore = "3.3.3" # newer version need minSdk 24 or library desugering +#noinspection GradleDependency newer version need minSdk 24 or library desugering +zxingCore = "3.3.3" guardianprojectNetcipher = "2.2.0-alpha" guardianprojectPanic = "1.0" -acra = "5.11.3" +acra = "5.12.0" adapterdelegates4 = "4.3.2" #noinspection GradleDependency Commons IO > 2.5 uses java.nio.file, which requires desugaring commonsIo = "2.6" @@ -43,7 +43,7 @@ commonsNet = "3.6" bouncycastle = "1.71" jmdns = "3.5.5" nanohttpd = "2.3.1" -guava = "32.1.3-android" +guava = "33.3.1-android" rxjava = "3.1.9" rxandroid = "3.0.2" diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 1da9e1e3f..c8e784161 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -191,6 +191,11 @@ + + + + + @@ -226,6 +231,11 @@ + + + + + @@ -246,6 +256,11 @@ + + + + + @@ -334,6 +349,11 @@ + + + + + @@ -384,6 +404,11 @@ + + + + + @@ -611,6 +636,11 @@ + + + + + @@ -631,6 +661,11 @@ + + + + + @@ -656,6 +691,11 @@ + + + + + @@ -676,6 +716,11 @@ + + + + + @@ -716,6 +761,11 @@ + + + + + @@ -736,6 +786,11 @@ + + + + + @@ -761,6 +816,11 @@ + + + + + @@ -781,6 +841,11 @@ + + + + + @@ -826,6 +891,11 @@ + + + + + @@ -851,6 +921,11 @@ + + + + + @@ -871,6 +946,11 @@ + + + + + @@ -896,6 +976,11 @@ + + + + + @@ -916,6 +1001,11 @@ + + + + + @@ -941,6 +1031,11 @@ + + + + + @@ -961,6 +1056,11 @@ + + + + + @@ -1001,6 +1101,11 @@ + + + + + @@ -1021,6 +1126,11 @@ + + + + + @@ -1046,6 +1156,11 @@ + + + + + @@ -1066,6 +1181,11 @@ + + + + + @@ -1091,6 +1211,11 @@ + + + + + @@ -1111,6 +1236,11 @@ + + + + + @@ -1136,6 +1266,11 @@ + + + + + @@ -1156,6 +1291,11 @@ + + + + + @@ -1181,6 +1321,11 @@ + + + + + @@ -1201,6 +1346,11 @@ + + + + + @@ -1226,6 +1376,11 @@ + + + + + @@ -1246,6 +1401,11 @@ + + + + + @@ -1271,6 +1431,11 @@ + + + + + @@ -1296,6 +1461,11 @@ + + + + + @@ -1321,6 +1491,11 @@ + + + + + @@ -1341,6 +1516,11 @@ + + + + + @@ -1366,6 +1546,11 @@ + + + + + @@ -1386,6 +1571,11 @@ + + + + + @@ -1406,6 +1596,11 @@ + + + + + @@ -1426,6 +1621,11 @@ + + + + + @@ -1464,6 +1664,11 @@ + + + + + @@ -1474,6 +1679,11 @@ + + + + + @@ -1603,6 +1813,11 @@ + + + + + @@ -2645,6 +2860,11 @@ + + + + + @@ -3457,6 +3677,11 @@ + + + + + @@ -3472,6 +3697,11 @@ + + + + + @@ -3487,6 +3717,11 @@ + + + + + @@ -6560,6 +6795,11 @@ + + + + + @@ -6644,6 +6884,11 @@ + + + + + @@ -6719,6 +6964,14 @@ + + + + + + + + @@ -6783,6 +7036,11 @@ + + + + + @@ -10724,6 +10982,11 @@ + + + + + @@ -12838,6 +13101,14 @@ + + + + + + + + @@ -13501,6 +13772,11 @@ + + + + + @@ -13570,6 +13846,11 @@ + + + + + @@ -13636,6 +13917,11 @@ + + + + + @@ -13687,6 +13973,11 @@ + + + + + @@ -13727,6 +14018,11 @@ + + + + + @@ -13757,6 +14053,11 @@ + + + + + @@ -13772,6 +14073,11 @@ + + + + + @@ -13792,6 +14098,11 @@ + + + + +