Merge "[ProfileInstaller] Introduce ProfileTranscoder to support N, O, P+ formats" into androidx-main
diff --git a/activity/integration-tests/testapp/build.gradle b/activity/integration-tests/testapp/build.gradle
index fdb5dec..11e5101 100644
--- a/activity/integration-tests/testapp/build.gradle
+++ b/activity/integration-tests/testapp/build.gradle
@@ -39,6 +39,6 @@
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
androidTestImplementation(ESPRESSO_CORE)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it's own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it's own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it's own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it's own MockMaker
}
diff --git a/ads/ads-identifier-benchmark/build.gradle b/ads/ads-identifier-benchmark/build.gradle
index cc75f5d..95e55d2 100644
--- a/ads/ads-identifier-benchmark/build.gradle
+++ b/ads/ads-identifier-benchmark/build.gradle
@@ -35,5 +35,5 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
}
diff --git a/ads/ads-identifier-provider/build.gradle b/ads/ads-identifier-provider/build.gradle
index d412cd9..f1039b5 100644
--- a/ads/ads-identifier-provider/build.gradle
+++ b/ads/ads-identifier-provider/build.gradle
@@ -39,7 +39,7 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
}
androidx {
diff --git a/ads/ads-identifier-testing/build.gradle b/ads/ads-identifier-testing/build.gradle
index 07d65f8..d8265c7 100644
--- a/ads/ads-identifier-testing/build.gradle
+++ b/ads/ads-identifier-testing/build.gradle
@@ -24,7 +24,7 @@
dependencies {
implementation(project(":ads-identifier-common"))
api("androidx.annotation:annotation:1.1.0")
- api(MOCKITO_CORE, libs.exclude_bytebuddy)
+ api(MOCKITO_CORE, excludes.bytebuddy)
}
android {
diff --git a/ads/ads-identifier/build.gradle b/ads/ads-identifier/build.gradle
index 6841cce..e3730f5 100644
--- a/ads/ads-identifier/build.gradle
+++ b/ads/ads-identifier/build.gradle
@@ -41,7 +41,7 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
}
android {
diff --git a/appcompat/appcompat-resources/build.gradle b/appcompat/appcompat-resources/build.gradle
index 33879d3..6390db6 100644
--- a/appcompat/appcompat-resources/build.gradle
+++ b/appcompat/appcompat-resources/build.gradle
@@ -36,9 +36,9 @@
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
androidTestImplementation(TRUTH)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(project(":internal-testutils-runtime"), {
exclude group: "androidx.appcompat", module: "appcompat-resources"
})
diff --git a/appcompat/appcompat/build.gradle b/appcompat/appcompat/build.gradle
index 99a5f06..29f8bf2 100644
--- a/appcompat/appcompat/build.gradle
+++ b/appcompat/appcompat/build.gradle
@@ -29,9 +29,9 @@
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
androidTestImplementation(TRUTH)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it's own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it's own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it's own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it's own MockMaker
androidTestImplementation(project(":internal-testutils-appcompat"), {
exclude group: "androidx.appcompat", module: "appcompat"
exclude group: "androidx.core", module: "core"
diff --git a/arch/core/core-testing/build.gradle b/arch/core/core-testing/build.gradle
index f94fa7a..bd80e98 100644
--- a/arch/core/core-testing/build.gradle
+++ b/arch/core/core-testing/build.gradle
@@ -29,7 +29,7 @@
api(project(":arch:core:core-runtime"))
api("androidx.annotation:annotation:1.1.0")
api(JUNIT)
- api(MOCKITO_CORE, libs.exclude_bytebuddy)
+ api(MOCKITO_CORE, excludes.bytebuddy)
testImplementation(JUNIT)
diff --git a/benchmark/macro-junit4/build.gradle b/benchmark/macro-junit4/build.gradle
index 4ee565e..d159e9f 100644
--- a/benchmark/macro-junit4/build.gradle
+++ b/benchmark/macro-junit4/build.gradle
@@ -50,9 +50,9 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ESPRESSO_CORE)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
// DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
// DexMaker has it"s own MockMaker
}
diff --git a/biometric/biometric-ktx/samples/src/main/java/androidx/biometric/samples/auth/CoroutineSamples.kt b/biometric/biometric-ktx/samples/src/main/java/androidx/biometric/samples/auth/CoroutineSamples.kt
index 9d9368e..d49de2e 100644
--- a/biometric/biometric-ktx/samples/src/main/java/androidx/biometric/samples/auth/CoroutineSamples.kt
+++ b/biometric/biometric-ktx/samples/src/main/java/androidx/biometric/samples/auth/CoroutineSamples.kt
@@ -102,7 +102,7 @@
}
@Sampled
-@Suppress("UnsafeNewApiCall", "NewApi")
+@Suppress("NewApi", "ClassVerificationFailure")
suspend fun Fragment.class3BiometricAuth() {
// To use Class3 authentication, we need to create a CryptoObject.
// First create a spec for the key to be generated.
@@ -163,7 +163,7 @@
}
@Sampled
-@Suppress("UnsafeNewApiCall", "NewApi")
+@Suppress("NewApi", "ClassVerificationFailure")
suspend fun Fragment.class3BiometricOrCredentialAuth() {
// To use Class3 authentication, we need to create a CryptoObject.
// First create a spec for the key to be generated.
@@ -224,7 +224,7 @@
}
@Sampled
-@Suppress("UnsafeNewApiCall", "NewApi")
+@Suppress("NewApi", "ClassVerificationFailure")
suspend fun Fragment.credentialAuth() {
// To use credential authentication, we need to create a CryptoObject.
// First create a spec for the key to be generated.
diff --git a/biometric/biometric/build.gradle b/biometric/biometric/build.gradle
index 0933892..6f12943 100644
--- a/biometric/biometric/build.gradle
+++ b/biometric/biometric/build.gradle
@@ -46,8 +46,8 @@
androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
androidTestImplementation(ANDROIDX_TEST_RULES)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
androidTestImplementation(TRUTH)
}
diff --git a/browser/browser/build.gradle b/browser/browser/build.gradle
index 5359fed..c98ffa8 100644
--- a/browser/browser/build.gradle
+++ b/browser/browser/build.gradle
@@ -40,9 +40,9 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(project(":internal-testutils-runtime"))
}
diff --git a/buildSrc/dependencies.gradle b/buildSrc/dependencies.gradle
index 0eb002e..23c0358 100644
--- a/buildSrc/dependencies.gradle
+++ b/buildSrc/dependencies.gradle
@@ -14,13 +14,13 @@
* limitations under the License.
*/
// Add ext.libs for library versions
-def libs = [:]
+def excludes = [:]
-libs.exclude_bytebuddy = {
+excludes.bytebuddy = {
exclude group: "net.bytebuddy"
}
-libs.exclude_for_espresso = {
+excludes.espresso = {
exclude group: "androidx.annotation"
exclude group: "androidx.appcompat"
exclude group: "androidx.recyclerview"
@@ -31,4 +31,4 @@
exclude group: "androidx.core"
}
-rootProject.ext["libs"] = libs
+rootProject.ext["excludes"] = excludes
diff --git a/buildSrc/src/main/kotlin/androidx/build/BundleInsideHelper.kt b/buildSrc/src/main/kotlin/androidx/build/BundleInsideHelper.kt
index 7d9d5d0..be96014 100644
--- a/buildSrc/src/main/kotlin/androidx/build/BundleInsideHelper.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/BundleInsideHelper.kt
@@ -40,12 +40,13 @@
*
* Used project are expected
*
+ * @see forInsideAar(String, String)
+ *
* @receiver the project that should bundle jars specified by these configurations
- * @param from specifies from which package the rename should happen
- * @param to specifies to which package to put the renamed classes
+ * @param relocations a list of package relocations to apply
*/
@JvmStatic
- fun Project.forInsideAar(from: String, to: String) {
+ fun Project.forInsideAar(relocations: List<Relocation>) {
val bundle = configurations.create("bundleInside")
val bundleDebug = configurations.create("debugBundleInside") {
it.extendsFrom(bundle)
@@ -53,8 +54,12 @@
val bundleRelease = configurations.create("releaseBundleInside") {
it.extendsFrom(bundle)
}
- val repackageRelease = configureRepackageTaskForType("Release", from, to, bundleRelease)
- val repackageDebug = configureRepackageTaskForType("Debug", from, to, bundleDebug)
+ val repackageRelease = configureRepackageTaskForType(
+ "Release",
+ relocations,
+ bundleRelease
+ )
+ val repackageDebug = configureRepackageTaskForType("Debug", relocations, bundleDebug)
// Add to AGP's configurations so these jars get packaged inside of the aar.
dependencies.add(
@@ -69,6 +74,26 @@
task.dependsOn(repackageRelease)
}
}
+ /**
+ * Creates 3 configurations for the users to use that will be used bundle these dependency
+ * jars inside of libs/ directory inside of the aar.
+ *
+ * ```
+ * dependencies {
+ * bundleInside(project(":foo"))
+ * }
+ * ```
+ *
+ * Used project are expected
+ *
+ * @receiver the project that should bundle jars specified by these configurations
+ * @param from specifies from which package the rename should happen
+ * @param to specifies to which package to put the renamed classes
+ */
+ @JvmStatic
+ fun Project.forInsideAar(from: String, to: String) {
+ forInsideAar(listOf(Relocation(from, to)))
+ }
/**
* Creates a configuration for the users to use that will be used bundle these dependency
@@ -88,7 +113,11 @@
@JvmStatic
fun Project.forInsideJar(from: String, to: String) {
val bundle = configurations.create("bundleInside")
- val repackage = configureRepackageTaskForType("jar", from, to, bundle)
+ val repackage = configureRepackageTaskForType(
+ "jar",
+ listOf(Relocation(from, to)),
+ bundle
+ )
dependencies.add("compileOnly", files(repackage.flatMap { it.archiveFile }))
dependencies.add("testImplementation", files(repackage.flatMap { it.archiveFile }))
@@ -165,10 +194,11 @@
}
}
+ data class Relocation(val from: String, val to: String)
+
private fun Project.configureRepackageTaskForType(
type: String,
- from: String,
- to: String,
+ relocations: List<Relocation>,
configuration: Configuration
): TaskProvider<ShadowJar> {
return tasks.register(
@@ -177,7 +207,9 @@
) { task ->
task.apply {
configurations = listOf(configuration)
- relocate(from, to)
+ for (relocation in relocations) {
+ relocate(relocation.from, relocation.to)
+ }
archiveBaseName.set("repackaged-$type")
archiveVersion.set("")
destinationDirectory.set(File(buildDir, "repackaged"))
diff --git a/camera/camera-camera2/build.gradle b/camera/camera-camera2/build.gradle
index 113c7b3..78ccd42 100644
--- a/camera/camera-camera2/build.gradle
+++ b/camera/camera-camera2/build.gradle
@@ -55,8 +55,8 @@
androidTestImplementation(TRUTH)
androidTestImplementation(ANDROIDX_TEST_UIAUTOMATOR)
androidTestImplementation(ESPRESSO_CORE)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it's own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it's own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it's own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it's own MockMaker
androidTestImplementation("androidx.appcompat:appcompat:1.1.0")
androidTestImplementation(project(":camera:camera-testing"))
androidTestImplementation(KOTLIN_STDLIB)
diff --git a/camera/camera-core/api/public_plus_experimental_current.txt b/camera/camera-core/api/public_plus_experimental_current.txt
index 32b510d..f3e2dd0 100644
--- a/camera/camera-core/api/public_plus_experimental_current.txt
+++ b/camera/camera-core/api/public_plus_experimental_current.txt
@@ -28,6 +28,7 @@
}
public interface CameraInfo {
+ method @androidx.camera.core.ExperimentalCameraFilter public androidx.camera.core.CameraSelector getCameraSelector();
method @androidx.camera.core.ExperimentalExposureCompensation public androidx.camera.core.ExposureState getExposureState();
method public int getSensorRotationDegrees();
method public int getSensorRotationDegrees(int);
diff --git a/camera/camera-core/build.gradle b/camera/camera-core/build.gradle
index 1ee46cb..2b4bf00 100644
--- a/camera/camera-core/build.gradle
+++ b/camera/camera-core/build.gradle
@@ -57,8 +57,8 @@
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
androidTestImplementation(TRUTH)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it's own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it's own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it's own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it's own MockMaker
androidTestImplementation(project(":camera:camera-testing"))
androidTestImplementation(KOTLIN_STDLIB)
androidTestImplementation(KOTLIN_COROUTINES_ANDROID)
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/CameraInfo.java b/camera/camera-core/src/main/java/androidx/camera/core/CameraInfo.java
index 43378ac..1eb2ff3 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/CameraInfo.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/CameraInfo.java
@@ -178,6 +178,15 @@
@ImplementationType
String getImplementationType();
+ /**
+ * Returns a {@link CameraSelector} unique to this camera.
+ *
+ * @return {@link CameraSelector} unique to this camera.
+ */
+ @ExperimentalCameraFilter
+ @NonNull
+ CameraSelector getCameraSelector();
+
/** @hide */
@StringDef(open = true, value = {IMPLEMENTATION_TYPE_UNKNOWN,
IMPLEMENTATION_TYPE_CAMERA2_LEGACY, IMPLEMENTATION_TYPE_CAMERA2,
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/CameraProvider.java b/camera/camera-core/src/main/java/androidx/camera/core/CameraProvider.java
index 5e11df0..a8e42bd 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/CameraProvider.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/CameraProvider.java
@@ -50,6 +50,11 @@
* selected through
* {@link androidx.camera.core.CameraXConfig.Builder#setAvailableCamerasLimiter(CameraSelector)}
*
+ * <p>While iterating through all the available {@link CameraInfo}, if one of them meets some
+ * predefined requirements, a {@link CameraSelector} that uniquely identifies its camera
+ * can be retrieved using {@link CameraInfo#getCameraSelector()}, which can then be used to bind
+ * {@linkplain UseCase use cases} to that camera.
+ *
* @return A list of {@link CameraInfo} instances for the available cameras.
*/
@NonNull
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraInfoInternal.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraInfoInternal.java
index aba76ae..43c07d5 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraInfoInternal.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraInfoInternal.java
@@ -19,7 +19,11 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.camera.core.CameraInfo;
+import androidx.camera.core.CameraSelector;
+import androidx.camera.core.ExperimentalCameraFilter;
+import androidx.core.util.Preconditions;
+import java.util.Collections;
import java.util.concurrent.Executor;
/**
@@ -70,4 +74,26 @@
/** Returns the {@link CamcorderProfileProvider} associated with this camera. */
@NonNull
CamcorderProfileProvider getCamcorderProfileProvider();
+
+ /** {@inheritDoc} */
+ @ExperimentalCameraFilter
+ @NonNull
+ @Override
+ default CameraSelector getCameraSelector() {
+ return new CameraSelector.Builder()
+ .addCameraFilter(cameraInfos -> {
+ final String cameraId = getCameraId();
+ for (CameraInfo cameraInfo : cameraInfos) {
+ Preconditions.checkArgument(cameraInfo instanceof CameraInfoInternal);
+ final CameraInfoInternal cameraInfoInternal =
+ (CameraInfoInternal) cameraInfo;
+ if (cameraInfoInternal.getCameraId().equals(cameraId)) {
+ return Collections.singletonList(cameraInfo);
+ }
+ }
+ throw new IllegalStateException("Unable to find camera with id " + cameraId
+ + " from list of available cameras.");
+ })
+ .build();
+ }
}
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/impl/CameraInfoInternalTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/impl/CameraInfoInternalTest.kt
new file mode 100644
index 0000000..7c083c9
--- /dev/null
+++ b/camera/camera-core/src/test/java/androidx/camera/core/impl/CameraInfoInternalTest.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2021 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.core.impl
+
+import android.os.Build
+import androidx.camera.testing.fakes.FakeCamera
+import androidx.camera.testing.fakes.FakeCameraInfoInternal
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.internal.DoNotInstrument
+
+private const val CAMERA_ID = "2"
+
+@RunWith(RobolectricTestRunner::class)
+@DoNotInstrument
+@Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
+internal class CameraInfoInternalTest {
+
+ @Test
+ fun selector_findsMatchingCamera() {
+ val cameraInfo = FakeCameraInfoInternal(CAMERA_ID)
+ val cameras = createCamerasWithIds(arrayOf(1, CAMERA_ID.toInt(), 3, 4))
+ val filteredCameras = cameraInfo.cameraSelector.filter(LinkedHashSet(cameras))
+
+ assertThat(filteredCameras).hasSize(1)
+ assertThat(filteredCameras.first().cameraInfoInternal.cameraId).isEqualTo(CAMERA_ID)
+ }
+
+ @Test(expected = IllegalStateException::class)
+ fun selector_doesNotFindMatchingCamera() {
+ val cameraInfo = FakeCameraInfoInternal(CAMERA_ID)
+ val cameras = createCamerasWithIds(arrayOf(1, 3, 4))
+ cameraInfo.cameraSelector.filter(LinkedHashSet(cameras))
+ }
+
+ private fun createCamerasWithIds(ids: Array<Int>): List<CameraInternal> {
+ return ids.map { FakeCamera(it.toString()) }
+ }
+}
\ No newline at end of file
diff --git a/camera/camera-extensions/build.gradle b/camera/camera-extensions/build.gradle
index 1d55af9..64d147b 100644
--- a/camera/camera-extensions/build.gradle
+++ b/camera/camera-extensions/build.gradle
@@ -49,9 +49,9 @@
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has its own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has its own MockMaker
androidTestImplementation(KOTLIN_STDLIB)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has its own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has its own MockMaker
androidTestImplementation(TRUTH)
androidTestImplementation(project(":camera:camera-testing"))
androidTestImplementation(project(":internal-testutils-truth"))
diff --git a/camera/camera-video/build.gradle b/camera/camera-video/build.gradle
index d2d4178..4527837 100644
--- a/camera/camera-video/build.gradle
+++ b/camera/camera-video/build.gradle
@@ -53,8 +53,8 @@
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
androidTestImplementation(TRUTH)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it's own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it's own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it's own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it's own MockMaker
androidTestImplementation(project(":camera:camera-testing"))
androidTestImplementation(KOTLIN_STDLIB)
androidTestImplementation(KOTLIN_COROUTINES_ANDROID)
diff --git a/camera/camera-view/build.gradle b/camera/camera-view/build.gradle
index aef81d0..06c00c8 100644
--- a/camera/camera-view/build.gradle
+++ b/camera/camera-view/build.gradle
@@ -73,8 +73,8 @@
androidTestImplementation(KOTLIN_STDLIB)
androidTestImplementation(TRUTH)
androidTestImplementation("androidx.camera:camera-camera2:${VIEW_ATOMIC_GROUP_PINNED_VER}")
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it's own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it's own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it's own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it's own MockMaker
}
android {
defaultConfig {
diff --git a/car/app/app-samples/showcase/automotive/src/main/AndroidManifest.xml b/car/app/app-samples/showcase/automotive/src/main/AndroidManifest.xml
index 8ffe920..c2ba48a 100644
--- a/car/app/app-samples/showcase/automotive/src/main/AndroidManifest.xml
+++ b/car/app/app-samples/showcase/automotive/src/main/AndroidManifest.xml
@@ -49,6 +49,10 @@
android:resource="@style/CarAppTheme"
tools:ignore="MetadataTagInsideApplicationTag" />
+ <meta-data android:name="androidx.car.app.minApiLevel"
+ android:value="1"
+ tools:ignore="MetadataTagInsideApplicationTag" />
+
<service
android:name="androidx.car.app.sample.showcase.common.ShowcaseService"
android:exported="true">
diff --git a/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/templates/LongMessageTemplateDemoScreen.java b/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/templates/LongMessageTemplateDemoScreen.java
index 28b8d61..a94713e 100644
--- a/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/templates/LongMessageTemplateDemoScreen.java
+++ b/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/templates/LongMessageTemplateDemoScreen.java
@@ -28,7 +28,9 @@
import androidx.car.app.model.ActionStrip;
import androidx.car.app.model.CarColor;
import androidx.car.app.model.LongMessageTemplate;
+import androidx.car.app.model.MessageTemplate;
import androidx.car.app.model.Template;
+import androidx.car.app.versioning.CarAppApiLevels;
/** A screen that demonstrates the long message template. */
@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)
@@ -83,6 +85,12 @@
@NonNull
@Override
public Template onGetTemplate() {
+ if (getCarContext().getCarAppApiLevel() < CarAppApiLevels.LEVEL_2) {
+ return new MessageTemplate.Builder("Your host doesn't support Long Message template")
+ .setTitle("Incompatible host")
+ .setHeaderAction(Action.BACK)
+ .build();
+ }
return new LongMessageTemplate.Builder(TEXT)
.setTitle("Long Message Template Demo")
.setHeaderAction(BACK)
diff --git a/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/templates/SignInTemplateDemoScreen.java b/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/templates/SignInTemplateDemoScreen.java
index 000eb03..113d018 100644
--- a/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/templates/SignInTemplateDemoScreen.java
+++ b/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/templates/SignInTemplateDemoScreen.java
@@ -41,6 +41,7 @@
import androidx.car.app.model.signin.SignInTemplate;
import androidx.car.app.sample.showcase.common.R;
import androidx.car.app.sample.showcase.common.common.Utils;
+import androidx.car.app.versioning.CarAppApiLevels;
import androidx.core.graphics.drawable.IconCompat;
import java.util.UUID;
@@ -108,6 +109,12 @@
@NonNull
@Override
public Template onGetTemplate() {
+ if (getCarContext().getCarAppApiLevel() < CarAppApiLevels.LEVEL_2) {
+ return new MessageTemplate.Builder("Your host doesn't support Sign In template")
+ .setTitle("Incompatible host")
+ .setHeaderAction(Action.BACK)
+ .build();
+ }
switch (mState) {
case USERNAME:
return getUsernameSignInTemplate();
diff --git a/car/app/app/api/current.txt b/car/app/app/api/current.txt
index 4197448..d79c285 100644
--- a/car/app/app/api/current.txt
+++ b/car/app/app/api/current.txt
@@ -6,6 +6,7 @@
method public int getLatestCarAppApiLevel();
method public String getLibraryDisplayVersion();
method public int getMinCarAppApiLevel();
+ field public static final String MIN_API_LEVEL_MANIFEST_KEY = "androidx.car.app.minApiLevel";
}
public class AppManager {
diff --git a/car/app/app/api/public_plus_experimental_current.txt b/car/app/app/api/public_plus_experimental_current.txt
index 0c92952a..892476a 100644
--- a/car/app/app/api/public_plus_experimental_current.txt
+++ b/car/app/app/api/public_plus_experimental_current.txt
@@ -6,6 +6,7 @@
method public int getLatestCarAppApiLevel();
method public String getLibraryDisplayVersion();
method public int getMinCarAppApiLevel();
+ field public static final String MIN_API_LEVEL_MANIFEST_KEY = "androidx.car.app.minApiLevel";
}
public class AppManager {
diff --git a/car/app/app/api/restricted_current.txt b/car/app/app/api/restricted_current.txt
index 4197448..d79c285 100644
--- a/car/app/app/api/restricted_current.txt
+++ b/car/app/app/api/restricted_current.txt
@@ -6,6 +6,7 @@
method public int getLatestCarAppApiLevel();
method public String getLibraryDisplayVersion();
method public int getMinCarAppApiLevel();
+ field public static final String MIN_API_LEVEL_MANIFEST_KEY = "androidx.car.app.minApiLevel";
}
public class AppManager {
diff --git a/car/app/app/src/main/java/androidx/car/app/AppInfo.java b/car/app/app/src/main/java/androidx/car/app/AppInfo.java
index 7fdc8bb..a2a1b6a 100644
--- a/car/app/app/src/main/java/androidx/car/app/AppInfo.java
+++ b/car/app/app/src/main/java/androidx/car/app/AppInfo.java
@@ -48,7 +48,7 @@
* <manifest ...>
* <application ...>
* <meta-data
- * android:name="androidx.car.app.min-api-level"
+ * android:name="androidx.car.app.minApiLevel"
* android:value="1" />
* ...
* </application>
@@ -62,10 +62,16 @@
// TODO(b/174803562): Automatically update the this version using Gradle
private static final String LIBRARY_VERSION = "1.1.0-alpha01";
- /** @hide */
- @RestrictTo(Scope.LIBRARY)
- @VisibleForTesting
- public static final String MIN_API_LEVEL_MANIFEST_KEY = "androidx.car.app.min-api-level";
+ /**
+ * Application meta-data tag used to define the minimum Car App API level this application is
+ * able to handle.
+ *
+ * <p>If not specified, the library assumes the application can only handle the Car App API
+ * level designed by {@link CarAppApiLevels#getLatest()} at the time of compiling.
+ *
+ * @see CarContext#getCarAppApiLevel()
+ */
+ public static final String MIN_API_LEVEL_MANIFEST_KEY = "androidx.car.app.minApiLevel";
@Keep
@Nullable
diff --git a/cleanBuild.sh b/cleanBuild.sh
index 3ee4ae6..c6ed4dd 100755
--- a/cleanBuild.sh
+++ b/cleanBuild.sh
@@ -1,19 +1,6 @@
#!/bin/bash
set -e
-echo "IF THIS SCRIPT FIXES YOUR BUILD; OPEN A BUG."
-echo "In nearly all cases, it should not be necessary to run a clean build."
-echo
-echo "You may be more interested in running:"
-echo
-echo " ./development/diagnose-build-failure/diagnose-build-failure.sh $*"
-echo
-echo "which attempts to diagnose more details about build failures"
-# one case where it is convenient to have a clean build is for double-checking that a build failure isn't due to an incremental build failure
-# another case where it is convenient to have a clean build is for performance testing
-# another case where it is convenient to have a clean build is when you're modifying the build and may have introduced some errors but haven't shared your changes yet (at which point you should have fixed the errors)
-echo
-
DO_PROMPT=true
if [ "$1" == "-y" ]; then
DO_PROMPT=false
@@ -52,7 +39,7 @@
# Confirm whether the user wants to run this script instead of diagnose-build-failure.sh
# Recall that we already mentioned the existence of diagnose-build-failure.sh above
echo
- echo "Press <Enter> to run a clean build or Ctrl-C to cancel"
+ echo "Press <Enter> to run a clean build (./gradlew --clean $goals) or Ctrl-C to cancel"
if [ "$DO_PROMPT" == "true" ]; then
read response
fi
@@ -62,25 +49,5 @@
scriptDir="$(cd $(dirname $0) && pwd)"
checkoutDir="$(cd $scriptDir/../.. && pwd)"
export OUT_DIR="$checkoutDir/out"
-function removeCaches() {
- echo removing caches
- rm -rf .gradle
- rm -rf buildSrc/.gradle
- rm -f local.properties
- # We move the Gradle cache (via the OUT_DIR) variable during this build to prevent
- # Other Gradle builds in other directories from sharing it, to be extra-sure that the
- # build will be clean. However, if the user subsequently runs `./gradlew`, it will use
- # ~/.gradle as the Gradle cache dir, which could surprise users because it might hold
- # different state. So, we preemptively remove ~/.gradle too, just in case the user
- # is going to want that for their following build
- rm -rf ~/.gradle
- # AGP should (also) do this automatically (b/170640263)
- rm -rf appsearch/appsearch/.cxx
- rm -rf appsearch/local-backend/.cxx
- rm -rf appsearch/local-storage/.cxx
- rm -rf $OUT_DIR
-}
-removeCaches
-echo running build
-./gradlew --no-daemon $goals
+./gradlew --clean $goals
diff --git a/compose/animation/animation-lint/src/main/java/androidx/compose/animation/lint/CrossfadeDetector.kt b/compose/animation/animation-lint/src/main/java/androidx/compose/animation/lint/CrossfadeDetector.kt
index f3edff4..9dcc564 100644
--- a/compose/animation/animation-lint/src/main/java/androidx/compose/animation/lint/CrossfadeDetector.kt
+++ b/compose/animation/animation-lint/src/main/java/androidx/compose/animation/lint/CrossfadeDetector.kt
@@ -48,7 +48,8 @@
override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
if (method.isInPackageName(Names.Animation.PackageName)) {
- val lambdaArgument = node.valueArguments.filterIsInstance<ULambdaExpression>().first()
+ val lambdaArgument = node.valueArguments.filterIsInstance<ULambdaExpression>()
+ .firstOrNull() ?: return
lambdaArgument.findUnreferencedParameters().forEach { unreferencedParameter ->
val location = unreferencedParameter.parameter
diff --git a/compose/animation/animation-lint/src/test/java/androidx/compose/animation/lint/CrossfadeDetectorTest.kt b/compose/animation/animation-lint/src/test/java/androidx/compose/animation/lint/CrossfadeDetectorTest.kt
index 9b483b1..180b874 100644
--- a/compose/animation/animation-lint/src/test/java/androidx/compose/animation/lint/CrossfadeDetectorTest.kt
+++ b/compose/animation/animation-lint/src/test/java/androidx/compose/animation/lint/CrossfadeDetectorTest.kt
@@ -177,6 +177,9 @@
Crossfade(foo) { param -> if (param) { /**/ } else { /**/ } }
Crossfade(foo, content = { param -> if (param) { /**/ } else { /**/ } })
+ val content : @Composable (Boolean) -> Unit = {}
+ Crossfade(foo, content = content)
+
Crossfade(foo) { param ->
foo.let {
it.let {
diff --git a/compose/foundation/foundation/build.gradle b/compose/foundation/foundation/build.gradle
index 80a5550..7d4b5d7 100644
--- a/compose/foundation/foundation/build.gradle
+++ b/compose/foundation/foundation/build.gradle
@@ -70,9 +70,9 @@
androidTestImplementation(ESPRESSO_CORE)
androidTestImplementation(JUNIT)
androidTestImplementation(TRUTH)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own
// MockMaker
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(MOCKITO_KOTLIN, {
exclude group: "org.mockito" // to keep control on the mockito version
})
@@ -136,9 +136,9 @@
implementation(ESPRESSO_CORE)
implementation(JUNIT)
implementation(TRUTH)
- implementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own
+ implementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own
// MockMaker
- implementation(MOCKITO_CORE, libs.exclude_bytebuddy)
+ implementation(MOCKITO_CORE, excludes.bytebuddy)
// DexMaker has it"s own MockMaker
implementation(MOCKITO_KOTLIN, {
exclude group: "org.mockito" // to keep control on the mockito version
diff --git a/compose/material/material/build.gradle b/compose/material/material/build.gradle
index dbc14ae..b7f40da 100644
--- a/compose/material/material/build.gradle
+++ b/compose/material/material/build.gradle
@@ -61,8 +61,8 @@
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(JUNIT)
androidTestImplementation(TRUTH)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(MOCKITO_KOTLIN, {
exclude group: "org.mockito" // to keep control on the mockito version
})
@@ -120,8 +120,8 @@
implementation(ANDROIDX_TEST_RUNNER)
implementation(JUNIT)
implementation(TRUTH)
- implementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- implementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ implementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ implementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
implementation(MOCKITO_KOTLIN, {
exclude group: "org.mockito" // to keep control on the mockito version
})
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextFieldDefaults.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextFieldDefaults.kt
index 3432747..c77f622 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextFieldDefaults.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextFieldDefaults.kt
@@ -18,20 +18,16 @@
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.tween
-import androidx.compose.foundation.interaction.FocusInteraction
-import androidx.compose.foundation.interaction.Interaction
import androidx.compose.foundation.interaction.InteractionSource
+import androidx.compose.foundation.interaction.collectIsFocusedAsState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
-import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
-import androidx.compose.runtime.mutableStateListOf
-import androidx.compose.runtime.remember
+import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
-import kotlinx.coroutines.flow.collect
/**
* Represents the colors of the input text, background and content (including label, placeholder,
@@ -327,25 +323,12 @@
isError: Boolean,
interactionSource: InteractionSource
): State<Color> {
- val interactions = remember { mutableStateListOf<Interaction>() }
- LaunchedEffect(interactionSource) {
- interactionSource.interactions.collect { interaction ->
- when (interaction) {
- is FocusInteraction.Focus -> {
- interactions.add(interaction)
- }
- is FocusInteraction.Unfocus -> {
- interactions.remove(interaction.focus)
- }
- }
- }
- }
- val interaction = interactions.lastOrNull()
+ val focused by interactionSource.collectIsFocusedAsState()
val targetValue = when {
!enabled -> disabledIndicatorColor
isError -> errorIndicatorColor
- interaction is FocusInteraction.Focus -> focusedIndicatorColor
+ focused -> focusedIndicatorColor
else -> unfocusedIndicatorColor
}
return if (enabled) {
@@ -371,25 +354,12 @@
error: Boolean,
interactionSource: InteractionSource
): State<Color> {
- val interactions = remember { mutableStateListOf<Interaction>() }
- LaunchedEffect(interactionSource) {
- interactionSource.interactions.collect { interaction ->
- when (interaction) {
- is FocusInteraction.Focus -> {
- interactions.add(interaction)
- }
- is FocusInteraction.Unfocus -> {
- interactions.remove(interaction.focus)
- }
- }
- }
- }
- val interaction = interactions.lastOrNull()
+ val focused by interactionSource.collectIsFocusedAsState()
val targetValue = when {
!enabled -> disabledLabelColor
error -> errorLabelColor
- interaction is FocusInteraction.Focus -> focusedLabelColor
+ focused -> focusedLabelColor
else -> unfocusedLabelColor
}
return if (enabled) {
diff --git a/compose/runtime/runtime-saveable/build.gradle b/compose/runtime/runtime-saveable/build.gradle
index eaf9e66..2c030ea 100644
--- a/compose/runtime/runtime-saveable/build.gradle
+++ b/compose/runtime/runtime-saveable/build.gradle
@@ -57,9 +57,9 @@
androidTestImplementation(ESPRESSO_CORE)
androidTestImplementation(JUNIT)
androidTestImplementation(TRUTH)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
// DexMaker has it"s own MockMaker
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
// DexMaker has it"s own MockMaker
lintPublish(project(":compose:runtime:runtime-saveable-lint"))
@@ -105,9 +105,9 @@
implementation(ESPRESSO_CORE)
implementation(JUNIT)
implementation(TRUTH)
- implementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ implementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
// DexMaker has it"s own MockMaker
- implementation(MOCKITO_CORE, libs.exclude_bytebuddy)
+ implementation(MOCKITO_CORE, excludes.bytebuddy)
// DexMaker has it"s own MockMaker
}
}
diff --git a/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTreeTest.kt b/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTreeTest.kt
index 87b2e16..b40bfcc 100644
--- a/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTreeTest.kt
+++ b/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTreeTest.kt
@@ -153,47 +153,46 @@
val builder = LayoutInspectorTree()
val nodes = builder.convert(view)
dumpNodes(nodes, view, builder)
+ val top = findTopPosition(view)
validate(nodes, builder) {
node(
name = "Column",
fileName = "LayoutInspectorTreeTest.kt",
- left = 0.0.dp, top = 0.0.dp, width = 72.0.dp, height = 78.9.dp,
+ left = 0.0.dp, top = top, width = 72.0.dp, height = 78.9.dp,
children = listOf("Text", "Icon", "Surface")
)
node(
name = "Text",
isRenderNode = true,
fileName = "LayoutInspectorTreeTest.kt",
- left = 0.0.dp, top = 0.0.dp, width = 72.0.dp, height = 18.9.dp,
+ left = 0.0.dp, top = top, width = 72.0.dp, height = 18.9.dp,
)
node(
name = "Icon",
isRenderNode = true,
fileName = "LayoutInspectorTreeTest.kt",
- left = 0.0.dp, top = 18.9.dp, width = 24.0.dp, height = 24.0.dp,
+ left = 0.0.dp, top = top + 18.9.dp, width = 24.0.dp, height = 24.0.dp,
)
node(
name = "Surface",
fileName = "LayoutInspectorTreeTest.kt",
isRenderNode = true,
- left = 0.0.dp,
- top = 42.9.dp, width = 64.0.dp, height = 36.0.dp,
+ left = 0.0.dp, top = top + 42.9.dp, width = 64.0.dp, height = 36.0.dp,
children = listOf("Button")
)
node(
name = "Button",
fileName = "LayoutInspectorTreeTest.kt",
isRenderNode = true,
- left = 0.0.dp,
- top = 42.9.dp, width = 64.0.dp, height = 36.0.dp,
+ left = 0.0.dp, top = top + 42.9.dp, width = 64.0.dp, height = 36.0.dp,
children = listOf("Text")
)
node(
name = "Text",
isRenderNode = true,
fileName = "LayoutInspectorTreeTest.kt",
- left = 21.7.dp, top = 51.6.dp, width = 20.9.dp, height = 18.9.dp,
+ left = 21.7.dp, top = top + 51.5.dp, width = 20.9.dp, height = 18.9.dp,
)
}
}
@@ -219,13 +218,14 @@
val builder = LayoutInspectorTree()
val nodes = builder.convert(view)
dumpNodes(nodes, view, builder)
+ val top = findTopPosition(view)
validate(nodes, builder) {
node(
name = "MaterialTheme",
hasTransformations = true,
fileName = "LayoutInspectorTreeTest.kt",
- left = 68.0.dp, top = 49.7.dp, width = 88.6.dp, height = 21.7.dp,
+ left = 68.0.dp, top = top + 49.8.dp, width = 88.6.dp, height = 21.7.dp,
children = listOf("Text")
)
node(
@@ -233,7 +233,7 @@
isRenderNode = true,
hasTransformations = true,
fileName = "LayoutInspectorTreeTest.kt",
- left = 68.0.dp, top = 49.7.dp, width = 88.6.dp, height = 21.7.dp,
+ left = 68.0.dp, top = top + 49.8.dp, width = 88.6.dp, height = 21.7.dp,
)
}
}
@@ -477,24 +477,59 @@
val builder = LayoutInspectorTree()
val nodes = builder.convert(appView)
dumpNodes(nodes, appView, builder)
+ val top = findTopPosition(appView)
// Verify that there are no Composable nodes from the dialog in the application itself:
validate(nodes, builder) {
node(
name = "Column",
fileName = "LayoutInspectorTreeTest.kt",
- left = 0.0.dp, top = 0.0.dp, width = 76.0.dp, height = 18.9.dp,
+ left = 0.0.dp, top = top, width = 76.0.dp, height = 18.9.dp,
children = listOf("Text")
)
node(
name = "Text",
isRenderNode = true,
fileName = "LayoutInspectorTreeTest.kt",
- left = 0.0.dp, top = 0.0.dp, width = 76.0.dp, height = 18.9.dp,
+ left = 0.0.dp, top = top, width = 76.0.dp, height = 18.9.dp,
)
}
}
+ @Test
+ fun testDialogLocation() {
+ val slotTableRecord = CompositionDataRecord.create()
+
+ show {
+ Inspectable(slotTableRecord) {
+ Column {
+ Text("Hello World!")
+ AlertDialog(
+ onDismissRequest = {},
+ confirmButton = {
+ Button({}) {
+ Text("This is the Confirm Button")
+ }
+ }
+ )
+ }
+ }
+ }
+ val composeViews = findAllAndroidComposeViews()
+ val dialogView = composeViews[1] // composeView[0] contains the contents of the app
+ val dialogLocation = IntArray(2)
+ dialogView.getLocationOnScreen(dialogLocation)
+ dialogView.setTag(R.id.inspection_slot_table_set, slotTableRecord.store)
+ val builder = LayoutInspectorTree()
+ val button = builder.convert(dialogView)
+ .flatMap { flatten(it) }
+ .single { it.name == "Button" }
+ assertThat(button.left).isGreaterThan(dialogLocation[0])
+ assertThat(button.top).isGreaterThan(dialogLocation[1])
+ assertThat(button.width).isLessThan(dialogView.width)
+ assertThat(button.height).isLessThan(dialogView.height)
+ }
+
@Suppress("SameParameterValue")
private fun validate(
result: List<InspectorNode>,
@@ -592,6 +627,12 @@
private fun flatten(node: InspectorNode): List<InspectorNode> =
listOf(node).plus(node.children.flatMap { flatten(it) })
+ private fun findTopPosition(view: View): Dp {
+ val location = IntArray(2)
+ view.getLocationOnScreen(location)
+ return with(density) { location[1].toDp() }
+ }
+
// region DEBUG print methods
private fun dumpNodes(nodes: List<InspectorNode>, view: View, builder: LayoutInspectorTree) {
@Suppress("ConstantConditionIf")
diff --git a/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTree.kt b/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTree.kt
index ccacc3b..68a2185 100644
--- a/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTree.kt
+++ b/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTree.kt
@@ -85,6 +85,7 @@
private val parameterFactory = ParameterFactory(inlineClassConverter)
private val cache = ArrayDeque<MutableInspectorNode>()
private var generatedId = -1L
+ private val rootLocation = IntArray(2)
/** Map from [LayoutInfo] to the nearest [InspectorNode] that contains it */
private val claimedNodes = IdentityHashMap<LayoutInfo, InspectorNode>()
/** Map from parent tree to child trees that are about to be stitched together */
@@ -192,6 +193,8 @@
}
private fun clear() {
+ rootLocation[0] = 0
+ rootLocation[1] = 0
cache.clear()
inlineClassConverter.clear()
claimedNodes.clear()
@@ -203,6 +206,7 @@
@OptIn(InternalComposeApi::class)
private fun convert(tables: Set<CompositionData>, view: View): List<InspectorNode> {
+ view.getLocationOnScreen(rootLocation)
val trees = tables.mapNotNull { convert(it, view) }
return when (trees.size) {
0 -> listOf()
@@ -414,8 +418,8 @@
@OptIn(UiToolingDataApi::class)
private fun parsePosition(group: Group, node: MutableInspectorNode) {
val box = group.box
- node.top = box.top
- node.left = box.left
+ node.top = box.top + rootLocation[1]
+ node.left = box.left + rootLocation[0]
node.height = box.bottom - box.top
node.width = box.right - box.left
}
diff --git a/compose/ui/ui-test-junit4/build.gradle b/compose/ui/ui-test-junit4/build.gradle
index 1130408..1923226 100644
--- a/compose/ui/ui-test-junit4/build.gradle
+++ b/compose/ui/ui-test-junit4/build.gradle
@@ -57,8 +57,8 @@
androidTestImplementation(ANDROIDX_TEST_RULES)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(TRUTH)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(MOCKITO_KOTLIN, {
exclude group: "org.mockito" // to keep control on the mockito version
})
@@ -108,8 +108,8 @@
implementation(ANDROIDX_TEST_RULES)
implementation(ANDROIDX_TEST_RUNNER)
implementation(TRUTH)
- implementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- implementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ implementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ implementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
implementation(MOCKITO_KOTLIN, {
exclude group: "org.mockito" // to keep control on the mockito version
})
diff --git a/compose/ui/ui-test/build.gradle b/compose/ui/ui-test/build.gradle
index 4f251e1..19de9f8 100644
--- a/compose/ui/ui-test/build.gradle
+++ b/compose/ui/ui-test/build.gradle
@@ -52,8 +52,8 @@
androidTestImplementation(project(":compose:test-utils"))
androidTestImplementation(project(":compose:ui:ui-test-junit4"))
androidTestImplementation(TRUTH)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(MOCKITO_KOTLIN, {
exclude group: "org.mockito" // to keep control on the mockito version
})
@@ -96,8 +96,8 @@
implementation(project(":compose:ui:ui-test-junit4"))
implementation(project(":activity:activity-compose"))
implementation(TRUTH)
- implementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- implementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ implementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ implementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
implementation(MOCKITO_KOTLIN, {
exclude group: "org.mockito" // to keep control on the mockito version
})
diff --git a/compose/ui/ui-text/build.gradle b/compose/ui/ui-text/build.gradle
index 07f2cfb..f3bb4c5 100644
--- a/compose/ui/ui-text/build.gradle
+++ b/compose/ui/ui-text/build.gradle
@@ -66,9 +66,9 @@
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ESPRESSO_CORE)
androidTestImplementation(JUNIT)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
// DexMaker has it"s own MockMaker
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
androidTestImplementation(TRUTH)
androidTestImplementation(MOCKITO_KOTLIN, {
exclude group: "org.mockito" // to keep control on the mockito version
@@ -139,9 +139,9 @@
implementation(ANDROIDX_TEST_RUNNER)
implementation(ESPRESSO_CORE)
implementation(JUNIT)
- implementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ implementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
// DexMaker has it"s own MockMaker
- implementation(MOCKITO_CORE, libs.exclude_bytebuddy)
+ implementation(MOCKITO_CORE, excludes.bytebuddy)
implementation(TRUTH)
implementation(MOCKITO_KOTLIN, {
exclude group: "org.mockito" // to keep control on the mockito version
diff --git a/compose/ui/ui/build.gradle b/compose/ui/ui/build.gradle
index 1517399..80bb64e 100644
--- a/compose/ui/ui/build.gradle
+++ b/compose/ui/ui/build.gradle
@@ -86,9 +86,9 @@
androidTestImplementation(KOTLIN_COROUTINES_TEST)
androidTestImplementation(ESPRESSO_CORE)
androidTestImplementation(JUNIT)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
// DexMaker has it"s own MockMaker
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
// DexMaker has it"s own MockMaker
androidTestImplementation(TRUTH)
androidTestImplementation(MOCKITO_KOTLIN, {
@@ -190,9 +190,9 @@
implementation(KOTLIN_COROUTINES_TEST)
implementation(ESPRESSO_CORE)
implementation(JUNIT)
- implementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ implementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
// DexMaker has it"s own MockMaker
- implementation(MOCKITO_CORE, libs.exclude_bytebuddy)
+ implementation(MOCKITO_CORE, excludes.bytebuddy)
// DexMaker has it"s own MockMaker
implementation(TRUTH)
implementation(MOCKITO_KOTLIN, {
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/desktop/AppWindow.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/desktop/AppWindow.desktop.kt
index 874e013..071661a 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/desktop/AppWindow.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/desktop/AppWindow.desktop.kt
@@ -111,7 +111,7 @@
"AppWindow should be created inside AWT Event Thread (use SwingUtilities.invokeLater " +
"or just dsl for creating window: Window { })"
}
- window = ComposeWindow(parent = this)
+ window = ComposeWindow()
window.apply {
defaultCloseOperation = WindowConstants.DISPOSE_ON_CLOSE
addWindowListener(object : WindowAdapter() {
@@ -122,7 +122,7 @@
onDispose?.invoke()
onDismiss?.invoke()
events.invokeOnClose()
- AppManager.removeWindow(parent)
+ AppManager.removeWindow(this@AppWindow)
}
}
}
@@ -137,7 +137,7 @@
override fun windowGainedFocus(event: WindowEvent) {
// Dialogs should not receive a common application menu bar
if (invoker == null) {
- window.setJMenuBar(parent.menuBar?.menuBar)
+ window.setJMenuBar([email protected]?.menuBar)
}
events.invokeOnFocusGet()
}
@@ -417,7 +417,6 @@
window.setContent(parentComposition) {
CompositionLocalProvider(
LocalAppWindow provides this,
- LocalLayerContainer provides window,
content = content
)
}
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/desktop/ComposeWindow.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/desktop/ComposeWindow.desktop.kt
index 90c25cf..273b3b0 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/desktop/ComposeWindow.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/desktop/ComposeWindow.desktop.kt
@@ -17,6 +17,7 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionContext
+import androidx.compose.runtime.CompositionLocalProvider
import org.jetbrains.skiko.ClipComponent
import org.jetbrains.skiko.GraphicsApi
import java.awt.Component
@@ -26,9 +27,8 @@
/**
* ComposeWindow is a window for building UI using Compose for Desktop.
* ComposeWindow inherits javax.swing.JFrame.
- * @param parent The parent AppFrame that wraps the ComposeWindow.
*/
-class ComposeWindow(val parent: AppFrame) : JFrame() {
+class ComposeWindow : JFrame() {
private var isDisposed = false
internal val layer = ComposeLayer()
private val pane = object : JLayeredPane() {
@@ -73,8 +73,13 @@
) {
layer.setContent(
parentComposition = parentComposition,
- content = content
- )
+ ) {
+ CompositionLocalProvider(
+ LocalLayerContainer provides this
+ ) {
+ content()
+ }
+ }
}
override fun dispose() {
diff --git a/contentpager/contentpager/build.gradle b/contentpager/contentpager/build.gradle
index 33bc9f0..17c5064 100644
--- a/contentpager/contentpager/build.gradle
+++ b/contentpager/contentpager/build.gradle
@@ -34,7 +34,7 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
}
androidx {
diff --git a/coordinatorlayout/coordinatorlayout/build.gradle b/coordinatorlayout/coordinatorlayout/build.gradle
index 98639d0..a6a6937 100644
--- a/coordinatorlayout/coordinatorlayout/build.gradle
+++ b/coordinatorlayout/coordinatorlayout/build.gradle
@@ -18,10 +18,10 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(ESPRESSO_CONTRIB, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(ESPRESSO_CONTRIB, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(project(":internal-testutils-runtime"), {
exclude group: "androidx.coordinatorlayout", module: "coordinatorlayout"
})
diff --git a/core/core-animation-integration-tests/testapp/build.gradle b/core/core-animation-integration-tests/testapp/build.gradle
index 5e2863f..f1a3103 100644
--- a/core/core-animation-integration-tests/testapp/build.gradle
+++ b/core/core-animation-integration-tests/testapp/build.gradle
@@ -27,7 +27,7 @@
implementation(project(":core:core-animation"))
implementation(project(":core:core-animation-testing"))
- implementation(ANDROIDX_TEST_EXT_JUNIT, libs.exclude_for_espresso)
- implementation(ANDROIDX_TEST_CORE, libs.exclude_for_espresso)
- implementation(ANDROIDX_TEST_RULES, libs.exclude_for_espresso)
+ implementation(ANDROIDX_TEST_EXT_JUNIT, excludes.espresso)
+ implementation(ANDROIDX_TEST_CORE, excludes.espresso)
+ implementation(ANDROIDX_TEST_RULES, excludes.espresso)
}
diff --git a/core/core-animation/build.gradle b/core/core-animation/build.gradle
index 2b4bbef..d7061d3 100644
--- a/core/core-animation/build.gradle
+++ b/core/core-animation/build.gradle
@@ -29,8 +29,8 @@
implementation("androidx.core:core:1.3.1")
implementation("androidx.collection:collection:1.1.0")
- androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT, libs.exclude_for_espresso)
- androidTestImplementation(ANDROIDX_TEST_RULES, libs.exclude_for_espresso)
+ androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT, excludes.espresso)
+ androidTestImplementation(ANDROIDX_TEST_RULES, excludes.espresso)
}
androidx {
diff --git a/core/core-google-shortcuts/build.gradle b/core/core-google-shortcuts/build.gradle
index 56bca79..2484a3a 100644
--- a/core/core-google-shortcuts/build.gradle
+++ b/core/core-google-shortcuts/build.gradle
@@ -47,8 +47,8 @@
androidTestImplementation(ANDROIDX_TEST_RULES)
androidTestImplementation(ESPRESSO_CORE)
androidTestImplementation(ESPRESSO_INTENTS)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
androidTestImplementation(TRUTH)
}
diff --git a/core/core/build.gradle b/core/core/build.gradle
index 80c146b..4b127c1 100644
--- a/core/core/build.gradle
+++ b/core/core/build.gradle
@@ -24,15 +24,15 @@
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
androidTestImplementation(TRUTH)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(MULTIDEX)
// Including both dexmakers allows support for all API levels plus final mocking support on
// API 28+. The implementation is swapped based on the finality of the mock type. This
// delegation is handled manually inside androidx.core.util.mockito.CustomMockMaker.
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO_INLINE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO_INLINE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation("androidx.appcompat:appcompat:1.1.0") {
exclude group: "androidx.core", module: "core"
}
diff --git a/core/core/lint-baseline.xml b/core/core/lint-baseline.xml
index e683e40..978eb9b 100644
--- a/core/core/lint-baseline.xml
+++ b/core/core/lint-baseline.xml
@@ -30,7 +30,7 @@
errorLine2=" ^">
<location
file="src/main/java/androidx/core/content/ContextCompat.java"
- line="605"
+ line="602"
column="5"/>
</issue>
@@ -228,7 +228,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/content/res/ResourcesCompat.java"
- line="553"
+ line="679"
column="29"/>
</issue>
@@ -239,7 +239,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/widget/TextViewCompat.java"
- line="605"
+ line="625"
column="25"/>
</issue>
@@ -2962,193 +2962,6 @@
<issue
id="ClassVerificationFailure"
- message="This call references a method added in API level 16; however, the containing class androidx.core.content.ContextCompat is reachable from earlier API levels and will fail run-time class verification."
- errorLine1=" context.startActivities(intents, options);"
- errorLine2=" ~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/core/content/ContextCompat.java"
- line="240"
- column="21"/>
- </issue>
-
- <issue
- id="ClassVerificationFailure"
- message="This call references a method added in API level 16; however, the containing class androidx.core.content.ContextCompat is reachable from earlier API levels and will fail run-time class verification."
- errorLine1=" context.startActivity(intent, options);"
- errorLine2=" ~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/core/content/ContextCompat.java"
- line="267"
- column="21"/>
- </issue>
-
- <issue
- id="ClassVerificationFailure"
- message="This call references a method added in API level 24; however, the containing class androidx.core.content.ContextCompat is reachable from earlier API levels and will fail run-time class verification."
- errorLine1=" return context.getDataDir();"
- errorLine2=" ~~~~~~~~~~">
- <location
- file="src/main/java/androidx/core/content/ContextCompat.java"
- line="291"
- column="28"/>
- </issue>
-
- <issue
- id="ClassVerificationFailure"
- message="This call references a method added in API level 19; however, the containing class androidx.core.content.ContextCompat is reachable from earlier API levels and will fail run-time class verification."
- errorLine1=" return context.getObbDirs();"
- errorLine2=" ~~~~~~~~~~">
- <location
- file="src/main/java/androidx/core/content/ContextCompat.java"
- line="344"
- column="28"/>
- </issue>
-
- <issue
- id="ClassVerificationFailure"
- message="This call references a method added in API level 19; however, the containing class androidx.core.content.ContextCompat is reachable from earlier API levels and will fail run-time class verification."
- errorLine1=" return context.getExternalFilesDirs(type);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/core/content/ContextCompat.java"
- line="397"
- column="28"/>
- </issue>
-
- <issue
- id="ClassVerificationFailure"
- message="This call references a method added in API level 19; however, the containing class androidx.core.content.ContextCompat is reachable from earlier API levels and will fail run-time class verification."
- errorLine1=" return context.getExternalCacheDirs();"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/core/content/ContextCompat.java"
- line="450"
- column="28"/>
- </issue>
-
- <issue
- id="ClassVerificationFailure"
- message="This call references a method added in API level 21; however, the containing class androidx.core.content.ContextCompat is reachable from earlier API levels and will fail run-time class verification."
- errorLine1=" return context.getDrawable(id);"
- errorLine2=" ~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/core/content/ContextCompat.java"
- line="471"
- column="28"/>
- </issue>
-
- <issue
- id="ClassVerificationFailure"
- message="This call references a method added in API level 23; however, the containing class androidx.core.content.ContextCompat is reachable from earlier API levels and will fail run-time class verification."
- errorLine1=" return context.getColorStateList(id);"
- errorLine2=" ~~~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/core/content/ContextCompat.java"
- line="510"
- column="28"/>
- </issue>
-
- <issue
- id="ClassVerificationFailure"
- message="This call references a method added in API level 23; however, the containing class androidx.core.content.ContextCompat is reachable from earlier API levels and will fail run-time class verification."
- errorLine1=" return context.getColor(id);"
- errorLine2=" ~~~~~~~~">
- <location
- file="src/main/java/androidx/core/content/ContextCompat.java"
- line="533"
- column="28"/>
- </issue>
-
- <issue
- id="ClassVerificationFailure"
- message="This call references a method added in API level 21; however, the containing class androidx.core.content.ContextCompat is reachable from earlier API levels and will fail run-time class verification."
- errorLine1=" return context.getNoBackupFilesDir();"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/core/content/ContextCompat.java"
- line="574"
- column="28"/>
- </issue>
-
- <issue
- id="ClassVerificationFailure"
- message="This call references a method added in API level 21; however, the containing class androidx.core.content.ContextCompat is reachable from earlier API levels and will fail run-time class verification."
- errorLine1=" return context.getCodeCacheDir();"
- errorLine2=" ~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/core/content/ContextCompat.java"
- line="598"
- column="28"/>
- </issue>
-
- <issue
- id="ClassVerificationFailure"
- message="This call references a method added in API level 24; however, the containing class androidx.core.content.ContextCompat is reachable from earlier API levels and will fail run-time class verification."
- errorLine1=" return context.createDeviceProtectedStorageContext();"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/core/content/ContextCompat.java"
- line="653"
- column="28"/>
- </issue>
-
- <issue
- id="ClassVerificationFailure"
- message="This call references a method added in API level 24; however, the containing class androidx.core.content.ContextCompat is reachable from earlier API levels and will fail run-time class verification."
- errorLine1=" return context.isDeviceProtectedStorage();"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/core/content/ContextCompat.java"
- line="667"
- column="28"/>
- </issue>
-
- <issue
- id="ClassVerificationFailure"
- message="This call references a method added in API level 28; however, the containing class androidx.core.content.ContextCompat is reachable from earlier API levels and will fail run-time class verification."
- errorLine1=" return context.getMainExecutor();"
- errorLine2=" ~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/core/content/ContextCompat.java"
- line="680"
- column="28"/>
- </issue>
-
- <issue
- id="ClassVerificationFailure"
- message="This call references a method added in API level 26; however, the containing class androidx.core.content.ContextCompat is reachable from earlier API levels and will fail run-time class verification."
- errorLine1=" context.startForegroundService(intent);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/core/content/ContextCompat.java"
- line="697"
- column="21"/>
- </issue>
-
- <issue
- id="ClassVerificationFailure"
- message="This call references a method added in API level 23; however, the containing class androidx.core.content.ContextCompat is reachable from earlier API levels and will fail run-time class verification."
- errorLine1=" return context.getSystemService(serviceClass);"
- errorLine2=" ~~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/core/content/ContextCompat.java"
- line="717"
- column="28"/>
- </issue>
-
- <issue
- id="ClassVerificationFailure"
- message="This call references a method added in API level 23; however, the containing class androidx.core.content.ContextCompat is reachable from earlier API levels and will fail run-time class verification."
- errorLine1=" return context.getSystemServiceName(serviceClass);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/core/content/ContextCompat.java"
- line="737"
- column="28"/>
- </issue>
-
- <issue
- id="ClassVerificationFailure"
message="This call references a method added in API level 28; however, the containing class androidx.core.database.CursorWindowCompat is reachable from earlier API levels and will fail run-time class verification."
errorLine1=" return new CursorWindow(name, windowSizeBytes);"
errorLine2=" ~~~~~~~~~~~~~~~~">
@@ -8467,7 +8280,7 @@
errorLine2=" ~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/content/res/ResourcesCompat.java"
- line="95"
+ line="104"
column="24"/>
</issue>
@@ -8478,7 +8291,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/content/res/ResourcesCompat.java"
- line="128"
+ line="137"
column="24"/>
</issue>
@@ -8489,7 +8302,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/content/res/ResourcesCompat.java"
- line="130"
+ line="139"
column="24"/>
</issue>
@@ -8500,7 +8313,7 @@
errorLine2=" ~~~~~~~~">
<location
file="src/main/java/androidx/core/content/res/ResourcesCompat.java"
- line="158"
+ line="167"
column="24"/>
</issue>
@@ -8511,7 +8324,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/content/res/ResourcesCompat.java"
- line="188"
+ line="195"
column="24"/>
</issue>
@@ -9908,7 +9721,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/widget/TextViewCompat.java"
- line="695"
+ line="715"
column="22"/>
</issue>
@@ -9919,7 +9732,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/widget/TextViewCompat.java"
- line="704"
+ line="724"
column="29"/>
</issue>
@@ -9930,7 +9743,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/widget/TextViewCompat.java"
- line="745"
+ line="765"
column="29"/>
</issue>
@@ -9941,7 +9754,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/widget/TextViewCompat.java"
- line="816"
+ line="836"
column="62"/>
</issue>
@@ -9952,7 +9765,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/widget/TextViewCompat.java"
- line="821"
+ line="841"
column="51"/>
</issue>
@@ -9963,7 +9776,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/widget/TextViewCompat.java"
- line="822"
+ line="842"
column="58"/>
</issue>
@@ -9974,7 +9787,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/widget/TextViewCompat.java"
- line="843"
+ line="863"
column="22"/>
</issue>
@@ -9985,7 +9798,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/widget/TextViewCompat.java"
- line="866"
+ line="886"
column="22"/>
</issue>
@@ -9996,7 +9809,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/widget/TextViewCompat.java"
- line="867"
+ line="887"
column="22"/>
</issue>
@@ -10007,7 +9820,7 @@
errorLine2=" ~~~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/widget/TextViewCompat.java"
- line="919"
+ line="939"
column="67"/>
</issue>
@@ -10018,7 +9831,7 @@
errorLine2=" ~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/widget/TextViewCompat.java"
- line="919"
+ line="939"
column="46"/>
</issue>
@@ -10029,7 +9842,7 @@
errorLine2=" ~~~~~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/widget/TextViewCompat.java"
- line="920"
+ line="940"
column="45"/>
</issue>
@@ -10040,7 +9853,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/widget/TextViewCompat.java"
- line="935"
+ line="955"
column="48"/>
</issue>
@@ -10051,7 +9864,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/widget/TextViewCompat.java"
- line="938"
+ line="958"
column="26"/>
</issue>
@@ -10062,7 +9875,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/widget/TextViewCompat.java"
- line="995"
+ line="1015"
column="22"/>
</issue>
@@ -10073,7 +9886,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/widget/TextViewCompat.java"
- line="1011"
+ line="1031"
column="29"/>
</issue>
@@ -10084,7 +9897,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/widget/TextViewCompat.java"
- line="1029"
+ line="1049"
column="22"/>
</issue>
@@ -10095,7 +9908,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/widget/TextViewCompat.java"
- line="1046"
+ line="1066"
column="29"/>
</issue>
@@ -11745,7 +11558,7 @@
errorLine2=" ~~~~~~~~~~~~~">
<location
file="src/main/java/androidx/core/content/ContextCompat.java"
- line="150"
+ line="156"
column="14"/>
</issue>
@@ -14626,7 +14439,7 @@
errorLine2=" ~~~~">
<location
file="src/main/java/androidx/core/content/ContextCompat.java"
- line="596"
+ line="593"
column="19"/>
</issue>
@@ -14637,7 +14450,7 @@
errorLine2=" ~~~~~~~~">
<location
file="src/main/java/androidx/core/content/ContextCompat.java"
- line="678"
+ line="675"
column="19"/>
</issue>
@@ -14648,7 +14461,7 @@
errorLine2=" ~~~~~~~">
<location
file="src/main/java/androidx/core/content/ContextCompat.java"
- line="678"
+ line="675"
column="44"/>
</issue>
@@ -18135,7 +17948,7 @@
errorLine2=" ~~~~~~~~">
<location
file="src/main/java/androidx/core/content/res/ResourcesCompat.java"
- line="307"
+ line="433"
column="54"/>
</issue>
@@ -18146,7 +17959,7 @@
errorLine2=" ~~~~~~~~">
<location
file="src/main/java/androidx/core/content/res/ResourcesCompat.java"
- line="376"
+ line="502"
column="19"/>
</issue>
@@ -18157,7 +17970,7 @@
errorLine2=" ~~~~~~~~~~">
<location
file="src/main/java/androidx/core/content/res/ResourcesCompat.java"
- line="376"
+ line="502"
column="79"/>
</issue>
diff --git a/core/core/src/main/java/androidx/core/content/ContextCompat.java b/core/core/src/main/java/androidx/core/content/ContextCompat.java
index d92b30f..882f35b 100644
--- a/core/core/src/main/java/androidx/core/content/ContextCompat.java
+++ b/core/core/src/main/java/androidx/core/content/ContextCompat.java
@@ -84,11 +84,13 @@
import android.appwidget.AppWidgetManager;
import android.bluetooth.BluetoothManager;
import android.content.ClipboardManager;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.RestrictionsManager;
import android.content.pm.ApplicationInfo;
import android.content.pm.LauncherApps;
+import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.graphics.drawable.Drawable;
import android.hardware.ConsumerIrManager;
@@ -115,6 +117,7 @@
import android.os.Handler;
import android.os.PowerManager;
import android.os.Process;
+import android.os.StatFs;
import android.os.UserManager;
import android.os.Vibrator;
import android.os.storage.StorageManager;
@@ -133,9 +136,11 @@
import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
+import androidx.annotation.DoNotInline;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import androidx.core.app.ActivityOptionsCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.core.os.EnvironmentCompat;
@@ -146,7 +151,7 @@
import java.util.concurrent.Executor;
/**
- * Helper for accessing features in {@link android.content.Context}.
+ * Helper for accessing features in {@link Context}.
*/
public class ContextCompat {
private static final String TAG = "ContextCompat";
@@ -173,7 +178,7 @@
@Nullable
public static String getAttributionTag(@NonNull Context context) {
if (Build.VERSION.SDK_INT >= 30) {
- return context.getAttributionTag();
+ return Api30Impl.getAttributionTag(context);
}
return null;
@@ -232,13 +237,13 @@
* @param intents Array of intents defining the activities that will be started. The element
* length-1 will correspond to the top activity on the resulting task stack.
* @param options Additional options for how the Activity should be started.
- * See {@link android.content.Context#startActivity(Intent, android.os.Bundle)}
+ * See {@link Context#startActivity(Intent, Bundle)}
* @return true if the underlying API was available and the call was successful, false otherwise
*/
public static boolean startActivities(@NonNull Context context, @NonNull Intent[] intents,
@Nullable Bundle options) {
if (Build.VERSION.SDK_INT >= 16) {
- context.startActivities(intents, options);
+ Api16Impl.startActivities(context, intents, options);
} else {
context.startActivities(intents);
}
@@ -255,7 +260,7 @@
* not exist the activity will be launched normally.</p>
*
* @param context Context to launch activity from.
- * @param intent The description of the activity to start.
+ * @param intent The description of the activity to start.
* @param options Additional options for how the Activity should be started.
* May be null if there are no options. See
* {@link ActivityOptionsCompat} for how to build the Bundle
@@ -265,7 +270,7 @@
public static void startActivity(@NonNull Context context, @NonNull Intent intent,
@Nullable Bundle options) {
if (Build.VERSION.SDK_INT >= 16) {
- context.startActivity(intent, options);
+ Api16Impl.startActivity(context, intent, options);
} else {
context.startActivity(intent);
}
@@ -289,7 +294,7 @@
@Nullable
public static File getDataDir(@NonNull Context context) {
if (Build.VERSION.SDK_INT >= 24) {
- return context.getDataDir();
+ return Api24Impl.getDataDir(context);
} else {
final String dataDir = context.getApplicationInfo().dataDir;
return dataDir != null ? new File(dataDir) : null;
@@ -318,9 +323,9 @@
* <p>
* An application may store data on any or all of the returned devices. For
* example, an app may choose to store large files on the device with the
- * most available space, as measured by {@link android.os.StatFs}.
+ * most available space, as measured by {@link StatFs}.
* <p>
- * Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions
+ * Starting in {@link Build.VERSION_CODES#KITKAT}, no permissions
* are required to write to the returned paths; they're always accessible to
* the calling app. Before then,
* {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} is required to
@@ -342,9 +347,9 @@
@NonNull
public static File[] getObbDirs(@NonNull Context context) {
if (Build.VERSION.SDK_INT >= 19) {
- return context.getObbDirs();
+ return Api19Impl.getObbDirs(context);
} else {
- return new File[] { context.getObbDir() };
+ return new File[]{context.getObbDir()};
}
}
@@ -370,9 +375,9 @@
* <p>
* An application may store data on any or all of the returned devices. For
* example, an app may choose to store large files on the device with the
- * most available space, as measured by {@link android.os.StatFs}.
+ * most available space, as measured by {@link StatFs}.
* <p>
- * Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions
+ * Starting in {@link Build.VERSION_CODES#KITKAT}, no permissions
* are required to write to the returned paths; they're always accessible to
* the calling app. Before then,
* {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} is required to
@@ -395,9 +400,9 @@
@NonNull
public static File[] getExternalFilesDirs(@NonNull Context context, @Nullable String type) {
if (Build.VERSION.SDK_INT >= 19) {
- return context.getExternalFilesDirs(type);
+ return Api19Impl.getExternalFilesDirs(context, type);
} else {
- return new File[] { context.getExternalFilesDir(type) };
+ return new File[]{context.getExternalFilesDir(type)};
}
}
@@ -423,9 +428,9 @@
* <p>
* An application may store data on any or all of the returned devices. For
* example, an app may choose to store large files on the device with the
- * most available space, as measured by {@link android.os.StatFs}.
+ * most available space, as measured by {@link StatFs}.
* <p>
- * Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions
+ * Starting in {@link Build.VERSION_CODES#KITKAT}, no permissions
* are required to write to the returned paths; they're always accessible to
* the calling app. Before then,
* {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} is required to
@@ -448,16 +453,16 @@
@NonNull
public static File[] getExternalCacheDirs(@NonNull Context context) {
if (Build.VERSION.SDK_INT >= 19) {
- return context.getExternalCacheDirs();
+ return Api19Impl.getExternalCacheDirs(context);
} else {
- return new File[] { context.getExternalCacheDir() };
+ return new File[]{context.getExternalCacheDir()};
}
}
/**
* Returns a drawable object associated with a particular resource ID.
* <p>
- * Starting in {@link android.os.Build.VERSION_CODES#LOLLIPOP}, the
+ * Starting in {@link Build.VERSION_CODES#LOLLIPOP}, the
* returned drawable will be styled for the specified Context's theme.
*
* @param id The desired resource identifier, as generated by the aapt tool.
@@ -469,7 +474,7 @@
@Nullable
public static Drawable getDrawable(@NonNull Context context, @DrawableRes int id) {
if (Build.VERSION.SDK_INT >= 21) {
- return context.getDrawable(id);
+ return Api21Impl.getDrawable(context, id);
} else if (Build.VERSION.SDK_INT >= 16) {
return context.getResources().getDrawable(id);
} else {
@@ -492,14 +497,14 @@
/**
* Returns a color state list associated with a particular resource ID.
* <p>
- * Starting in {@link android.os.Build.VERSION_CODES#M}, the returned
+ * Starting in {@link Build.VERSION_CODES#M}, the returned
* color state list will be styled for the specified Context's theme.
*
* @param id The desired resource identifier, as generated by the aapt
* tool. This integer encodes the package, type, and resource
* entry. The value 0 is an invalid identifier.
* @return A color state list, or {@code null} if the resource could not be
- * resolved.
+ * resolved.
* @throws android.content.res.Resources.NotFoundException if the given ID
* does not exist.
*/
@@ -511,7 +516,7 @@
/**
* Returns a color associated with a particular resource ID
* <p>
- * Starting in {@link android.os.Build.VERSION_CODES#M}, the returned
+ * Starting in {@link Build.VERSION_CODES#M}, the returned
* color will be styled for the specified Context's theme.
*
* @param id The desired resource identifier, as generated by the aapt
@@ -525,7 +530,7 @@
@ColorInt
public static int getColor(@NonNull Context context, @ColorRes int id) {
if (Build.VERSION.SDK_INT >= 23) {
- return context.getColor(id);
+ return Api23Impl.getColor(context, id);
} else {
return context.getResources().getColor(id);
}
@@ -535,38 +540,35 @@
* Determine whether <em>you</em> have been granted a particular permission.
*
* @param permission The name of the permission being checked.
- *
- * @return {@link android.content.pm.PackageManager#PERMISSION_GRANTED} if you have the
- * permission, or {@link android.content.pm.PackageManager#PERMISSION_DENIED} if not.
- *
- * @see android.content.pm.PackageManager#checkPermission(String, String)
+ * @return {@link PackageManager#PERMISSION_GRANTED} if you have the
+ * permission, or {@link PackageManager#PERMISSION_DENIED} if not.
+ * @see PackageManager#checkPermission(String, String)
*/
public static int checkSelfPermission(@NonNull Context context, @NonNull String permission) {
if (permission == null) {
throw new IllegalArgumentException("permission is null");
}
- return context.checkPermission(permission, android.os.Process.myPid(), Process.myUid());
+ return context.checkPermission(permission, Process.myPid(), Process.myUid());
}
/**
* Returns the absolute path to the directory on the filesystem similar to
* {@link Context#getFilesDir()}. The difference is that files placed under this
* directory will be excluded from automatic backup to remote storage on
- * devices running {@link android.os.Build.VERSION_CODES#LOLLIPOP} or later.
+ * devices running {@link Build.VERSION_CODES#LOLLIPOP} or later.
*
* <p>No permissions are required to read or write to the returned path, since this
* path is internal storage.
*
* @return The path of the directory holding application files that will not be
- * automatically backed up to remote storage.
- *
- * @see android.content.Context#getFilesDir()
+ * automatically backed up to remote storage.
+ * @see Context#getFilesDir()
*/
@Nullable
public static File getNoBackupFilesDir(@NonNull Context context) {
if (Build.VERSION.SDK_INT >= 21) {
- return context.getNoBackupFilesDir();
+ return Api21Impl.getNoBackupFilesDir(context);
} else {
ApplicationInfo appInfo = context.getApplicationInfo();
return createFilesDir(new File(appInfo.dataDir, "no_backup"));
@@ -576,7 +578,7 @@
/**
* Returns the absolute path to the application specific cache directory on
* the filesystem designed for storing cached code. On devices running
- * {@link android.os.Build.VERSION_CODES#LOLLIPOP} or later, the system will delete
+ * {@link Build.VERSION_CODES#LOLLIPOP} or later, the system will delete
* any files stored in this location both when your specific application is
* upgraded, and when the entire platform is upgraded.
* <p>
@@ -590,7 +592,7 @@
*/
public static File getCodeCacheDir(@NonNull Context context) {
if (Build.VERSION.SDK_INT >= 21) {
- return context.getCodeCacheDir();
+ return Api21Impl.getCodeCacheDir(context);
} else {
ApplicationInfo appInfo = context.getApplicationInfo();
return createFilesDir(new File(appInfo.dataDir, "code_cache"));
@@ -645,7 +647,7 @@
@Nullable
public static Context createDeviceProtectedStorageContext(@NonNull Context context) {
if (Build.VERSION.SDK_INT >= 24) {
- return context.createDeviceProtectedStorageContext();
+ return Api24Impl.createDeviceProtectedStorageContext(context);
} else {
return null;
}
@@ -659,7 +661,7 @@
*/
public static boolean isDeviceProtectedStorage(@NonNull Context context) {
if (Build.VERSION.SDK_INT >= 24) {
- return context.isDeviceProtectedStorage();
+ return Api24Impl.isDeviceProtectedStorage(context);
} else {
return false;
}
@@ -672,7 +674,7 @@
*/
public static Executor getMainExecutor(Context context) {
if (Build.VERSION.SDK_INT >= 28) {
- return context.getMainExecutor();
+ return Api28Impl.getMainExecutor(context);
}
return ExecutorCompat.create(new Handler(context.getMainLooper()));
}
@@ -682,14 +684,13 @@
* for before O.
*
* @param context Context to start Service from.
- * @param intent The description of the Service to start.
- *
+ * @param intent The description of the Service to start.
* @see Context#startForegroundService(Intent)
* @see Context#startService(Intent)
*/
public static void startForegroundService(@NonNull Context context, @NonNull Intent intent) {
if (Build.VERSION.SDK_INT >= 26) {
- context.startForegroundService(intent);
+ Api26Impl.startForegroundService(context, intent);
} else {
// Pre-O behavior.
context.startService(intent);
@@ -699,17 +700,16 @@
/**
* Return the handle to a system-level service by class.
*
- * @param context Context to retrieve service from.
+ * @param context Context to retrieve service from.
* @param serviceClass The class of the desired service.
* @return The service or null if the class is not a supported system service.
- *
* @see Context#getSystemService(Class)
*/
@SuppressWarnings("unchecked")
@Nullable
public static <T> T getSystemService(@NonNull Context context, @NonNull Class<T> serviceClass) {
if (Build.VERSION.SDK_INT >= 23) {
- return context.getSystemService(serviceClass);
+ return Api23Impl.getSystemService(context, serviceClass);
}
String serviceName = getSystemServiceName(context, serviceClass);
@@ -719,17 +719,16 @@
/**
* Gets the name of the system-level service that is represented by the specified class.
*
- * @param context Context to retrieve service name from.
+ * @param context Context to retrieve service name from.
* @param serviceClass The class of the desired service.
* @return The service name or null if the class is not a supported system service.
- *
* @see Context#getSystemServiceName(Class)
*/
@Nullable
public static String getSystemServiceName(@NonNull Context context,
@NonNull Class<?> serviceClass) {
if (Build.VERSION.SDK_INT >= 23) {
- return context.getSystemServiceName(serviceClass);
+ return Api23Impl.getSystemServiceName(context, serviceClass);
}
return LegacyServiceMapHolder.SERVICES.get(serviceClass);
}
@@ -804,4 +803,150 @@
SERVICES.put(WindowManager.class, WINDOW_SERVICE);
}
}
+
+ @RequiresApi(16)
+ static class Api16Impl {
+ private Api16Impl() {
+ // This class is not instantiable.
+ }
+
+ @DoNotInline
+ static void startActivities(Context obj, Intent[] intents, Bundle options) {
+ obj.startActivities(intents, options);
+ }
+
+ @DoNotInline
+ static void startActivity(Context obj, Intent intent, Bundle options) {
+ obj.startActivity(intent, options);
+ }
+ }
+
+ @RequiresApi(19)
+ static class Api19Impl {
+ private Api19Impl() {
+ // This class is not instantiable.
+ }
+
+ @DoNotInline
+ static File[] getExternalCacheDirs(Context obj) {
+ return obj.getExternalCacheDirs();
+ }
+
+ @DoNotInline
+ static File[] getExternalFilesDirs(Context obj, String type) {
+ return obj.getExternalFilesDirs(type);
+ }
+
+ @DoNotInline
+ static File[] getObbDirs(Context obj) {
+ return obj.getObbDirs();
+ }
+ }
+
+ @RequiresApi(21)
+ static class Api21Impl {
+ private Api21Impl() {
+ // This class is not instantiable.
+ }
+
+ @DoNotInline
+ static Drawable getDrawable(Context obj, int id) {
+ return obj.getDrawable(id);
+ }
+
+ @DoNotInline
+ static File getNoBackupFilesDir(Context obj) {
+ return obj.getNoBackupFilesDir();
+ }
+
+ @DoNotInline
+ static File getCodeCacheDir(Context obj) {
+ return obj.getCodeCacheDir();
+ }
+ }
+
+ @RequiresApi(23)
+ static class Api23Impl {
+ private Api23Impl() {
+ // This class is not instantiable.
+ }
+
+ @DoNotInline
+ static ColorStateList getColorStateList(Context obj, int id) {
+ return obj.getColorStateList(id);
+ }
+
+ @DoNotInline
+ static int getColor(Context obj, int id) {
+ return obj.getColor(id);
+ }
+
+ @DoNotInline
+ static <T> T getSystemService(Context obj, Class<T> serviceClass) {
+ return obj.getSystemService(serviceClass);
+ }
+
+ @DoNotInline
+ static String getSystemServiceName(Context obj, Class<?> serviceClass) {
+ return obj.getSystemServiceName(serviceClass);
+ }
+ }
+
+ @RequiresApi(24)
+ static class Api24Impl {
+ private Api24Impl() {
+ // This class is not instantiable.
+ }
+
+ @DoNotInline
+ static File getDataDir(Context obj) {
+ return obj.getDataDir();
+ }
+
+ @DoNotInline
+ static Context createDeviceProtectedStorageContext(Context obj) {
+ return obj.createDeviceProtectedStorageContext();
+ }
+
+ @DoNotInline
+ static boolean isDeviceProtectedStorage(Context obj) {
+ return obj.isDeviceProtectedStorage();
+ }
+ }
+
+ @RequiresApi(26)
+ static class Api26Impl {
+ private Api26Impl() {
+ // This class is not instantiable.
+ }
+
+ @DoNotInline
+ static ComponentName startForegroundService(Context obj, Intent service) {
+ return obj.startForegroundService(service);
+ }
+ }
+
+ @RequiresApi(28)
+ static class Api28Impl {
+ private Api28Impl() {
+ // This class is not instantiable.
+ }
+
+ @DoNotInline
+ static Executor getMainExecutor(Context obj) {
+ return obj.getMainExecutor();
+ }
+ }
+
+ @RequiresApi(30)
+ static class Api30Impl {
+ private Api30Impl() {
+ // This class is not instantiable.
+ }
+
+ @DoNotInline
+ static String getAttributionTag(Context obj) {
+ return obj.getAttributionTag();
+ }
+ }
}
diff --git a/docs-tip-of-tree/build.gradle b/docs-tip-of-tree/build.gradle
index 02d58fa..aec0e23 100644
--- a/docs-tip-of-tree/build.gradle
+++ b/docs-tip-of-tree/build.gradle
@@ -118,6 +118,10 @@
docs(project(":emoji"))
docs(project(":emoji-appcompat"))
docs(project(":emoji-bundled"))
+ docs(project(":emoji2:emoji2"))
+ docs(project(":emoji2:emoji2-bundled"))
+ docs(project(":emoji2:emoji2-views"))
+ docs(project(":emoji2:emoji2-views-helper"))
docs(project(":enterprise-feedback"))
docs(project(":enterprise-feedback-testing"))
docs(project(":exifinterface:exifinterface"))
diff --git a/dynamic-animation/dynamic-animation-ktx/build.gradle b/dynamic-animation/dynamic-animation-ktx/build.gradle
index 9533a73..e3ec3f0 100644
--- a/dynamic-animation/dynamic-animation-ktx/build.gradle
+++ b/dynamic-animation/dynamic-animation-ktx/build.gradle
@@ -35,9 +35,9 @@
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
}
androidx {
diff --git a/dynamic-animation/dynamic-animation/build.gradle b/dynamic-animation/dynamic-animation/build.gradle
index 6ad3e31..13e952f 100644
--- a/dynamic-animation/dynamic-animation/build.gradle
+++ b/dynamic-animation/dynamic-animation/build.gradle
@@ -16,9 +16,9 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
}
androidx {
diff --git a/emoji/core/build.gradle b/emoji/core/build.gradle
index 2c54100..94334a7 100644
--- a/emoji/core/build.gradle
+++ b/emoji/core/build.gradle
@@ -31,9 +31,9 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(project(":internal-testutils-runtime"))
}
diff --git a/emoji2/emoji2-benchmark/build.gradle b/emoji2/emoji2-benchmark/build.gradle
index c3dd0be..a4709c1 100644
--- a/emoji2/emoji2-benchmark/build.gradle
+++ b/emoji2/emoji2-benchmark/build.gradle
@@ -34,8 +34,8 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation project(':internal-testutils-runtime')
androidTestImplementation(KOTLIN_STDLIB)
}
@@ -43,7 +43,7 @@
androidx {
name = "Emoji2 Benchmarks"
publish = Publish.NONE
- mavenGroup = LibraryGroups.NAVIGATION
- inceptionYear = "2018"
- description = "Navigation Benchmarks"
+ mavenGroup = LibraryGroups.EMOJI2
+ inceptionYear = "2021"
+ description = "Emoji2 Benchmarks"
}
diff --git a/emoji2/emoji2-bundled/api/current.txt b/emoji2/emoji2-bundled/api/current.txt
new file mode 100644
index 0000000..8749c28
--- /dev/null
+++ b/emoji2/emoji2-bundled/api/current.txt
@@ -0,0 +1,9 @@
+// Signature format: 4.0
+package androidx.emoji2.bundled {
+
+ public class BundledEmojiCompatConfig extends androidx.emoji2.text.EmojiCompat.Config {
+ ctor public BundledEmojiCompatConfig(android.content.Context);
+ }
+
+}
+
diff --git a/emoji2/emoji2-bundled/api/public_plus_experimental_current.txt b/emoji2/emoji2-bundled/api/public_plus_experimental_current.txt
new file mode 100644
index 0000000..8749c28
--- /dev/null
+++ b/emoji2/emoji2-bundled/api/public_plus_experimental_current.txt
@@ -0,0 +1,9 @@
+// Signature format: 4.0
+package androidx.emoji2.bundled {
+
+ public class BundledEmojiCompatConfig extends androidx.emoji2.text.EmojiCompat.Config {
+ ctor public BundledEmojiCompatConfig(android.content.Context);
+ }
+
+}
+
diff --git a/emoji2/emoji2-bundled/api/res-current.txt b/emoji2/emoji2-bundled/api/res-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/emoji2/emoji2-bundled/api/res-current.txt
diff --git a/emoji2/emoji2-bundled/api/restricted_current.txt b/emoji2/emoji2-bundled/api/restricted_current.txt
new file mode 100644
index 0000000..8749c28
--- /dev/null
+++ b/emoji2/emoji2-bundled/api/restricted_current.txt
@@ -0,0 +1,9 @@
+// Signature format: 4.0
+package androidx.emoji2.bundled {
+
+ public class BundledEmojiCompatConfig extends androidx.emoji2.text.EmojiCompat.Config {
+ ctor public BundledEmojiCompatConfig(android.content.Context);
+ }
+
+}
+
diff --git a/emoji2/emoji2-bundled/build.gradle b/emoji2/emoji2-bundled/build.gradle
index 0978cbf..7d6c347 100644
--- a/emoji2/emoji2-bundled/build.gradle
+++ b/emoji2/emoji2-bundled/build.gradle
@@ -39,9 +39,9 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation project(':internal-testutils-runtime')
// view tests that use font are in this module as well; for licensing reasons
@@ -50,11 +50,12 @@
androidx {
name = "Android Emoji2 Compat"
- publish = Publish.NONE
+ publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.EMOJI2
mavenGroup = LibraryGroups.EMOJI2
inceptionYear = "2017"
- description = "Library bundled with assets to enable emoji compatibility in Kitkat and newer devices to avoid the empty emoji characters."
+ description = "Library bundled with assets to enable emoji compatibility in Kitkat and newer " +
+ "devices to avoid the empty emoji characters."
license {
name = "SIL Open Font License, Version 1.1"
diff --git a/emoji2/emoji2-views-helper/AndroidManifest.xml b/emoji2/emoji2-views-helper/AndroidManifest.xml
index 2f4b90a5..0b6d86b 100644
--- a/emoji2/emoji2-views-helper/AndroidManifest.xml
+++ b/emoji2/emoji2-views-helper/AndroidManifest.xml
@@ -13,4 +13,4 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<manifest package="androidx.emoji2.helpers"/>
+<manifest package="androidx.emoji2.viewshelper"/>
diff --git a/emoji2/emoji2-views-helper/api/current.txt b/emoji2/emoji2-views-helper/api/current.txt
new file mode 100644
index 0000000..e4cacba9
--- /dev/null
+++ b/emoji2/emoji2-views-helper/api/current.txt
@@ -0,0 +1,22 @@
+// Signature format: 4.0
+package androidx.emoji2.viewshelper {
+
+ public final class EmojiEditTextHelper {
+ ctor public EmojiEditTextHelper(android.widget.EditText);
+ method public android.text.method.KeyListener getKeyListener(android.text.method.KeyListener);
+ method public int getMaxEmojiCount();
+ method public android.view.inputmethod.InputConnection? onCreateInputConnection(android.view.inputmethod.InputConnection?, android.view.inputmethod.EditorInfo);
+ method public void setMaxEmojiCount(@IntRange(from=0) int);
+ }
+
+ public final class EmojiTextViewHelper {
+ ctor public EmojiTextViewHelper(android.widget.TextView);
+ method public android.text.InputFilter![] getFilters(android.text.InputFilter![]);
+ method public void setAllCaps(boolean);
+ method public void setEnabled(boolean);
+ method public void updateTransformationMethod();
+ method public android.text.method.TransformationMethod? wrapTransformationMethod(android.text.method.TransformationMethod?);
+ }
+
+}
+
diff --git a/emoji2/emoji2-views-helper/api/public_plus_experimental_current.txt b/emoji2/emoji2-views-helper/api/public_plus_experimental_current.txt
new file mode 100644
index 0000000..e4cacba9
--- /dev/null
+++ b/emoji2/emoji2-views-helper/api/public_plus_experimental_current.txt
@@ -0,0 +1,22 @@
+// Signature format: 4.0
+package androidx.emoji2.viewshelper {
+
+ public final class EmojiEditTextHelper {
+ ctor public EmojiEditTextHelper(android.widget.EditText);
+ method public android.text.method.KeyListener getKeyListener(android.text.method.KeyListener);
+ method public int getMaxEmojiCount();
+ method public android.view.inputmethod.InputConnection? onCreateInputConnection(android.view.inputmethod.InputConnection?, android.view.inputmethod.EditorInfo);
+ method public void setMaxEmojiCount(@IntRange(from=0) int);
+ }
+
+ public final class EmojiTextViewHelper {
+ ctor public EmojiTextViewHelper(android.widget.TextView);
+ method public android.text.InputFilter![] getFilters(android.text.InputFilter![]);
+ method public void setAllCaps(boolean);
+ method public void setEnabled(boolean);
+ method public void updateTransformationMethod();
+ method public android.text.method.TransformationMethod? wrapTransformationMethod(android.text.method.TransformationMethod?);
+ }
+
+}
+
diff --git a/emoji2/emoji2-views-helper/api/res-current.txt b/emoji2/emoji2-views-helper/api/res-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/emoji2/emoji2-views-helper/api/res-current.txt
diff --git a/emoji2/emoji2-views-helper/api/restricted_current.txt b/emoji2/emoji2-views-helper/api/restricted_current.txt
new file mode 100644
index 0000000..e4cacba9
--- /dev/null
+++ b/emoji2/emoji2-views-helper/api/restricted_current.txt
@@ -0,0 +1,22 @@
+// Signature format: 4.0
+package androidx.emoji2.viewshelper {
+
+ public final class EmojiEditTextHelper {
+ ctor public EmojiEditTextHelper(android.widget.EditText);
+ method public android.text.method.KeyListener getKeyListener(android.text.method.KeyListener);
+ method public int getMaxEmojiCount();
+ method public android.view.inputmethod.InputConnection? onCreateInputConnection(android.view.inputmethod.InputConnection?, android.view.inputmethod.EditorInfo);
+ method public void setMaxEmojiCount(@IntRange(from=0) int);
+ }
+
+ public final class EmojiTextViewHelper {
+ ctor public EmojiTextViewHelper(android.widget.TextView);
+ method public android.text.InputFilter![] getFilters(android.text.InputFilter![]);
+ method public void setAllCaps(boolean);
+ method public void setEnabled(boolean);
+ method public void updateTransformationMethod();
+ method public android.text.method.TransformationMethod? wrapTransformationMethod(android.text.method.TransformationMethod?);
+ }
+
+}
+
diff --git a/emoji2/emoji2-views-helper/build.gradle b/emoji2/emoji2-views-helper/build.gradle
index 9f5aef9..038f23c 100644
--- a/emoji2/emoji2-views-helper/build.gradle
+++ b/emoji2/emoji2-views-helper/build.gradle
@@ -20,9 +20,9 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation project(':internal-testutils-runtime')
}
@@ -37,7 +37,7 @@
androidx {
name = "Android Emoji2 Compat view helpers"
- publish = Publish.NONE
+ publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.EMOJI2
mavenGroup = LibraryGroups.EMOJI2
inceptionYear = "2017"
diff --git a/emoji2/emoji2-views-helper/src/androidTest/AndroidManifest.xml b/emoji2/emoji2-views-helper/src/androidTest/AndroidManifest.xml
index 6c30771..f28fe19 100644
--- a/emoji2/emoji2-views-helper/src/androidTest/AndroidManifest.xml
+++ b/emoji2/emoji2-views-helper/src/androidTest/AndroidManifest.xml
@@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<manifest package="androidx.emoji2.helpers">
+<manifest package="androidx.emoji2.viewshelper">
<application>
</application>
diff --git a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiTextViewHelperTest.java b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiTextViewHelperTest.java
deleted file mode 100644
index 51b71cf..0000000
--- a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiTextViewHelperTest.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright 2021 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.emoji2.helpers;
-
-import static org.hamcrest.CoreMatchers.hasItem;
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.mock;
-
-import android.text.InputFilter;
-import android.text.method.PasswordTransformationMethod;
-import android.text.method.TransformationMethod;
-import android.widget.TextView;
-
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SdkSuppress;
-import androidx.test.filters.SmallTest;
-
-import org.hamcrest.CoreMatchers;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Arrays;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-@SdkSuppress(minSdkVersion = 19)
-public class EmojiTextViewHelperTest {
- EmojiTextViewHelper mTextViewHelper;
- TextView mTextView;
-
- @Before
- public void setup() {
- mTextView = new TextView(ApplicationProvider.getApplicationContext());
- mTextViewHelper = new EmojiTextViewHelper(mTextView);
- }
-
- @Test
- public void testUpdateTransformationMethod() {
- mTextView.setTransformationMethod(mock(TransformationMethod.class));
-
- mTextViewHelper.updateTransformationMethod();
-
- assertThat(mTextView.getTransformationMethod(),
- instanceOf(EmojiTransformationMethod.class));
- }
-
- @Test
- public void testUpdateTransformationMethod_doesNotUpdateForPasswordTransformation() {
- final PasswordTransformationMethod transformationMethod =
- new PasswordTransformationMethod();
- mTextView.setTransformationMethod(transformationMethod);
-
- mTextViewHelper.updateTransformationMethod();
-
- assertEquals(transformationMethod, mTextView.getTransformationMethod());
- }
-
- @Test
- public void testUpdateTransformationMethod_doesNotCreateNewInstance() {
- mTextView.setTransformationMethod(mock(TransformationMethod.class));
-
- mTextViewHelper.updateTransformationMethod();
- final TransformationMethod tm = mTextView.getTransformationMethod();
- assertThat(tm, instanceOf(EmojiTransformationMethod.class));
-
- // call the function again
- mTextViewHelper.updateTransformationMethod();
- assertSame(tm, mTextView.getTransformationMethod());
- }
-
- @Test
- public void testGetFilters() {
- final InputFilter existingFilter = mock(InputFilter.class);
- final InputFilter[] filters = new InputFilter[]{existingFilter};
-
- final InputFilter[] newFilters = mTextViewHelper.getFilters(filters);
-
- assertEquals(2, newFilters.length);
- assertThat(Arrays.asList(newFilters), hasItem(existingFilter));
- assertNotNull(findEmojiInputFilter(newFilters));
- }
-
- @Test
- public void testGetFilters_doesNotAddSecondInstance() {
- final InputFilter existingFilter = mock(InputFilter.class);
- final InputFilter[] filters = new InputFilter[]{existingFilter};
-
- InputFilter[] newFilters = mTextViewHelper.getFilters(filters);
- EmojiInputFilter emojiInputFilter = findEmojiInputFilter(newFilters);
- assertNotNull(emojiInputFilter);
-
- // run it again with the updated filters and see that it does not add new filter
- newFilters = mTextViewHelper.getFilters(newFilters);
-
- assertEquals(2, newFilters.length);
- assertThat(Arrays.asList(newFilters), hasItem(existingFilter));
- assertThat(Arrays.asList(newFilters), CoreMatchers.hasItem(emojiInputFilter));
- }
-
- private EmojiInputFilter findEmojiInputFilter(final InputFilter[] filters) {
- for (int i = 0; i < filters.length; i++) {
- if (filters[i] instanceof EmojiInputFilter) {
- return (EmojiInputFilter) filters[i];
- }
- }
- return null;
- }
-
- @Test
- public void testWrapTransformationMethod() {
- assertThat(mTextViewHelper.wrapTransformationMethod(null),
- instanceOf(EmojiTransformationMethod.class));
- }
-
- @Test
- public void testWrapTransformationMethod_doesNotCreateNewInstance() {
- final TransformationMethod tm1 = mTextViewHelper.wrapTransformationMethod(null);
- final TransformationMethod tm2 = mTextViewHelper.wrapTransformationMethod(tm1);
- assertSame(tm1, tm2);
- }
-
- @Test
- public void testSetAllCaps_withTrueSetsTransformationMethod() {
- mTextView.setTransformationMethod(mock(TransformationMethod.class));
- mTextViewHelper.setAllCaps(true);
- assertThat(mTextView.getTransformationMethod(),
- instanceOf(EmojiTransformationMethod.class));
- }
-
- @Test
- public void testSetAllCaps_withFalseDoesNotSetTransformationMethod() {
- mTextView.setTransformationMethod(null);
- mTextViewHelper.setAllCaps(false);
- assertNull(mTextView.getTransformationMethod());
- }
-
- @Test
- public void testSetAllCaps_withPasswordTransformationDoesNotSetTransformationMethod() {
- final PasswordTransformationMethod transformationMethod =
- new PasswordTransformationMethod();
- mTextView.setTransformationMethod(transformationMethod);
- mTextViewHelper.setAllCaps(true);
- assertSame(transformationMethod, mTextView.getTransformationMethod());
- }
-}
diff --git a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiEditTextHelperPre19Test.java b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiEditTextHelperPre19Test.java
similarity index 98%
rename from emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiEditTextHelperPre19Test.java
rename to emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiEditTextHelperPre19Test.java
index c431518..829fae8 100644
--- a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiEditTextHelperPre19Test.java
+++ b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiEditTextHelperPre19Test.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package androidx.emoji2.helpers;
+package androidx.emoji2.viewshelper;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
diff --git a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiEditTextHelperTest.java b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiEditTextHelperTest.java
similarity index 99%
rename from emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiEditTextHelperTest.java
rename to emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiEditTextHelperTest.java
index c054c74..6cad221 100644
--- a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiEditTextHelperTest.java
+++ b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiEditTextHelperTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package androidx.emoji2.helpers;
+package androidx.emoji2.viewshelper;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.assertEquals;
diff --git a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiEditableFactoryTest.java b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiEditableFactoryTest.java
similarity index 98%
rename from emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiEditableFactoryTest.java
rename to emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiEditableFactoryTest.java
index 36200b0..d85e40c 100644
--- a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiEditableFactoryTest.java
+++ b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiEditableFactoryTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package androidx.emoji2.helpers;
+package androidx.emoji2.viewshelper;
import static org.hamcrest.Matchers.arrayWithSize;
import static org.hamcrest.Matchers.instanceOf;
diff --git a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiInputConnectionTest.java b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiInputConnectionTest.java
similarity index 98%
rename from emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiInputConnectionTest.java
rename to emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiInputConnectionTest.java
index 9516a10..843a803 100644
--- a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiInputConnectionTest.java
+++ b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiInputConnectionTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package androidx.emoji2.helpers;
+package androidx.emoji2.viewshelper;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
diff --git a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiInputFilterTest.java b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiInputFilterTest.java
similarity index 98%
rename from emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiInputFilterTest.java
rename to emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiInputFilterTest.java
index 1b75ce9..4dd7387 100644
--- a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiInputFilterTest.java
+++ b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiInputFilterTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package androidx.emoji2.helpers;
+package androidx.emoji2.viewshelper;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
diff --git a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiKeyListenerTest.java b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiKeyListenerTest.java
similarity index 98%
rename from emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiKeyListenerTest.java
rename to emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiKeyListenerTest.java
index d1eea0e..d944658 100644
--- a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiKeyListenerTest.java
+++ b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiKeyListenerTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package androidx.emoji2.helpers;
+package androidx.emoji2.viewshelper;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
diff --git a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiTextViewHelperPre19Test.java b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiTextViewHelperPre19Test.java
similarity index 98%
rename from emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiTextViewHelperPre19Test.java
rename to emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiTextViewHelperPre19Test.java
index 6a9932a..308dcfd 100644
--- a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiTextViewHelperPre19Test.java
+++ b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiTextViewHelperPre19Test.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package androidx.emoji2.helpers;
+package androidx.emoji2.viewshelper;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
diff --git a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiTextViewHelperTest.java b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiTextViewHelperTest.java
new file mode 100644
index 0000000..909ca57
--- /dev/null
+++ b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiTextViewHelperTest.java
@@ -0,0 +1,381 @@
+/*
+ * Copyright 2021 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.emoji2.viewshelper;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.mock;
+
+import android.text.InputFilter;
+import android.text.method.PasswordTransformationMethod;
+import android.text.method.TransformationMethod;
+import android.widget.TextView;
+
+import androidx.emoji2.text.EmojiCompat;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.hamcrest.CoreMatchers;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+@SdkSuppress(minSdkVersion = 19)
+public class EmojiTextViewHelperTest {
+ EmojiTextViewHelper mTextViewHelper;
+ TextView mTextView;
+
+ @Before
+ public void setup() {
+ mTextView = new TextView(ApplicationProvider.getApplicationContext());
+ mTextViewHelper = new EmojiTextViewHelper(mTextView);
+ EmojiCompat.reset(mock(EmojiCompat.class));
+ }
+
+ @Test
+ public void testUpdateTransformationMethod() {
+ mTextView.setTransformationMethod(mock(TransformationMethod.class));
+
+ mTextViewHelper.updateTransformationMethod();
+
+ assertThat(mTextView.getTransformationMethod(),
+ instanceOf(EmojiTransformationMethod.class));
+ }
+
+ @Test
+ public void testUpdateTransformationMethod_whenDisabled_doesntWrap() {
+ TransformationMethod mockTransform = mock(TransformationMethod.class);
+ mTextView.setTransformationMethod(mockTransform);
+
+ mTextViewHelper.setEnabled(false);
+ mTextViewHelper.updateTransformationMethod();
+
+ assertThat(mTextView.getTransformationMethod(), is(mockTransform));
+ }
+
+ @Test
+ public void testUpdateTransformation_whenNotConfigured_NoEffectWhenSkipConfig() {
+ EmojiCompat.reset((EmojiCompat) null);
+ mTextViewHelper = new EmojiTextViewHelper(mTextView, false);
+ TransformationMethod mockTransform = mock(TransformationMethod.class);
+ mTextView.setTransformationMethod(mockTransform);
+ mTextViewHelper.updateTransformationMethod();
+ assertThat(mTextView.getTransformationMethod(), is(mockTransform));
+ }
+
+ @Test
+ public void testUpdateTransformationMethod_doesNotUpdateForPasswordTransformation() {
+ final PasswordTransformationMethod transformationMethod =
+ new PasswordTransformationMethod();
+ mTextView.setTransformationMethod(transformationMethod);
+
+ mTextViewHelper.updateTransformationMethod();
+
+ assertEquals(transformationMethod, mTextView.getTransformationMethod());
+ }
+
+ @Test
+ public void testUpdateTransformationMethod_doesNotCreateNewInstance() {
+ mTextView.setTransformationMethod(mock(TransformationMethod.class));
+
+ mTextViewHelper.updateTransformationMethod();
+ final TransformationMethod tm = mTextView.getTransformationMethod();
+ assertThat(tm, instanceOf(EmojiTransformationMethod.class));
+
+ // call the function again
+ mTextViewHelper.updateTransformationMethod();
+ assertSame(tm, mTextView.getTransformationMethod());
+ }
+
+ @Test
+ public void testGetFilters() {
+ final InputFilter existingFilter = mock(InputFilter.class);
+ final InputFilter[] filters = new InputFilter[]{existingFilter};
+
+ final InputFilter[] newFilters = mTextViewHelper.getFilters(filters);
+
+ assertEquals(2, newFilters.length);
+ assertThat(Arrays.asList(newFilters), hasItem(existingFilter));
+ assertNotNull(findEmojiInputFilter(newFilters));
+ }
+
+ @Test
+ public void testGetFilters_doesNotAddSecondInstance() {
+ final InputFilter existingFilter = mock(InputFilter.class);
+ final InputFilter[] filters = new InputFilter[]{existingFilter};
+
+ InputFilter[] newFilters = mTextViewHelper.getFilters(filters);
+ EmojiInputFilter emojiInputFilter = findEmojiInputFilter(newFilters);
+ assertNotNull(emojiInputFilter);
+
+ // run it again with the updated filters and see that it does not add new filter
+ newFilters = mTextViewHelper.getFilters(newFilters);
+
+ assertEquals(2, newFilters.length);
+ assertThat(Arrays.asList(newFilters), hasItem(existingFilter));
+ assertThat(Arrays.asList(newFilters), CoreMatchers.hasItem(emojiInputFilter));
+ }
+
+ @Test
+ public void getFilter_addsFilter_whenEmptyArray() {
+ InputFilter[] actual = mTextViewHelper.getFilters(new InputFilter[0]);
+ EmojiInputFilter emojiInputFilter = findEmojiInputFilter(actual);
+ assertNotNull(emojiInputFilter);
+ }
+
+ @Test
+ public void getFilter_doesntAddFilter_whenDisabled() {
+ mTextViewHelper.setEnabled(false);
+ InputFilter[] expected = new InputFilter[0];
+ InputFilter[] actual = mTextViewHelper.getFilters(expected);
+ assertThat(expected, is(actual));
+ }
+
+ @Test
+ public void setFilter_doesntAddFilter_whenNotConfiguredAndSkipping() {
+ EmojiCompat.reset((EmojiCompat) null);
+ mTextViewHelper = new EmojiTextViewHelper(mTextView, false);
+ InputFilter[] expected = new InputFilter[0];
+ InputFilter[] actual = mTextViewHelper.getFilters(expected);
+ assertThat(expected, is(actual));
+ }
+
+ @Test
+ public void getFilter_removesFilter_whenDisabled() {
+ mTextViewHelper.setEnabled(false);
+ InputFilter[] input = new InputFilter[1];
+ input[0] = new EmojiInputFilter(mTextView);
+ InputFilter[] actual = mTextViewHelper.getFilters(input);
+ assertThat(actual, equalTo(new InputFilter[0]));
+ }
+
+ @Test
+ public void getFilter_removesAllFilters_whenDisabled() {
+ mTextViewHelper.setEnabled(false);
+ InputFilter[] input = new InputFilter[3];
+ input[0] = new EmojiInputFilter(mTextView);
+ input[1] = mock(InputFilter.class);
+ input[2] = new EmojiInputFilter(mTextView);
+ InputFilter[] actual = mTextViewHelper.getFilters(input);
+ InputFilter[] expected = new InputFilter[1];
+ expected[0] = input[1];
+ assertThat(actual, equalTo(expected));
+ }
+
+ private EmojiInputFilter findEmojiInputFilter(final InputFilter[] filters) {
+ for (int i = 0; i < filters.length; i++) {
+ if (filters[i] instanceof EmojiInputFilter) {
+ return (EmojiInputFilter) filters[i];
+ }
+ }
+ return null;
+ }
+
+ @Test
+ public void testWrapTransformationMethod_doesNotCreateNewInstance() {
+ final TransformationMethod tm1 = mTextViewHelper.wrapTransformationMethod(null);
+ final TransformationMethod tm2 = mTextViewHelper.wrapTransformationMethod(tm1);
+ assertSame(tm1, tm2);
+ }
+
+ @Test
+ public void wrapTransformationMethod_whenEnabled_andPassword_returnsOriginal() {
+ TransformationMethod expected = new PasswordTransformationMethod();
+ TransformationMethod actual = mTextViewHelper.wrapTransformationMethod(expected);
+ assertThat(actual, is(expected));
+ }
+
+ @Test
+ public void wrapTransformationMethod_whenDisabled_andPassword_returnsOriginal() {
+ mTextViewHelper.setEnabled(false);
+ TransformationMethod expected = new PasswordTransformationMethod();
+ TransformationMethod actual = mTextViewHelper.wrapTransformationMethod(expected);
+ assertThat(actual, is(expected));
+ }
+
+ @Test
+ public void wrapTransformationMethod_whenEnabled_andEmoji_returnsOriginal() {
+ TransformationMethod expected = new EmojiTransformationMethod(null);
+ TransformationMethod actual = mTextViewHelper.wrapTransformationMethod(expected);
+ assertThat(actual, is(expected));
+ }
+
+ @Test
+ public void wrapTransformationMethod_whenDisabled_andEmoji_returnsUnwrapped() {
+ TransformationMethod expected = mock(TransformationMethod.class);
+ TransformationMethod input = new EmojiTransformationMethod(expected);
+ mTextViewHelper.setEnabled(false);
+ TransformationMethod actual = mTextViewHelper.wrapTransformationMethod(input);
+ assertThat(actual, is(expected));
+ }
+
+ @Test
+ public void wrapTransformationMethod_whenNull_andEnabled_returnsEmojiTransformationMethod() {
+ TransformationMethod actual = mTextViewHelper.wrapTransformationMethod(null);
+ assertThat(actual, instanceOf(EmojiTransformationMethod.class));
+ }
+
+ @Test
+ public void wrapTransformationMethod_whenNull_andDisabled_returnsNull() {
+ mTextViewHelper.setEnabled(false);
+ TransformationMethod actual = mTextViewHelper.wrapTransformationMethod(null);
+ assertNull(actual);
+ }
+
+ @Test
+ public void wrapTransformationMethod_whenNotEmoji_andDisabled_returnsOriginal() {
+ mTextViewHelper.setEnabled(false);
+ TransformationMethod expected = mock(TransformationMethod.class);
+ TransformationMethod actual = mTextViewHelper.wrapTransformationMethod(expected);
+ assertThat(actual, is(expected));
+ }
+
+ @Test
+ public void testSetAllCaps_withTrueSetsTransformationMethod() {
+ mTextView.setTransformationMethod(mock(TransformationMethod.class));
+ mTextViewHelper.setAllCaps(true);
+ assertThat(mTextView.getTransformationMethod(),
+ instanceOf(EmojiTransformationMethod.class));
+ }
+
+ @Test
+ public void testSetAllCaps_withFalseDoesNotSetTransformationMethod() {
+ mTextView.setTransformationMethod(null);
+ mTextViewHelper.setAllCaps(false);
+ assertNull(mTextView.getTransformationMethod());
+ }
+
+ @Test
+ public void testSetAllCaps_withPasswordTransformationDoesNotSetTransformationMethod() {
+ final PasswordTransformationMethod transformationMethod =
+ new PasswordTransformationMethod();
+ mTextView.setTransformationMethod(transformationMethod);
+ mTextViewHelper.setAllCaps(true);
+ assertSame(transformationMethod, mTextView.getTransformationMethod());
+ }
+
+ @Test
+ public void setEnabled_fromEnabled_leavesTransformationMethod() {
+ TransformationMethod mockTransform = mock(TransformationMethod.class);
+ mTextView.setTransformationMethod(mockTransform);
+ mTextViewHelper.updateTransformationMethod();
+ assertThat(mTextView.getTransformationMethod(),
+ instanceOf(EmojiTransformationMethod.class));
+ mTextViewHelper.setEnabled(true);
+ assertThat(mTextView.getTransformationMethod(),
+ instanceOf(EmojiTransformationMethod.class));
+ }
+
+ @Test
+ public void setEnabled_fromEnabled_leavesFilter() {
+ InputFilter[] expected = mTextViewHelper.getFilters(new InputFilter[0]);
+ mTextView.setFilters(expected);
+ mTextViewHelper.setEnabled(true);
+ assertThat(mTextView.getFilters(), is(expected));
+ }
+
+ @Test
+ public void setDisabled_fromEnabled_unWrapsTransformationMethod() {
+ TransformationMethod mockTransform = mock(TransformationMethod.class);
+ mTextView.setTransformationMethod(mockTransform);
+ mTextViewHelper.updateTransformationMethod();
+ assertThat(mTextView.getTransformationMethod(),
+ instanceOf(EmojiTransformationMethod.class));
+
+ mTextViewHelper.setEnabled(false);
+ assertThat(mTextView.getTransformationMethod(), is(mockTransform));
+ }
+
+ @Test
+ public void setDisabled_fromEnabled_removesFilter() {
+ InputFilter[] expected = new InputFilter[0];
+ mTextView.setFilters(mTextViewHelper.getFilters(expected));
+ mTextViewHelper.setEnabled(false);
+ assertThat(mTextView.getFilters(), equalTo(expected));
+ }
+
+ @Test
+ public void setEnabled_whenEnabling_reWrapsTransformationMethod() {
+ TransformationMethod mockTransform = mock(TransformationMethod.class);
+ mTextView.setTransformationMethod(mockTransform);
+ mTextViewHelper.updateTransformationMethod();
+ assertThat(mTextView.getTransformationMethod(),
+ instanceOf(EmojiTransformationMethod.class));
+
+ mTextViewHelper.setEnabled(false);
+ assertThat(mTextView.getTransformationMethod(), is(mockTransform));
+
+ mTextViewHelper.setEnabled(true);
+ assertThat(mTextView.getTransformationMethod(),
+ instanceOf(EmojiTransformationMethod.class));
+ }
+
+ @Test
+ public void setEnabled_whenEnabling_reAddsFilter() {
+ InputFilter[] expected = mTextViewHelper.getFilters(new InputFilter[0]);
+ mTextView.setFilters(expected);
+ mTextViewHelper.setEnabled(false);
+ assertThat(mTextView.getFilters(), equalTo(new InputFilter[0]));
+ mTextViewHelper.setEnabled(true);
+ assertThat(mTextView.getFilters(), equalTo(expected));
+ }
+
+ @Test
+ public void setEnabled_whenNotConfigured_andSkipConfig_doesNothing() {
+ EmojiCompat.reset((EmojiCompat) null);
+ mTextViewHelper = new EmojiTextViewHelper(mTextView, false);
+
+ InputFilter[] expectedInput = new InputFilter[1];
+ expectedInput[0] = mock(InputFilter.class);
+ mTextView.setFilters(expectedInput);
+ TransformationMethod expectedTransform = mock(TransformationMethod.class);
+ mTextView.setTransformationMethod(expectedTransform);
+
+ mTextViewHelper.setEnabled(true);
+ InputFilter[] actualInput1 = mTextView.getFilters();
+ TransformationMethod actualTransform1 = mTextView.getTransformationMethod();
+ mTextViewHelper.setEnabled(false);
+ InputFilter[] actualInput2 = mTextView.getFilters();
+ TransformationMethod actualTransform2 = mTextView.getTransformationMethod();
+ mTextViewHelper.setEnabled(true);
+ InputFilter[] actualInput3 = mTextView.getFilters();
+ TransformationMethod actualTransform3 = mTextView.getTransformationMethod();
+
+ // use transitive reference equality to do a bunch of assertions
+ assertSame(expectedInput, actualInput1);
+ assertSame(actualInput1, actualInput2);
+ assertSame(actualInput2, actualInput3);
+
+ assertSame(expectedTransform, actualTransform1);
+ assertSame(actualTransform1, actualTransform2);
+ assertSame(actualTransform2, actualTransform3);
+ }
+
+}
diff --git a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiTextWatcherTest.java b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiTextWatcherTest.java
similarity index 98%
rename from emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiTextWatcherTest.java
rename to emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiTextWatcherTest.java
index e1cf65e..df1f2de 100644
--- a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiTextWatcherTest.java
+++ b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiTextWatcherTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package androidx.emoji2.helpers;
+package androidx.emoji2.viewshelper;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
diff --git a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiTransformationMethodTest.java b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiTransformationMethodTest.java
similarity index 99%
rename from emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiTransformationMethodTest.java
rename to emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiTransformationMethodTest.java
index 6b0c88b..e0c6792 100644
--- a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/helpers/EmojiTransformationMethodTest.java
+++ b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewshelper/EmojiTransformationMethodTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package androidx.emoji2.helpers;
+package androidx.emoji2.viewshelper;
import static androidx.emoji2.util.EmojiMatcher.sameCharSequence;
diff --git a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiTextViewHelper.java b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiTextViewHelper.java
deleted file mode 100644
index ee45e85..0000000
--- a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiTextViewHelper.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright 2021 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.emoji2.helpers;
-
-import android.os.Build;
-import android.text.InputFilter;
-import android.text.method.PasswordTransformationMethod;
-import android.text.method.TransformationMethod;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
-import androidx.core.util.Preconditions;
-import androidx.emoji2.text.EmojiCompat;
-
-/**
- * Utility class to enhance custom TextView widgets with {@link EmojiCompat}.
- * <pre>
- * public class MyEmojiTextView extends TextView {
- * public MyEmojiTextView(Context context) {
- * super(context);
- * init();
- * }
- * // ..
- * private void init() {
- * getEmojiTextViewHelper().updateTransformationMethod();
- * }
- *
- * {@literal @}Override
- * public void setFilters(InputFilter[] filters) {
- * super.setFilters(getEmojiTextViewHelper().getFilters(filters));
- * }
- *
- * {@literal @}Override
- * public void setAllCaps(boolean allCaps) {
- * super.setAllCaps(allCaps);
- * getEmojiTextViewHelper().setAllCaps(allCaps);
- * }
- *
- * private EmojiTextViewHelper getEmojiTextViewHelper() {
- * if (mEmojiTextViewHelper == null) {
- * mEmojiTextViewHelper = new EmojiTextViewHelper(this);
- * }
- * return mEmojiTextViewHelper;
- * }
- * }
- * </pre>
- */
-public final class EmojiTextViewHelper {
-
- private final HelperInternal mHelper;
-
- /**
- * Default constructor.
- *
- * @param textView TextView instance
- */
- public EmojiTextViewHelper(@NonNull TextView textView) {
- Preconditions.checkNotNull(textView, "textView cannot be null");
- mHelper = Build.VERSION.SDK_INT >= 19 ? new HelperInternal19(textView)
- : new HelperInternal();
- }
-
- /**
- * Updates widget's TransformationMethod so that the transformed text can be processed.
- * Should be called in the widget constructor. When used on devices running API 18 or below,
- * this method does nothing.
- *
- * @see #wrapTransformationMethod(TransformationMethod)
- */
- public void updateTransformationMethod() {
- mHelper.updateTransformationMethod();
- }
-
- /**
- * Appends EmojiCompat InputFilters to the widget InputFilters. Should be called by {@link
- * TextView#setFilters(InputFilter[])} to update the InputFilters. When used on devices running
- * API 18 or below, this method returns {@code filters} that is given as a parameter.
- *
- * @param filters InputFilter array passed to {@link TextView#setFilters(InputFilter[])}
- *
- * @return same copy if the array already contains EmojiCompat InputFilter. A new array copy if
- * not.
- */
- @NonNull
- public InputFilter[] getFilters(@NonNull final InputFilter[] filters) {
- return mHelper.getFilters(filters);
- }
-
- /**
- * Returns transformation method that can update the transformed text to display emojis. When
- * used on devices running API 18 or below, this method returns {@code transformationMethod}
- * that is given as a parameter.
- *
- * @param transformationMethod instance to be wrapped
- */
- @Nullable
- public TransformationMethod wrapTransformationMethod(
- @Nullable TransformationMethod transformationMethod) {
- return mHelper.wrapTransformationMethod(transformationMethod);
- }
-
- /**
- * Call when allCaps is set on TextView. When used on devices running API 18 or below, this
- * method does nothing.
- *
- * @param allCaps allCaps parameter passed to {@link TextView#setAllCaps(boolean)}
- */
- public void setAllCaps(boolean allCaps) {
- mHelper.setAllCaps(allCaps);
- }
-
- @SuppressWarnings("WeakerAccess") /* synthetic access */
- static class HelperInternal {
-
- void updateTransformationMethod() {
- // do nothing
- }
-
- InputFilter[] getFilters(@NonNull final InputFilter[] filters) {
- return filters;
- }
-
- TransformationMethod wrapTransformationMethod(TransformationMethod transformationMethod) {
- return transformationMethod;
- }
-
- void setAllCaps(boolean allCaps) {
- // do nothing
- }
- }
-
- @RequiresApi(19)
- private static class HelperInternal19 extends HelperInternal {
- private final TextView mTextView;
- private final EmojiInputFilter mEmojiInputFilter;
-
- HelperInternal19(TextView textView) {
- mTextView = textView;
- mEmojiInputFilter = new EmojiInputFilter(textView);
- }
-
- @Override
- void updateTransformationMethod() {
- final TransformationMethod tm = mTextView.getTransformationMethod();
- if (tm != null && !(tm instanceof PasswordTransformationMethod)) {
- mTextView.setTransformationMethod(wrapTransformationMethod(tm));
- }
- }
-
- @Override
- InputFilter[] getFilters(@NonNull final InputFilter[] filters) {
- final int count = filters.length;
- for (int i = 0; i < count; i++) {
- if (filters[i] instanceof EmojiInputFilter) {
- return filters;
- }
- }
- final InputFilter[] newFilters = new InputFilter[filters.length + 1];
- System.arraycopy(filters, 0, newFilters, 0, count);
- newFilters[count] = mEmojiInputFilter;
- return newFilters;
- }
-
- @Override
- TransformationMethod wrapTransformationMethod(TransformationMethod transformationMethod) {
- if (transformationMethod instanceof EmojiTransformationMethod) {
- return transformationMethod;
- }
- return new EmojiTransformationMethod(transformationMethod);
- }
-
- @Override
- void setAllCaps(boolean allCaps) {
- // When allCaps is set to false TextView sets the transformation method to be null. We
- // are only interested when allCaps is set to true in order to wrap the original method.
- if (allCaps) {
- updateTransformationMethod();
- }
- }
-
- }
-}
diff --git a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiEditTextHelper.java b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiEditTextHelper.java
similarity index 98%
rename from emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiEditTextHelper.java
rename to emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiEditTextHelper.java
index 54216ea..90c9f82 100644
--- a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiEditTextHelper.java
+++ b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiEditTextHelper.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package androidx.emoji2.helpers;
+package androidx.emoji2.viewshelper;
import android.os.Build;
import android.text.method.KeyListener;
@@ -122,6 +122,7 @@
*
* @return a new KeyListener instance that wraps {@code keyListener}.
*/
+ @SuppressWarnings("ExecutorRegistration")
@NonNull
public KeyListener getKeyListener(@NonNull final KeyListener keyListener) {
Preconditions.checkNotNull(keyListener, "keyListener cannot be null");
diff --git a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiEditableFactory.java b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiEditableFactory.java
similarity index 98%
rename from emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiEditableFactory.java
rename to emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiEditableFactory.java
index bb6a713f..7e9c5a4 100644
--- a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiEditableFactory.java
+++ b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiEditableFactory.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package androidx.emoji2.helpers;
+package androidx.emoji2.viewshelper;
import android.annotation.SuppressLint;
import android.text.Editable;
diff --git a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiInputConnection.java b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiInputConnection.java
similarity index 98%
rename from emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiInputConnection.java
rename to emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiInputConnection.java
index 03f41ce..6513aba 100644
--- a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiInputConnection.java
+++ b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiInputConnection.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package androidx.emoji2.helpers;
+package androidx.emoji2.viewshelper;
import android.text.Editable;
import android.view.inputmethod.EditorInfo;
diff --git a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiInputFilter.java b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiInputFilter.java
similarity index 98%
rename from emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiInputFilter.java
rename to emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiInputFilter.java
index 6560a80..f3746de 100644
--- a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiInputFilter.java
+++ b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiInputFilter.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package androidx.emoji2.helpers;
+package androidx.emoji2.viewshelper;
import android.text.Selection;
import android.text.Spannable;
diff --git a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiKeyListener.java b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiKeyListener.java
similarity index 98%
rename from emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiKeyListener.java
rename to emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiKeyListener.java
index e3d0a72..67ddc72 100644
--- a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiKeyListener.java
+++ b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiKeyListener.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package androidx.emoji2.helpers;
+package androidx.emoji2.viewshelper;
import android.text.Editable;
import android.text.method.KeyListener;
diff --git a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiTextViewHelper.java b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiTextViewHelper.java
new file mode 100644
index 0000000..b4b9197
--- /dev/null
+++ b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiTextViewHelper.java
@@ -0,0 +1,471 @@
+/*
+ * Copyright 2021 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.emoji2.viewshelper;
+
+import android.os.Build;
+import android.text.InputFilter;
+import android.text.method.PasswordTransformationMethod;
+import android.text.method.TransformationMethod;
+import android.util.SparseArray;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
+import androidx.core.util.Preconditions;
+import androidx.emoji2.text.EmojiCompat;
+
+/**
+ * Utility class to enhance custom TextView widgets with {@link EmojiCompat}.
+ * <pre>
+ * public class MyEmojiTextView extends TextView {
+ * public MyEmojiTextView(Context context) {
+ * super(context);
+ * init();
+ * }
+ * // ..
+ * private void init() {
+ * getEmojiTextViewHelper().updateTransformationMethod();
+ * }
+ *
+ * {@literal @}Override
+ * public void setFilters(InputFilter[] filters) {
+ * super.setFilters(getEmojiTextViewHelper().getFilters(filters));
+ * }
+ *
+ * {@literal @}Override
+ * public void setAllCaps(boolean allCaps) {
+ * super.setAllCaps(allCaps);
+ * getEmojiTextViewHelper().setAllCaps(allCaps);
+ * }
+ *
+ * private EmojiTextViewHelper getEmojiTextViewHelper() {
+ * if (mEmojiTextViewHelper == null) {
+ * mEmojiTextViewHelper = new EmojiTextViewHelper(this);
+ * }
+ * return mEmojiTextViewHelper;
+ * }
+ * }
+ * </pre>
+ */
+public final class EmojiTextViewHelper {
+
+ private final HelperInternal mHelper;
+
+ /**
+ * Default constructor.
+ *
+ * @param textView TextView instance
+ */
+ public EmojiTextViewHelper(@NonNull TextView textView) {
+ this(textView, true);
+ }
+
+ /**
+ * Allows skipping of all processing until EmojiCompat.init is called.
+ *
+ * @param textView TextView instance
+ * @param expectInitializedEmojiCompat if true, this helper will assume init has been called
+ * and throw if it has not. If false, the methods on this
+ * helper will have no effect until EmojiCompat.init is
+ * called.
+ *
+ * @hide
+ */
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+ public EmojiTextViewHelper(@NonNull TextView textView, boolean expectInitializedEmojiCompat) {
+ Preconditions.checkNotNull(textView, "textView cannot be null");
+ if (Build.VERSION.SDK_INT < 19) {
+ mHelper = new HelperInternal();
+ } else if (!expectInitializedEmojiCompat) {
+ mHelper = new SkippingHelper19(textView);
+ } else {
+ mHelper = new HelperInternal19(textView);
+ }
+ }
+
+ /**
+ * Updates widget's TransformationMethod so that the transformed text can be processed.
+ * Should be called in the widget constructor. When used on devices running API 18 or below,
+ * this method does nothing.
+ *
+ * @see #wrapTransformationMethod(TransformationMethod)
+ */
+ public void updateTransformationMethod() {
+ mHelper.updateTransformationMethod();
+ }
+
+ /**
+ * Appends EmojiCompat InputFilters to the widget InputFilters. Should be called by {@link
+ * TextView#setFilters(InputFilter[])} to update the InputFilters. When used on devices running
+ * API 18 or below, this method returns {@code filters} that is given as a parameter.
+ *
+ * @param filters InputFilter array passed to {@link TextView#setFilters(InputFilter[])}
+ *
+ * @return same copy if the array already contains EmojiCompat InputFilter. A new array copy if
+ * not.
+ */
+ @SuppressWarnings("ArrayReturn")
+ @NonNull
+ public InputFilter[] getFilters(
+ @SuppressWarnings("ArrayReturn") @NonNull final InputFilter[] filters) {
+ return mHelper.getFilters(filters);
+ }
+
+ /**
+ * Returns transformation method that can update the transformed text to display emojis. When
+ * used on devices running API 18 or below, this method returns {@code transformationMethod}
+ * that is given as a parameter.
+ *
+ * @param transformationMethod instance to be wrapped
+ */
+ @Nullable
+ public TransformationMethod wrapTransformationMethod(
+ @Nullable TransformationMethod transformationMethod) {
+ return mHelper.wrapTransformationMethod(transformationMethod);
+ }
+
+ /**
+ * When enabled, methods will have their documented behavior.
+ *
+ * When disabled, all methods will have no effect and emoji will not be processed.
+ *
+ * Setting this to disable will also have the side effect of setting both the transformation
+ * method and filter if enabled has changed since the last call. By default
+ * EmojiTextViewHelper is enabled.
+ *
+ * You do not need to call {@link EmojiTextViewHelper#updateTransformationMethod()} again after
+ * calling setEnabled.
+ *
+ * @param enabled if this helper should process emoji.
+ */
+ public void setEnabled(boolean enabled) {
+ mHelper.setEnabled(enabled);
+ }
+
+ /**
+ * Call when allCaps is set on TextView. When used on devices running API 18 or below, this
+ * method does nothing.
+ *
+ * @param allCaps allCaps parameter passed to {@link TextView#setAllCaps(boolean)}
+ */
+ public void setAllCaps(boolean allCaps) {
+ mHelper.setAllCaps(allCaps);
+ }
+
+ @SuppressWarnings("WeakerAccess") /* synthetic access */
+ static class HelperInternal {
+
+ void updateTransformationMethod() {
+ // do nothing
+ }
+
+ @NonNull
+ InputFilter[] getFilters(@NonNull final InputFilter[] filters) {
+ return filters;
+ }
+
+ @Nullable
+ TransformationMethod wrapTransformationMethod(
+ @Nullable TransformationMethod transformationMethod) {
+ return transformationMethod;
+ }
+
+ void setAllCaps(boolean allCaps) {
+ // do nothing
+ }
+
+ void setEnabled(boolean processEmoji) {
+ // do nothing
+ }
+ }
+
+ /**
+ * This helper allows EmojiTextViewHelper to skip all calls to EmojiCompat until
+ * {@link EmojiCompat#isConfigured()} returns true on devices that are 19+.
+ *
+ * When isConfigured returns true, this delegates to {@link HelperInternal19} to provide
+ * EmojiCompat behavior. This has the effect of making EmojiCompat calls a "no-op" when
+ * EmojiCompat is not configured on a device.
+ *
+ * There is no mechanism to be informed when isConfigured becomes true as it will lead to
+ * likely memory leaks in situations where isConfigured never becomes true, and it is the
+ * responsibility of the caller to call
+ * {@link EmojiTextViewHelper#updateTransformationMethod()} after configuring EmojiCompat if
+ * TextView's using EmojiTextViewHelper are already displayed to the user.
+ */
+ @RequiresApi(19)
+ private static class SkippingHelper19 extends HelperInternal {
+ private HelperInternal19 mHelperDelegate;
+
+ SkippingHelper19(TextView textView) {
+ mHelperDelegate = new HelperInternal19(textView);
+ }
+
+
+ private boolean skipBecauseEmojiCompatNotInitialized() {
+ return !EmojiCompat.isConfigured();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * This method will have no effect if !{@link EmojiCompat#isConfigured()}
+ */
+ @Override
+ void updateTransformationMethod() {
+ if (skipBecauseEmojiCompatNotInitialized()) {
+ return;
+ }
+ mHelperDelegate.updateTransformationMethod();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * This method will have no effect if !{@link EmojiCompat#isConfigured()}
+ */
+ @NonNull
+ @Override
+ InputFilter[] getFilters(@NonNull InputFilter[] filters) {
+ if (skipBecauseEmojiCompatNotInitialized()) {
+ return filters;
+ }
+ return mHelperDelegate.getFilters(filters);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * This method will have no effect if !{@link EmojiCompat#isConfigured()}
+ */
+ @Nullable
+ @Override
+ TransformationMethod wrapTransformationMethod(
+ @Nullable TransformationMethod transformationMethod) {
+ if (skipBecauseEmojiCompatNotInitialized()) {
+ return transformationMethod;
+ }
+ return mHelperDelegate.wrapTransformationMethod(transformationMethod);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * This method will have no effect if !{@link EmojiCompat#isConfigured()}
+ */
+ @Override
+ void setAllCaps(boolean allCaps) {
+ if (skipBecauseEmojiCompatNotInitialized()) {
+ return;
+ }
+ mHelperDelegate.setAllCaps(allCaps);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * This method will track enabled, but have no other effect if
+ * !{@link EmojiCompat#isConfigured()}
+ */
+ @Override
+ void setEnabled(boolean processEmoji) {
+ if (skipBecauseEmojiCompatNotInitialized()) {
+ mHelperDelegate.setEnabledUnsafe(processEmoji);
+ } else {
+ mHelperDelegate.setEnabled(processEmoji);
+ }
+ }
+ }
+
+ @RequiresApi(19)
+ private static class HelperInternal19 extends HelperInternal {
+ private final TextView mTextView;
+ private final EmojiInputFilter mEmojiInputFilter;
+ private boolean mEnabled;
+
+ HelperInternal19(TextView textView) {
+ mTextView = textView;
+ mEnabled = true;
+ mEmojiInputFilter = new EmojiInputFilter(textView);
+ }
+
+
+ @Override
+ void updateTransformationMethod() {
+ // since this is not a pure function, we need to have a side effect for both enabled
+ // and disabled
+ final TransformationMethod tm =
+ wrapTransformationMethod(mTextView.getTransformationMethod());
+ mTextView.setTransformationMethod(tm);
+ }
+
+ /**
+ * Call whenever mEnabled changes
+ */
+ private void updateFilters() {
+ InputFilter[] oldFilters = mTextView.getFilters();
+ mTextView.setFilters(getFilters(oldFilters));
+ }
+
+ @NonNull
+ @Override
+ InputFilter[] getFilters(@NonNull final InputFilter[] filters) {
+ if (!mEnabled) {
+ // remove any EmojiInputFilter when disabled
+ return removeEmojiInputFilterIfPresent(filters);
+ } else {
+ return addEmojiInputFilterIfMissing(filters);
+ }
+ }
+
+ /**
+ * Make sure that EmojiInputFilter is present in filters, or add it.
+ *
+ * @param filters to check
+ * @return filters with mEmojiInputFilter added, if not previously present
+ */
+ @NonNull
+ private InputFilter[] addEmojiInputFilterIfMissing(@NonNull InputFilter[] filters) {
+ final int count = filters.length;
+ for (int i = 0; i < count; i++) {
+ if (filters[i] == mEmojiInputFilter) {
+ return filters;
+ }
+ }
+ final InputFilter[] newFilters = new InputFilter[filters.length + 1];
+ System.arraycopy(filters, 0, newFilters, 0, count);
+ newFilters[count] = mEmojiInputFilter;
+ return newFilters;
+ }
+
+ /**
+ * Remove all EmojiInputFilter from filters
+ *
+ * @return filters.filter { it !== mEmojiInputFilter }
+ */
+ @NonNull
+ private InputFilter[] removeEmojiInputFilterIfPresent(@NonNull InputFilter[] filters) {
+ // find out the new size after removing (all) EmojiInputFilter
+ SparseArray<InputFilter> filterSet = getEmojiInputFilterPositionArray(filters);
+ if (filterSet.size() == 0) {
+ return filters;
+ }
+
+
+ final int inCount = filters.length;
+ int outCount = filters.length - filterSet.size();
+ InputFilter[] result = new InputFilter[outCount];
+ int destPosition = 0;
+ for (int srcPosition = 0; srcPosition < inCount; srcPosition++) {
+ if (filterSet.indexOfKey(srcPosition) < 0) {
+ result[destPosition] = filters[srcPosition];
+ destPosition++;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Populate a sparse array with true for all indexes that contain an EmojiInputFilter.
+ */
+ private SparseArray<InputFilter> getEmojiInputFilterPositionArray(
+ @NonNull InputFilter[] filters) {
+ SparseArray<InputFilter> result = new SparseArray<>(1);
+ for (int pos = 0; pos < filters.length; pos++) {
+ if (filters[pos] instanceof EmojiInputFilter) {
+ result.put(pos, filters[pos]);
+ }
+ }
+ return result;
+ }
+
+ @Nullable
+ @Override
+ TransformationMethod wrapTransformationMethod(
+ @Nullable TransformationMethod transformationMethod) {
+ if (mEnabled) {
+ return wrapForEnabled(transformationMethod);
+ } else {
+ return unwrapForDisabled(transformationMethod);
+ }
+ }
+
+ /**
+ * Unwrap EmojiTransformationMethods safely.
+ */
+ @Nullable
+ private TransformationMethod unwrapForDisabled(
+ @Nullable TransformationMethod transformationMethod) {
+ if (transformationMethod instanceof EmojiTransformationMethod) {
+ EmojiTransformationMethod etm =
+ (EmojiTransformationMethod) transformationMethod;
+ return etm.getOriginalTransformationMethod();
+ } else {
+ return transformationMethod;
+ }
+ }
+
+ /**
+ * Wrap in EmojiTransformationMethod, but don't double wrap.
+ *
+ * This will not wrap {@link PasswordTransformationMethod}.
+ */
+ @NonNull
+ private TransformationMethod wrapForEnabled(
+ @Nullable TransformationMethod transformationMethod) {
+ if (transformationMethod instanceof EmojiTransformationMethod) {
+ return transformationMethod;
+ } else if (transformationMethod instanceof PasswordTransformationMethod) {
+ return transformationMethod;
+ } else {
+ return new EmojiTransformationMethod(transformationMethod);
+ }
+ }
+
+ @Override
+ void setAllCaps(boolean allCaps) {
+ // When allCaps is set to false TextView sets the transformation method to be null. We
+ // are only interested when allCaps is set to true in order to wrap the original method.
+ if (allCaps) {
+ updateTransformationMethod();
+ }
+ }
+
+ @Override
+ void setEnabled(boolean enabled) {
+ boolean oldValue = mEnabled;
+ mEnabled = enabled;
+ if (oldValue != enabled) {
+ updateTransformationMethod();
+ updateFilters();
+ }
+ }
+
+ /**
+ * Call to set enabled without side effects. Should only be used when EmojiCompat is not
+ * initialized.
+ *
+ * @param processEmoji when true, this helper will process emoji
+ * @hide
+ */
+ @RestrictTo(RestrictTo.Scope.LIBRARY)
+ void setEnabledUnsafe(boolean processEmoji) {
+ mEnabled = processEmoji;
+ }
+ }
+}
diff --git a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiTextWatcher.java b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiTextWatcher.java
similarity index 98%
rename from emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiTextWatcher.java
rename to emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiTextWatcher.java
index c86f3e2..73d5653 100644
--- a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiTextWatcher.java
+++ b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiTextWatcher.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package androidx.emoji2.helpers;
+package androidx.emoji2.viewshelper;
import android.text.Editable;
import android.text.Selection;
diff --git a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiTransformationMethod.java b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiTransformationMethod.java
similarity index 85%
rename from emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiTransformationMethod.java
rename to emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiTransformationMethod.java
index 47484e5..bd3561f 100644
--- a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/helpers/EmojiTransformationMethod.java
+++ b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewshelper/EmojiTransformationMethod.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package androidx.emoji2.helpers;
+package androidx.emoji2.viewshelper;
import android.graphics.Rect;
import android.text.method.TransformationMethod;
@@ -33,9 +33,10 @@
@RestrictTo(RestrictTo.Scope.LIBRARY)
@RequiresApi(19)
class EmojiTransformationMethod implements TransformationMethod {
+ @Nullable
private final TransformationMethod mTransformationMethod;
- EmojiTransformationMethod(TransformationMethod transformationMethod) {
+ EmojiTransformationMethod(@Nullable TransformationMethod transformationMethod) {
mTransformationMethod = transformationMethod;
}
@@ -71,4 +72,12 @@
previouslyFocusedRect);
}
}
+
+ /**
+ * Get the original transformation method that this is wrapping
+ * @return any transformation methods this emoji transformation method was wrapping
+ */
+ public TransformationMethod getOriginalTransformationMethod() {
+ return mTransformationMethod;
+ }
}
diff --git a/emoji2/emoji2-views/api/current.txt b/emoji2/emoji2-views/api/current.txt
new file mode 100644
index 0000000..879b30e
--- /dev/null
+++ b/emoji2/emoji2-views/api/current.txt
@@ -0,0 +1,34 @@
+// Signature format: 4.0
+package androidx.emoji2.widget {
+
+ public class EmojiButton extends android.widget.Button {
+ ctor public EmojiButton(android.content.Context);
+ ctor public EmojiButton(android.content.Context, android.util.AttributeSet?);
+ ctor public EmojiButton(android.content.Context, android.util.AttributeSet?, int);
+ }
+
+ public class EmojiEditText extends android.widget.EditText {
+ ctor public EmojiEditText(android.content.Context);
+ ctor public EmojiEditText(android.content.Context, android.util.AttributeSet?);
+ ctor public EmojiEditText(android.content.Context, android.util.AttributeSet?, int);
+ method public int getMaxEmojiCount();
+ method public void setMaxEmojiCount(@IntRange(from=0) int);
+ }
+
+ public class EmojiExtractTextLayout extends android.widget.LinearLayout {
+ ctor public EmojiExtractTextLayout(android.content.Context);
+ ctor public EmojiExtractTextLayout(android.content.Context, android.util.AttributeSet?);
+ ctor public EmojiExtractTextLayout(android.content.Context, android.util.AttributeSet?, int);
+ method public int getEmojiReplaceStrategy();
+ method public void onUpdateExtractingViews(android.inputmethodservice.InputMethodService, android.view.inputmethod.EditorInfo);
+ method public void setEmojiReplaceStrategy(int);
+ }
+
+ public class EmojiTextView extends android.widget.TextView {
+ ctor public EmojiTextView(android.content.Context);
+ ctor public EmojiTextView(android.content.Context, android.util.AttributeSet?);
+ ctor public EmojiTextView(android.content.Context, android.util.AttributeSet?, int);
+ }
+
+}
+
diff --git a/emoji2/emoji2-views/api/public_plus_experimental_current.txt b/emoji2/emoji2-views/api/public_plus_experimental_current.txt
new file mode 100644
index 0000000..b77930a
--- /dev/null
+++ b/emoji2/emoji2-views/api/public_plus_experimental_current.txt
@@ -0,0 +1,34 @@
+// Signature format: 4.0
+package androidx.emoji2.widget {
+
+ public class EmojiButton extends android.widget.Button {
+ ctor public EmojiButton(android.content.Context);
+ ctor public EmojiButton(android.content.Context, android.util.AttributeSet?);
+ ctor public EmojiButton(android.content.Context, android.util.AttributeSet?, int);
+ }
+
+ public class EmojiEditText extends android.widget.EditText {
+ ctor public EmojiEditText(android.content.Context);
+ ctor public EmojiEditText(android.content.Context, android.util.AttributeSet?);
+ ctor public EmojiEditText(android.content.Context, android.util.AttributeSet?, int);
+ method public int getMaxEmojiCount();
+ method public void setMaxEmojiCount(@IntRange(from=0) int);
+ }
+
+ public class EmojiExtractTextLayout extends android.widget.LinearLayout {
+ ctor public EmojiExtractTextLayout(android.content.Context);
+ ctor public EmojiExtractTextLayout(android.content.Context, android.util.AttributeSet?);
+ ctor public EmojiExtractTextLayout(android.content.Context, android.util.AttributeSet?, int);
+ method public int getEmojiReplaceStrategy();
+ method public void onUpdateExtractingViews(android.inputmethodservice.InputMethodService, android.view.inputmethod.EditorInfo);
+ method public void setEmojiReplaceStrategy(@androidx.emoji2.text.EmojiCompat.ReplaceStrategy int);
+ }
+
+ public class EmojiTextView extends android.widget.TextView {
+ ctor public EmojiTextView(android.content.Context);
+ ctor public EmojiTextView(android.content.Context, android.util.AttributeSet?);
+ ctor public EmojiTextView(android.content.Context, android.util.AttributeSet?, int);
+ }
+
+}
+
diff --git a/emoji2/emoji2-views/api/res-current.txt b/emoji2/emoji2-views/api/res-current.txt
new file mode 100644
index 0000000..8bc8423
--- /dev/null
+++ b/emoji2/emoji2-views/api/res-current.txt
@@ -0,0 +1,2 @@
+attr emojiReplaceStrategy
+attr maxEmojiCount
diff --git a/emoji2/emoji2-views/api/restricted_current.txt b/emoji2/emoji2-views/api/restricted_current.txt
new file mode 100644
index 0000000..b77930a
--- /dev/null
+++ b/emoji2/emoji2-views/api/restricted_current.txt
@@ -0,0 +1,34 @@
+// Signature format: 4.0
+package androidx.emoji2.widget {
+
+ public class EmojiButton extends android.widget.Button {
+ ctor public EmojiButton(android.content.Context);
+ ctor public EmojiButton(android.content.Context, android.util.AttributeSet?);
+ ctor public EmojiButton(android.content.Context, android.util.AttributeSet?, int);
+ }
+
+ public class EmojiEditText extends android.widget.EditText {
+ ctor public EmojiEditText(android.content.Context);
+ ctor public EmojiEditText(android.content.Context, android.util.AttributeSet?);
+ ctor public EmojiEditText(android.content.Context, android.util.AttributeSet?, int);
+ method public int getMaxEmojiCount();
+ method public void setMaxEmojiCount(@IntRange(from=0) int);
+ }
+
+ public class EmojiExtractTextLayout extends android.widget.LinearLayout {
+ ctor public EmojiExtractTextLayout(android.content.Context);
+ ctor public EmojiExtractTextLayout(android.content.Context, android.util.AttributeSet?);
+ ctor public EmojiExtractTextLayout(android.content.Context, android.util.AttributeSet?, int);
+ method public int getEmojiReplaceStrategy();
+ method public void onUpdateExtractingViews(android.inputmethodservice.InputMethodService, android.view.inputmethod.EditorInfo);
+ method public void setEmojiReplaceStrategy(@androidx.emoji2.text.EmojiCompat.ReplaceStrategy int);
+ }
+
+ public class EmojiTextView extends android.widget.TextView {
+ ctor public EmojiTextView(android.content.Context);
+ ctor public EmojiTextView(android.content.Context, android.util.AttributeSet?);
+ ctor public EmojiTextView(android.content.Context, android.util.AttributeSet?, int);
+ }
+
+}
+
diff --git a/emoji2/emoji2-views/build.gradle b/emoji2/emoji2-views/build.gradle
index 5a66a08..a7b3177 100644
--- a/emoji2/emoji2-views/build.gradle
+++ b/emoji2/emoji2-views/build.gradle
@@ -21,9 +21,9 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation project(':internal-testutils-runtime')
}
@@ -37,7 +37,7 @@
androidx {
name = "Android Emoji2 Compat Views"
- publish = Publish.NONE
+ publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.EMOJI2
mavenGroup = LibraryGroups.EMOJI2
inceptionYear = "2017"
diff --git a/emoji2/emoji2-views/src/main/java/androidx/emoji2/widget/EmojiButton.java b/emoji2/emoji2-views/src/main/java/androidx/emoji2/widget/EmojiButton.java
index 08d5465..373e03e 100644
--- a/emoji2/emoji2-views/src/main/java/androidx/emoji2/widget/EmojiButton.java
+++ b/emoji2/emoji2-views/src/main/java/androidx/emoji2/widget/EmojiButton.java
@@ -24,7 +24,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.widget.TextViewCompat;
-import androidx.emoji2.helpers.EmojiTextViewHelper;
+import androidx.emoji2.viewshelper.EmojiTextViewHelper;
/**
* Button widget enhanced with emoji capability by using {@link EmojiTextViewHelper}. When used
@@ -62,7 +62,7 @@
}
@Override
- public void setFilters(@NonNull InputFilter[] filters) {
+ public void setFilters(@SuppressWarnings("ArrayReturn") @NonNull InputFilter[] filters) {
super.setFilters(getEmojiTextViewHelper().getFilters(filters));
}
diff --git a/emoji2/emoji2-views/src/main/java/androidx/emoji2/widget/EmojiEditText.java b/emoji2/emoji2-views/src/main/java/androidx/emoji2/widget/EmojiEditText.java
index b0925a6..b7dbdc3 100644
--- a/emoji2/emoji2-views/src/main/java/androidx/emoji2/widget/EmojiEditText.java
+++ b/emoji2/emoji2-views/src/main/java/androidx/emoji2/widget/EmojiEditText.java
@@ -27,8 +27,8 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.widget.TextViewCompat;
-import androidx.emoji2.helpers.EmojiEditTextHelper;
import androidx.emoji2.text.EmojiCompat;
+import androidx.emoji2.viewshelper.EmojiEditTextHelper;
/**
* EditText widget enhanced with emoji capability by using {@link EmojiEditTextHelper}. When used
diff --git a/emoji2/emoji2-views/src/main/java/androidx/emoji2/widget/EmojiExtractEditText.java b/emoji2/emoji2-views/src/main/java/androidx/emoji2/widget/EmojiExtractEditText.java
index fb7443c..6f625f8 100644
--- a/emoji2/emoji2-views/src/main/java/androidx/emoji2/widget/EmojiExtractEditText.java
+++ b/emoji2/emoji2-views/src/main/java/androidx/emoji2/widget/EmojiExtractEditText.java
@@ -30,9 +30,9 @@
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.core.widget.TextViewCompat;
-import androidx.emoji2.helpers.EmojiEditTextHelper;
import androidx.emoji2.text.EmojiCompat;
import androidx.emoji2.text.EmojiSpan;
+import androidx.emoji2.viewshelper.EmojiEditTextHelper;
/**
* ExtractEditText widget enhanced with emoji capability by using {@link EmojiEditTextHelper}.
diff --git a/emoji2/emoji2-views/src/main/java/androidx/emoji2/widget/EmojiTextView.java b/emoji2/emoji2-views/src/main/java/androidx/emoji2/widget/EmojiTextView.java
index 137deb2..d32dcf3 100644
--- a/emoji2/emoji2-views/src/main/java/androidx/emoji2/widget/EmojiTextView.java
+++ b/emoji2/emoji2-views/src/main/java/androidx/emoji2/widget/EmojiTextView.java
@@ -24,7 +24,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.widget.TextViewCompat;
-import androidx.emoji2.helpers.EmojiTextViewHelper;
+import androidx.emoji2.viewshelper.EmojiTextViewHelper;
/**
* TextView widget enhanced with emoji capability by using {@link EmojiTextViewHelper}. When used
@@ -62,7 +62,7 @@
}
@Override
- public void setFilters(@NonNull InputFilter[] filters) {
+ public void setFilters(@SuppressWarnings("ArrayReturn") @NonNull InputFilter[] filters) {
super.setFilters(getEmojiTextViewHelper().getFilters(filters));
}
diff --git a/emoji2/emoji2/api/current.txt b/emoji2/emoji2/api/current.txt
new file mode 100644
index 0000000..f69bb70
--- /dev/null
+++ b/emoji2/emoji2/api/current.txt
@@ -0,0 +1,106 @@
+// Signature format: 4.0
+package androidx.emoji2.text {
+
+ public final class DefaultEmojiCompatConfig {
+ method public static androidx.emoji2.text.EmojiCompat.Config? create(android.content.Context);
+ }
+
+ @AnyThread public class EmojiCompat {
+ method public static androidx.emoji2.text.EmojiCompat get();
+ method public String getAssetSignature();
+ method public int getLoadState();
+ method public static boolean handleDeleteSurroundingText(android.view.inputmethod.InputConnection, android.text.Editable, @IntRange(from=0) int, @IntRange(from=0) int, boolean);
+ method public static boolean handleOnKeyDown(android.text.Editable, int, android.view.KeyEvent);
+ method public boolean hasEmojiGlyph(CharSequence);
+ method public boolean hasEmojiGlyph(CharSequence, @IntRange(from=0) int);
+ method public static androidx.emoji2.text.EmojiCompat? init(android.content.Context);
+ method public static androidx.emoji2.text.EmojiCompat init(androidx.emoji2.text.EmojiCompat.Config);
+ method public static boolean isConfigured();
+ method public void load();
+ method @CheckResult public CharSequence? process(CharSequence?);
+ method @CheckResult public CharSequence? process(CharSequence?, @IntRange(from=0) int, @IntRange(from=0) int);
+ method @CheckResult public CharSequence? process(CharSequence?, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int);
+ method @CheckResult public CharSequence? process(CharSequence?, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int, int);
+ method public void registerInitCallback(androidx.emoji2.text.EmojiCompat.InitCallback);
+ method public void unregisterInitCallback(androidx.emoji2.text.EmojiCompat.InitCallback);
+ field public static final String EDITOR_INFO_METAVERSION_KEY = "android.support.text.emoji.emojiCompat_metadataVersion";
+ field public static final String EDITOR_INFO_REPLACE_ALL_KEY = "android.support.text.emoji.emojiCompat_replaceAll";
+ field public static final int LOAD_STATE_DEFAULT = 3; // 0x3
+ field public static final int LOAD_STATE_FAILED = 2; // 0x2
+ field public static final int LOAD_STATE_LOADING = 0; // 0x0
+ field public static final int LOAD_STATE_SUCCEEDED = 1; // 0x1
+ field public static final int LOAD_STRATEGY_DEFAULT = 0; // 0x0
+ field public static final int LOAD_STRATEGY_MANUAL = 1; // 0x1
+ field public static final int REPLACE_STRATEGY_ALL = 1; // 0x1
+ field public static final int REPLACE_STRATEGY_DEFAULT = 0; // 0x0
+ field public static final int REPLACE_STRATEGY_NON_EXISTENT = 2; // 0x2
+ }
+
+ public abstract static class EmojiCompat.Config {
+ ctor protected EmojiCompat.Config(androidx.emoji2.text.EmojiCompat.MetadataRepoLoader);
+ method protected final androidx.emoji2.text.EmojiCompat.MetadataRepoLoader getMetadataRepoLoader();
+ method public androidx.emoji2.text.EmojiCompat.Config registerInitCallback(androidx.emoji2.text.EmojiCompat.InitCallback);
+ method public androidx.emoji2.text.EmojiCompat.Config setEmojiSpanIndicatorColor(@ColorInt int);
+ method public androidx.emoji2.text.EmojiCompat.Config setEmojiSpanIndicatorEnabled(boolean);
+ method public androidx.emoji2.text.EmojiCompat.Config setGlyphChecker(androidx.emoji2.text.EmojiCompat.GlyphChecker);
+ method public androidx.emoji2.text.EmojiCompat.Config setMetadataLoadStrategy(int);
+ method public androidx.emoji2.text.EmojiCompat.Config setReplaceAll(boolean);
+ method public androidx.emoji2.text.EmojiCompat.Config setUseEmojiAsDefaultStyle(boolean);
+ method public androidx.emoji2.text.EmojiCompat.Config setUseEmojiAsDefaultStyle(boolean, java.util.List<java.lang.Integer!>?);
+ method public androidx.emoji2.text.EmojiCompat.Config unregisterInitCallback(androidx.emoji2.text.EmojiCompat.InitCallback);
+ }
+
+ public static interface EmojiCompat.GlyphChecker {
+ method public boolean hasGlyph(CharSequence, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int);
+ }
+
+ public abstract static class EmojiCompat.InitCallback {
+ ctor public EmojiCompat.InitCallback();
+ method public void onFailed(Throwable?);
+ method public void onInitialized();
+ }
+
+ public static interface EmojiCompat.MetadataRepoLoader {
+ method public void load(androidx.emoji2.text.EmojiCompat.MetadataRepoLoaderCallback);
+ }
+
+ public abstract static class EmojiCompat.MetadataRepoLoaderCallback {
+ ctor public EmojiCompat.MetadataRepoLoaderCallback();
+ method public abstract void onFailed(Throwable?);
+ method public abstract void onLoaded(androidx.emoji2.text.MetadataRepo);
+ }
+
+ public class EmojiCompatInitializer implements androidx.startup.Initializer<java.lang.Boolean> {
+ ctor public EmojiCompatInitializer();
+ method public Boolean create(android.content.Context);
+ method public java.util.List<java.lang.Class<? extends androidx.startup.Initializer<?>>!> dependencies();
+ }
+
+ @RequiresApi(19) public abstract class EmojiSpan extends android.text.style.ReplacementSpan {
+ method public int getSize(android.graphics.Paint, CharSequence!, int, int, android.graphics.Paint.FontMetricsInt?);
+ }
+
+ public class FontRequestEmojiCompatConfig extends androidx.emoji2.text.EmojiCompat.Config {
+ ctor public FontRequestEmojiCompatConfig(android.content.Context, androidx.core.provider.FontRequest);
+ method public androidx.emoji2.text.FontRequestEmojiCompatConfig setHandler(android.os.Handler?);
+ method public androidx.emoji2.text.FontRequestEmojiCompatConfig setRetryPolicy(androidx.emoji2.text.FontRequestEmojiCompatConfig.RetryPolicy?);
+ }
+
+ public static class FontRequestEmojiCompatConfig.ExponentialBackoffRetryPolicy extends androidx.emoji2.text.FontRequestEmojiCompatConfig.RetryPolicy {
+ ctor public FontRequestEmojiCompatConfig.ExponentialBackoffRetryPolicy(long);
+ method public long getRetryDelay();
+ }
+
+ public abstract static class FontRequestEmojiCompatConfig.RetryPolicy {
+ ctor public FontRequestEmojiCompatConfig.RetryPolicy();
+ method public abstract long getRetryDelay();
+ }
+
+ @AnyThread @RequiresApi(19) public final class MetadataRepo {
+ method public static androidx.emoji2.text.MetadataRepo create(android.graphics.Typeface, java.io.InputStream) throws java.io.IOException;
+ method public static androidx.emoji2.text.MetadataRepo create(android.graphics.Typeface, java.nio.ByteBuffer) throws java.io.IOException;
+ method public static androidx.emoji2.text.MetadataRepo create(android.content.res.AssetManager, String) throws java.io.IOException;
+ }
+
+}
+
diff --git a/emoji2/emoji2/api/public_plus_experimental_current.txt b/emoji2/emoji2/api/public_plus_experimental_current.txt
new file mode 100644
index 0000000..f69bb70
--- /dev/null
+++ b/emoji2/emoji2/api/public_plus_experimental_current.txt
@@ -0,0 +1,106 @@
+// Signature format: 4.0
+package androidx.emoji2.text {
+
+ public final class DefaultEmojiCompatConfig {
+ method public static androidx.emoji2.text.EmojiCompat.Config? create(android.content.Context);
+ }
+
+ @AnyThread public class EmojiCompat {
+ method public static androidx.emoji2.text.EmojiCompat get();
+ method public String getAssetSignature();
+ method public int getLoadState();
+ method public static boolean handleDeleteSurroundingText(android.view.inputmethod.InputConnection, android.text.Editable, @IntRange(from=0) int, @IntRange(from=0) int, boolean);
+ method public static boolean handleOnKeyDown(android.text.Editable, int, android.view.KeyEvent);
+ method public boolean hasEmojiGlyph(CharSequence);
+ method public boolean hasEmojiGlyph(CharSequence, @IntRange(from=0) int);
+ method public static androidx.emoji2.text.EmojiCompat? init(android.content.Context);
+ method public static androidx.emoji2.text.EmojiCompat init(androidx.emoji2.text.EmojiCompat.Config);
+ method public static boolean isConfigured();
+ method public void load();
+ method @CheckResult public CharSequence? process(CharSequence?);
+ method @CheckResult public CharSequence? process(CharSequence?, @IntRange(from=0) int, @IntRange(from=0) int);
+ method @CheckResult public CharSequence? process(CharSequence?, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int);
+ method @CheckResult public CharSequence? process(CharSequence?, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int, int);
+ method public void registerInitCallback(androidx.emoji2.text.EmojiCompat.InitCallback);
+ method public void unregisterInitCallback(androidx.emoji2.text.EmojiCompat.InitCallback);
+ field public static final String EDITOR_INFO_METAVERSION_KEY = "android.support.text.emoji.emojiCompat_metadataVersion";
+ field public static final String EDITOR_INFO_REPLACE_ALL_KEY = "android.support.text.emoji.emojiCompat_replaceAll";
+ field public static final int LOAD_STATE_DEFAULT = 3; // 0x3
+ field public static final int LOAD_STATE_FAILED = 2; // 0x2
+ field public static final int LOAD_STATE_LOADING = 0; // 0x0
+ field public static final int LOAD_STATE_SUCCEEDED = 1; // 0x1
+ field public static final int LOAD_STRATEGY_DEFAULT = 0; // 0x0
+ field public static final int LOAD_STRATEGY_MANUAL = 1; // 0x1
+ field public static final int REPLACE_STRATEGY_ALL = 1; // 0x1
+ field public static final int REPLACE_STRATEGY_DEFAULT = 0; // 0x0
+ field public static final int REPLACE_STRATEGY_NON_EXISTENT = 2; // 0x2
+ }
+
+ public abstract static class EmojiCompat.Config {
+ ctor protected EmojiCompat.Config(androidx.emoji2.text.EmojiCompat.MetadataRepoLoader);
+ method protected final androidx.emoji2.text.EmojiCompat.MetadataRepoLoader getMetadataRepoLoader();
+ method public androidx.emoji2.text.EmojiCompat.Config registerInitCallback(androidx.emoji2.text.EmojiCompat.InitCallback);
+ method public androidx.emoji2.text.EmojiCompat.Config setEmojiSpanIndicatorColor(@ColorInt int);
+ method public androidx.emoji2.text.EmojiCompat.Config setEmojiSpanIndicatorEnabled(boolean);
+ method public androidx.emoji2.text.EmojiCompat.Config setGlyphChecker(androidx.emoji2.text.EmojiCompat.GlyphChecker);
+ method public androidx.emoji2.text.EmojiCompat.Config setMetadataLoadStrategy(int);
+ method public androidx.emoji2.text.EmojiCompat.Config setReplaceAll(boolean);
+ method public androidx.emoji2.text.EmojiCompat.Config setUseEmojiAsDefaultStyle(boolean);
+ method public androidx.emoji2.text.EmojiCompat.Config setUseEmojiAsDefaultStyle(boolean, java.util.List<java.lang.Integer!>?);
+ method public androidx.emoji2.text.EmojiCompat.Config unregisterInitCallback(androidx.emoji2.text.EmojiCompat.InitCallback);
+ }
+
+ public static interface EmojiCompat.GlyphChecker {
+ method public boolean hasGlyph(CharSequence, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int);
+ }
+
+ public abstract static class EmojiCompat.InitCallback {
+ ctor public EmojiCompat.InitCallback();
+ method public void onFailed(Throwable?);
+ method public void onInitialized();
+ }
+
+ public static interface EmojiCompat.MetadataRepoLoader {
+ method public void load(androidx.emoji2.text.EmojiCompat.MetadataRepoLoaderCallback);
+ }
+
+ public abstract static class EmojiCompat.MetadataRepoLoaderCallback {
+ ctor public EmojiCompat.MetadataRepoLoaderCallback();
+ method public abstract void onFailed(Throwable?);
+ method public abstract void onLoaded(androidx.emoji2.text.MetadataRepo);
+ }
+
+ public class EmojiCompatInitializer implements androidx.startup.Initializer<java.lang.Boolean> {
+ ctor public EmojiCompatInitializer();
+ method public Boolean create(android.content.Context);
+ method public java.util.List<java.lang.Class<? extends androidx.startup.Initializer<?>>!> dependencies();
+ }
+
+ @RequiresApi(19) public abstract class EmojiSpan extends android.text.style.ReplacementSpan {
+ method public int getSize(android.graphics.Paint, CharSequence!, int, int, android.graphics.Paint.FontMetricsInt?);
+ }
+
+ public class FontRequestEmojiCompatConfig extends androidx.emoji2.text.EmojiCompat.Config {
+ ctor public FontRequestEmojiCompatConfig(android.content.Context, androidx.core.provider.FontRequest);
+ method public androidx.emoji2.text.FontRequestEmojiCompatConfig setHandler(android.os.Handler?);
+ method public androidx.emoji2.text.FontRequestEmojiCompatConfig setRetryPolicy(androidx.emoji2.text.FontRequestEmojiCompatConfig.RetryPolicy?);
+ }
+
+ public static class FontRequestEmojiCompatConfig.ExponentialBackoffRetryPolicy extends androidx.emoji2.text.FontRequestEmojiCompatConfig.RetryPolicy {
+ ctor public FontRequestEmojiCompatConfig.ExponentialBackoffRetryPolicy(long);
+ method public long getRetryDelay();
+ }
+
+ public abstract static class FontRequestEmojiCompatConfig.RetryPolicy {
+ ctor public FontRequestEmojiCompatConfig.RetryPolicy();
+ method public abstract long getRetryDelay();
+ }
+
+ @AnyThread @RequiresApi(19) public final class MetadataRepo {
+ method public static androidx.emoji2.text.MetadataRepo create(android.graphics.Typeface, java.io.InputStream) throws java.io.IOException;
+ method public static androidx.emoji2.text.MetadataRepo create(android.graphics.Typeface, java.nio.ByteBuffer) throws java.io.IOException;
+ method public static androidx.emoji2.text.MetadataRepo create(android.content.res.AssetManager, String) throws java.io.IOException;
+ }
+
+}
+
diff --git a/emoji2/emoji2/api/res-current.txt b/emoji2/emoji2/api/res-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/emoji2/emoji2/api/res-current.txt
diff --git a/emoji2/emoji2/api/restricted_current.txt b/emoji2/emoji2/api/restricted_current.txt
new file mode 100644
index 0000000..f69bb70
--- /dev/null
+++ b/emoji2/emoji2/api/restricted_current.txt
@@ -0,0 +1,106 @@
+// Signature format: 4.0
+package androidx.emoji2.text {
+
+ public final class DefaultEmojiCompatConfig {
+ method public static androidx.emoji2.text.EmojiCompat.Config? create(android.content.Context);
+ }
+
+ @AnyThread public class EmojiCompat {
+ method public static androidx.emoji2.text.EmojiCompat get();
+ method public String getAssetSignature();
+ method public int getLoadState();
+ method public static boolean handleDeleteSurroundingText(android.view.inputmethod.InputConnection, android.text.Editable, @IntRange(from=0) int, @IntRange(from=0) int, boolean);
+ method public static boolean handleOnKeyDown(android.text.Editable, int, android.view.KeyEvent);
+ method public boolean hasEmojiGlyph(CharSequence);
+ method public boolean hasEmojiGlyph(CharSequence, @IntRange(from=0) int);
+ method public static androidx.emoji2.text.EmojiCompat? init(android.content.Context);
+ method public static androidx.emoji2.text.EmojiCompat init(androidx.emoji2.text.EmojiCompat.Config);
+ method public static boolean isConfigured();
+ method public void load();
+ method @CheckResult public CharSequence? process(CharSequence?);
+ method @CheckResult public CharSequence? process(CharSequence?, @IntRange(from=0) int, @IntRange(from=0) int);
+ method @CheckResult public CharSequence? process(CharSequence?, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int);
+ method @CheckResult public CharSequence? process(CharSequence?, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int, int);
+ method public void registerInitCallback(androidx.emoji2.text.EmojiCompat.InitCallback);
+ method public void unregisterInitCallback(androidx.emoji2.text.EmojiCompat.InitCallback);
+ field public static final String EDITOR_INFO_METAVERSION_KEY = "android.support.text.emoji.emojiCompat_metadataVersion";
+ field public static final String EDITOR_INFO_REPLACE_ALL_KEY = "android.support.text.emoji.emojiCompat_replaceAll";
+ field public static final int LOAD_STATE_DEFAULT = 3; // 0x3
+ field public static final int LOAD_STATE_FAILED = 2; // 0x2
+ field public static final int LOAD_STATE_LOADING = 0; // 0x0
+ field public static final int LOAD_STATE_SUCCEEDED = 1; // 0x1
+ field public static final int LOAD_STRATEGY_DEFAULT = 0; // 0x0
+ field public static final int LOAD_STRATEGY_MANUAL = 1; // 0x1
+ field public static final int REPLACE_STRATEGY_ALL = 1; // 0x1
+ field public static final int REPLACE_STRATEGY_DEFAULT = 0; // 0x0
+ field public static final int REPLACE_STRATEGY_NON_EXISTENT = 2; // 0x2
+ }
+
+ public abstract static class EmojiCompat.Config {
+ ctor protected EmojiCompat.Config(androidx.emoji2.text.EmojiCompat.MetadataRepoLoader);
+ method protected final androidx.emoji2.text.EmojiCompat.MetadataRepoLoader getMetadataRepoLoader();
+ method public androidx.emoji2.text.EmojiCompat.Config registerInitCallback(androidx.emoji2.text.EmojiCompat.InitCallback);
+ method public androidx.emoji2.text.EmojiCompat.Config setEmojiSpanIndicatorColor(@ColorInt int);
+ method public androidx.emoji2.text.EmojiCompat.Config setEmojiSpanIndicatorEnabled(boolean);
+ method public androidx.emoji2.text.EmojiCompat.Config setGlyphChecker(androidx.emoji2.text.EmojiCompat.GlyphChecker);
+ method public androidx.emoji2.text.EmojiCompat.Config setMetadataLoadStrategy(int);
+ method public androidx.emoji2.text.EmojiCompat.Config setReplaceAll(boolean);
+ method public androidx.emoji2.text.EmojiCompat.Config setUseEmojiAsDefaultStyle(boolean);
+ method public androidx.emoji2.text.EmojiCompat.Config setUseEmojiAsDefaultStyle(boolean, java.util.List<java.lang.Integer!>?);
+ method public androidx.emoji2.text.EmojiCompat.Config unregisterInitCallback(androidx.emoji2.text.EmojiCompat.InitCallback);
+ }
+
+ public static interface EmojiCompat.GlyphChecker {
+ method public boolean hasGlyph(CharSequence, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int);
+ }
+
+ public abstract static class EmojiCompat.InitCallback {
+ ctor public EmojiCompat.InitCallback();
+ method public void onFailed(Throwable?);
+ method public void onInitialized();
+ }
+
+ public static interface EmojiCompat.MetadataRepoLoader {
+ method public void load(androidx.emoji2.text.EmojiCompat.MetadataRepoLoaderCallback);
+ }
+
+ public abstract static class EmojiCompat.MetadataRepoLoaderCallback {
+ ctor public EmojiCompat.MetadataRepoLoaderCallback();
+ method public abstract void onFailed(Throwable?);
+ method public abstract void onLoaded(androidx.emoji2.text.MetadataRepo);
+ }
+
+ public class EmojiCompatInitializer implements androidx.startup.Initializer<java.lang.Boolean> {
+ ctor public EmojiCompatInitializer();
+ method public Boolean create(android.content.Context);
+ method public java.util.List<java.lang.Class<? extends androidx.startup.Initializer<?>>!> dependencies();
+ }
+
+ @RequiresApi(19) public abstract class EmojiSpan extends android.text.style.ReplacementSpan {
+ method public int getSize(android.graphics.Paint, CharSequence!, int, int, android.graphics.Paint.FontMetricsInt?);
+ }
+
+ public class FontRequestEmojiCompatConfig extends androidx.emoji2.text.EmojiCompat.Config {
+ ctor public FontRequestEmojiCompatConfig(android.content.Context, androidx.core.provider.FontRequest);
+ method public androidx.emoji2.text.FontRequestEmojiCompatConfig setHandler(android.os.Handler?);
+ method public androidx.emoji2.text.FontRequestEmojiCompatConfig setRetryPolicy(androidx.emoji2.text.FontRequestEmojiCompatConfig.RetryPolicy?);
+ }
+
+ public static class FontRequestEmojiCompatConfig.ExponentialBackoffRetryPolicy extends androidx.emoji2.text.FontRequestEmojiCompatConfig.RetryPolicy {
+ ctor public FontRequestEmojiCompatConfig.ExponentialBackoffRetryPolicy(long);
+ method public long getRetryDelay();
+ }
+
+ public abstract static class FontRequestEmojiCompatConfig.RetryPolicy {
+ ctor public FontRequestEmojiCompatConfig.RetryPolicy();
+ method public abstract long getRetryDelay();
+ }
+
+ @AnyThread @RequiresApi(19) public final class MetadataRepo {
+ method public static androidx.emoji2.text.MetadataRepo create(android.graphics.Typeface, java.io.InputStream) throws java.io.IOException;
+ method public static androidx.emoji2.text.MetadataRepo create(android.graphics.Typeface, java.nio.ByteBuffer) throws java.io.IOException;
+ method public static androidx.emoji2.text.MetadataRepo create(android.content.res.AssetManager, String) throws java.io.IOException;
+ }
+
+}
+
diff --git a/emoji2/emoji2/build.gradle b/emoji2/emoji2/build.gradle
index fd53536..ef1872e 100644
--- a/emoji2/emoji2/build.gradle
+++ b/emoji2/emoji2/build.gradle
@@ -13,8 +13,12 @@
BundleInsideHelper.forInsideAar(
project,
- /* from = */ "com.google.flatbuffers",
- /* to = */ "androidx.text.emoji.flatbuffer"
+ [
+ new BundleInsideHelper.Relocation("com.google.flatbuffers",
+ "androidx.emoji2.text.flatbuffer"),
+ new BundleInsideHelper.Relocation("androidx.text.emoji.flatbuffer",
+ "androidx.emoji2.text.flatbuffer")
+ ]
)
dependencies {
@@ -28,15 +32,15 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation project(':internal-testutils-runtime')
}
androidx {
name = "Android Emoji2 Compat"
- publish = Publish.NONE
+ publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.EMOJI2
mavenGroup = LibraryGroups.EMOJI2
inceptionYear = "2017"
diff --git a/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiCompat.java b/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiCompat.java
index 94ecef2..07b735d 100644
--- a/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiCompat.java
+++ b/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiCompat.java
@@ -379,6 +379,41 @@
}
/**
+ * Return true if EmojiCompat has been configured by a successful call to
+ * {@link EmojiCompat#init}.
+ *
+ * You can use this to check if {@link EmojiCompat#get()} will return a valid EmojiCompat
+ * instance.
+ *
+ * This function does not check the {@link #getLoadState()} and will return true even if the
+ * font is still loading, or has failed to load.
+ *
+ * @return true if EmojiCompat has been successfully initialized.
+ */
+ @SuppressWarnings("GuardedBy") // same rationale as double-check lock
+ public static boolean isConfigured() {
+ // Note: this is true immediately after calling .init(Config).
+ //
+ // These are three situations this may return false
+ // 1) An app has disabled EmojiCompatInitializer and does not intend to call .init.
+ // 2) EmojiCompatInitializer did not find a configuration
+ // 3) EmojiCompatInitializer was disable or failed, and the app will call .init. In the
+ // future it will return true.
+ //
+ // In case one and two, this method will always return false for the duration of the
+ // application lifecycle.
+ //
+ // In case three, this will return true at some future point. There is no callback
+ // mechanism to learn about the init call due to the high potential for leaked references
+ // in a static context if it's actually case 2 (when using manual callback registration).
+ //
+ // It is recommended that applications call init prior to creating any screens that
+ // may show emoji or user generated content.
+ return sInstance != null;
+ }
+
+
+ /**
* Used by the tests to reset EmojiCompat with a new configuration. Every time it is called a
* new instance is created with the new configuration.
*
@@ -527,6 +562,7 @@
*
* @see #unregisterInitCallback(InitCallback)
*/
+ @SuppressWarnings("ExecutorRegistration")
public void registerInitCallback(@NonNull InitCallback initCallback) {
Preconditions.checkNotNull(initCallback, "initCallback cannot be null");
@@ -946,6 +982,7 @@
*
* @param loaderCallback callback to signal the loading state
*/
+ @SuppressWarnings("ExecutorRegistration")
void load(@NonNull MetadataRepoLoaderCallback loaderCallback);
}
@@ -1067,6 +1104,7 @@
*
* @return EmojiCompat.Config instance
*/
+ @SuppressWarnings("ExecutorRegistration")
@NonNull
public Config registerInitCallback(@NonNull InitCallback initCallback) {
Preconditions.checkNotNull(initCallback, "initCallback cannot be null");
diff --git a/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiCompatInitializer.java b/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiCompatInitializer.java
index 2be308f..462d1d4 100644
--- a/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiCompatInitializer.java
+++ b/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiCompatInitializer.java
@@ -49,8 +49,6 @@
* </provider>
* </pre>
*
- * For more information see {@link https://developer.android.com/topic/libraries/app-startup#manual}
- *
* @see androidx.emoji2.text.DefaultEmojiCompatConfig
*/
public class EmojiCompatInitializer implements Initializer<Boolean> {
diff --git a/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiMetadata.java b/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiMetadata.java
index 8f15f52..7244296 100644
--- a/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiMetadata.java
+++ b/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiMetadata.java
@@ -28,8 +28,8 @@
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo;
-import androidx.text.emoji.flatbuffer.MetadataItem;
-import androidx.text.emoji.flatbuffer.MetadataList;
+import androidx.emoji2.text.flatbuffer.MetadataItem;
+import androidx.emoji2.text.flatbuffer.MetadataList;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
diff --git a/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiSpan.java b/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiSpan.java
index 28f39ef..145af0d 100644
--- a/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiSpan.java
+++ b/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiSpan.java
@@ -79,7 +79,8 @@
@Override
public int getSize(@NonNull final Paint paint,
- @SuppressLint("UnknownNullness") final CharSequence text,
+ @SuppressLint("UnknownNullness") @SuppressWarnings("MissingNullability")
+ final CharSequence text,
final int start,
final int end,
@Nullable final Paint.FontMetricsInt fm) {
diff --git a/emoji2/emoji2/src/main/java/androidx/emoji2/text/MetadataListReader.java b/emoji2/emoji2/src/main/java/androidx/emoji2/text/MetadataListReader.java
index 674202d..2ed42e0 100644
--- a/emoji2/emoji2/src/main/java/androidx/emoji2/text/MetadataListReader.java
+++ b/emoji2/emoji2/src/main/java/androidx/emoji2/text/MetadataListReader.java
@@ -22,7 +22,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo;
-import androidx.text.emoji.flatbuffer.MetadataList;
+import androidx.emoji2.text.flatbuffer.MetadataList;
import java.io.IOException;
import java.io.InputStream;
diff --git a/emoji2/emoji2/src/main/java/androidx/emoji2/text/MetadataRepo.java b/emoji2/emoji2/src/main/java/androidx/emoji2/text/MetadataRepo.java
index 27afc5d..bc31e26 100644
--- a/emoji2/emoji2/src/main/java/androidx/emoji2/text/MetadataRepo.java
+++ b/emoji2/emoji2/src/main/java/androidx/emoji2/text/MetadataRepo.java
@@ -25,7 +25,7 @@
import androidx.annotation.RestrictTo;
import androidx.annotation.VisibleForTesting;
import androidx.core.util.Preconditions;
-import androidx.text.emoji.flatbuffer.MetadataList;
+import androidx.emoji2.text.flatbuffer.MetadataList;
import java.io.IOException;
import java.io.InputStream;
diff --git a/fragment/fragment-testing/build.gradle b/fragment/fragment-testing/build.gradle
index 716c481..6c9828d 100644
--- a/fragment/fragment-testing/build.gradle
+++ b/fragment/fragment-testing/build.gradle
@@ -36,8 +36,8 @@
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
androidTestImplementation(TRUTH)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
lintPublish(project(":fragment:fragment-testing-lint"))
}
diff --git a/fragment/fragment/build.gradle b/fragment/fragment/build.gradle
index 57dd500..da73487 100644
--- a/fragment/fragment/build.gradle
+++ b/fragment/fragment/build.gradle
@@ -58,9 +58,9 @@
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
androidTestImplementation(TRUTH)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(MULTIDEX)
androidTestImplementation(project(":internal-testutils-runtime"), {
exclude group: "androidx.fragment", module: "fragment"
diff --git a/gradlew b/gradlew
index a43ff0f..4067d06 100755
--- a/gradlew
+++ b/gradlew
@@ -222,8 +222,14 @@
TMPDIR_ARG="-Djava.io.tmpdir=$TMPDIR"
fi
+if [[ " ${@} " =~ " --clean " ]]; then
+ cleanCaches=true
+else
+ cleanCaches=false
+fi
+
# Expand some arguments
-for compact in "--ci" "--strict"; do
+for compact in "--ci" "--strict" "--clean"; do
if [ "$compact" == "--ci" ]; then
expanded="--strict\
--stacktrace\
@@ -240,30 +246,38 @@
--no-daemon\
--offline"
fi
+ if [ "$compact" == "--clean" ]; then
+ expanded="" # we parsed the argument above but we still have to remove it to avoid confusing Gradle
+ fi
- # Expand an individual argument
- # Start by making a copy of our list of arguments and iterating through the copy
- for arg in "$@"; do
- # Remove this argument from our list of arguments.
- # By the time we've completed this loop, we will have removed the original copy of
- # each argument, and potentially re-added a new copy or an expansion of each.
- shift
- # Determine whether to expand this argument
- if [ "$arg" == "$compact" ]; then
- # Add the expansion to our arguments
- set -- "$@" $expanded
- echo "gradlew expanded '$compact' into '$expanded'"
- echo
- # We avoid re-adding this argument itself back into the list for two reasons:
- # 1. This argument might not be directly understood by Gradle
- # 2. We want to enforce that all behaviors enabled by this flag can be toggled independently,
- # so we don't want it to be easy to inadvertently check for the presence of this flag
- # specifically
- else
- # Add this argument back into our arguments
- set -- "$@" "$arg"
- fi
- done
+ # check whether this particular compat argument was passed (and therefore needs expansion)
+ if [[ " ${@} " =~ " $compact " ]]; then
+ # Expand an individual argument
+ # Start by making a copy of our list of arguments and iterating through the copy
+ for arg in "$@"; do
+ # Remove this argument from our list of arguments.
+ # By the time we've completed this loop, we will have removed the original copy of
+ # each argument, and potentially re-added a new copy or an expansion of each.
+ shift
+ # Determine whether to expand this argument
+ if [ "$arg" == "$compact" ]; then
+ # Add the expansion to our arguments
+ set -- "$@" $expanded
+ if [ "$expanded" != "" ]; then
+ echo "gradlew expanded '$compact' into '$expanded'"
+ echo
+ fi
+ # We avoid re-adding this argument itself back into the list for two reasons:
+ # 1. This argument might not be directly understood by Gradle
+ # 2. We want to enforce that all behaviors enabled by this flag can be toggled independently,
+ # so we don't want it to be easy to inadvertently check for the presence of this flag
+ # specifically
+ else
+ # Add this argument back into our arguments
+ set -- "$@" "$arg"
+ fi
+ done
+ fi
done
function tryToDiagnosePossibleDaemonFailure() {
@@ -276,6 +290,41 @@
fi
}
+function removeCaches() {
+ rm -rf $SCRIPT_PATH/.gradle
+ rm -rf $SCRIPT_PATH/buildSrc/.gradle
+ rm -f $SCRIPT_PATH/local.properties
+ if [ "$GRADLE_USER_HOME" != "" ]; then
+ rm -rf "$GRADLE_USER_HOME"
+ else
+ rm -rf ~/.gradle
+ fi
+ # AGP should (also) do this automatically (b/170640263)
+ rm -rf $SCRIPT_PATH/appsearch/appsearch/.cxx
+ rm -rf $SCRIPT_PATH/appsearch/local-backend/.cxx
+ rm -rf $SCRIPT_PATH/appsearch/local-storage/.cxx
+ rm -rf $OUT_DIR
+}
+
+if [ "$cleanCaches" == true ]; then
+ echo "IF ./gradlew --clean FIXES YOUR BUILD; OPEN A BUG."
+ echo "In nearly all cases, it should not be necessary to run a clean build."
+ echo
+ echo "You may be more interested in running:"
+ echo
+ echo " ./development/diagnose-build-failure/diagnose-build-failure.sh $*"
+ echo
+ echo "which attempts to diagnose more details about build failures."
+ echo
+ echo "Removing caches"
+ # one case where it is convenient to have a clean build is for double-checking that a build failure isn't due to an incremental build failure
+ # another case where it is convenient to have a clean build is for performance testing
+ # another case where it is convenient to have a clean build is when you're modifying the build and may have introduced some errors but haven't shared your changes yet (at which point you should have fixed the errors)
+ echo
+
+ removeCaches
+fi
+
function runGradle() {
processOutput=false
if [[ " ${@} " =~ " -Pandroidx.validateNoUnrecognizedMessages " ]]; then
diff --git a/gridlayout/gridlayout/build.gradle b/gridlayout/gridlayout/build.gradle
index 613a911..b5c5616 100644
--- a/gridlayout/gridlayout/build.gradle
+++ b/gridlayout/gridlayout/build.gradle
@@ -16,7 +16,7 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
}
androidx {
diff --git a/heifwriter/heifwriter/build.gradle b/heifwriter/heifwriter/build.gradle
index b31fef5..2df6655 100644
--- a/heifwriter/heifwriter/build.gradle
+++ b/heifwriter/heifwriter/build.gradle
@@ -21,7 +21,7 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
}
androidx {
diff --git a/leanback/leanback-paging/build.gradle b/leanback/leanback-paging/build.gradle
index 32e4434..415101b 100644
--- a/leanback/leanback-paging/build.gradle
+++ b/leanback/leanback-paging/build.gradle
@@ -19,9 +19,9 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(project(":internal-testutils-espresso"))
androidTestImplementation(project(":internal-testutils-runtime"))
androidTestImplementation(project(":internal-testutils-common"))
diff --git a/leanback/leanback-tab/build.gradle b/leanback/leanback-tab/build.gradle
index 8bad67a..587ee18 100644
--- a/leanback/leanback-tab/build.gradle
+++ b/leanback/leanback-tab/build.gradle
@@ -25,9 +25,9 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(project(":internal-testutils-espresso"))
androidTestImplementation(project(":internal-testutils-runtime"))
androidTestImplementation(project(":internal-testutils-common"))
diff --git a/leanback/leanback/build.gradle b/leanback/leanback/build.gradle
index e0f38fa..cbc1960 100644
--- a/leanback/leanback/build.gradle
+++ b/leanback/leanback/build.gradle
@@ -23,9 +23,9 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(project(":internal-testutils-espresso"))
androidTestImplementation(project(":internal-testutils-runtime"))
androidTestImplementation(project(":internal-testutils-common"))
diff --git a/loader/loader-ktx/build.gradle b/loader/loader-ktx/build.gradle
index e27fe01..12f8e80 100644
--- a/loader/loader-ktx/build.gradle
+++ b/loader/loader-ktx/build.gradle
@@ -38,9 +38,9 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
}
androidx {
diff --git a/loader/loader/build.gradle b/loader/loader/build.gradle
index 3b958cf..315f072 100644
--- a/loader/loader/build.gradle
+++ b/loader/loader/build.gradle
@@ -27,9 +27,9 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
}
androidx {
diff --git a/media/media/build.gradle b/media/media/build.gradle
index 49e34a9..561b834 100644
--- a/media/media/build.gradle
+++ b/media/media/build.gradle
@@ -31,7 +31,7 @@
androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
androidTestImplementation(project(":internal-testutils-runtime"))
annotationProcessor(project(":versionedparcelable:versionedparcelable-compiler"))
}
diff --git a/media2/media2-common/build.gradle b/media2/media2-common/build.gradle
index 45d8b15..e128665 100644
--- a/media2/media2-common/build.gradle
+++ b/media2/media2-common/build.gradle
@@ -38,7 +38,7 @@
androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
androidTestImplementation(project(":internal-testutils-runtime"))
annotationProcessor(project(":versionedparcelable:versionedparcelable-compiler"))
}
diff --git a/media2/media2-player/build.gradle b/media2/media2-player/build.gradle
index 73f080a..cfd7110 100644
--- a/media2/media2-player/build.gradle
+++ b/media2/media2-player/build.gradle
@@ -39,7 +39,7 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
androidTestImplementation(project(":internal-testutils-runtime"))
annotationProcessor(project(":versionedparcelable:versionedparcelable-compiler"))
}
diff --git a/media2/media2-session/build.gradle b/media2/media2-session/build.gradle
index 4aa0edb..47e3b2e 100644
--- a/media2/media2-session/build.gradle
+++ b/media2/media2-session/build.gradle
@@ -37,7 +37,7 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
androidTestImplementation(project(":internal-testutils-runtime"))
annotationProcessor(project(":versionedparcelable:versionedparcelable-compiler"))
}
diff --git a/media2/media2-widget/build.gradle b/media2/media2-widget/build.gradle
index f26fb57..e637e6c 100644
--- a/media2/media2-widget/build.gradle
+++ b/media2/media2-widget/build.gradle
@@ -33,9 +33,9 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(project(":internal-testutils-runtime"))
androidTestImplementation(project(":media2:media2-player"))
}
diff --git a/mediarouter/mediarouter/build.gradle b/mediarouter/mediarouter/build.gradle
index 993ef6e..84c37b6 100644
--- a/mediarouter/mediarouter/build.gradle
+++ b/mediarouter/mediarouter/build.gradle
@@ -37,7 +37,7 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
androidTestImplementation(project(":media:version-compat-tests:lib"))
}
diff --git a/navigation/navigation-common/build.gradle b/navigation/navigation-common/build.gradle
index e45b8cf..5ecb6d0 100644
--- a/navigation/navigation-common/build.gradle
+++ b/navigation/navigation-common/build.gradle
@@ -46,8 +46,8 @@
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ESPRESSO_CORE)
androidTestImplementation(TRUTH)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
androidTestImplementation(KOTLIN_STDLIB)
}
diff --git a/navigation/navigation-dynamic-features-fragment/build.gradle b/navigation/navigation-dynamic-features-fragment/build.gradle
index ccf402b..369f823 100644
--- a/navigation/navigation-dynamic-features-fragment/build.gradle
+++ b/navigation/navigation-dynamic-features-fragment/build.gradle
@@ -42,9 +42,9 @@
androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
androidTestImplementation(ANDROIDX_TEST_RULES)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
androidTestImplementation(ESPRESSO_CORE)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
androidTestImplementation(TRUTH)
androidTestImplementation(project(":internal-testutils-runtime"), {
exclude group: "androidx.fragment", module: "fragment"
diff --git a/navigation/navigation-dynamic-features-runtime/build.gradle b/navigation/navigation-dynamic-features-runtime/build.gradle
index 3853ed4..e395526a 100644
--- a/navigation/navigation-dynamic-features-runtime/build.gradle
+++ b/navigation/navigation-dynamic-features-runtime/build.gradle
@@ -43,9 +43,9 @@
androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
androidTestImplementation(ANDROIDX_TEST_RULES)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
androidTestImplementation(ESPRESSO_CORE)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
androidTestImplementation(TRUTH)
}
diff --git a/navigation/navigation-runtime/build.gradle b/navigation/navigation-runtime/build.gradle
index 8117a55..9ac58b4 100644
--- a/navigation/navigation-runtime/build.gradle
+++ b/navigation/navigation-runtime/build.gradle
@@ -44,8 +44,8 @@
androidTestImplementation(ESPRESSO_CORE)
androidTestImplementation(ESPRESSO_INTENTS)
androidTestImplementation(TRUTH)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
androidTestImplementation(KOTLIN_STDLIB)
}
diff --git a/percentlayout/percentlayout/build.gradle b/percentlayout/percentlayout/build.gradle
index ae86a44..bc6a65e 100644
--- a/percentlayout/percentlayout/build.gradle
+++ b/percentlayout/percentlayout/build.gradle
@@ -16,7 +16,7 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
}
android {
diff --git a/preference/preference/build.gradle b/preference/preference/build.gradle
index 5cc86e5..b26f71e 100644
--- a/preference/preference/build.gradle
+++ b/preference/preference/build.gradle
@@ -38,9 +38,9 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(KOTLIN_STDLIB)
androidTestImplementation(TRUTH)
androidTestImplementation(MULTIDEX)
diff --git a/recyclerview/recyclerview-selection/build.gradle b/recyclerview/recyclerview-selection/build.gradle
index efd061d..d7fcd32 100644
--- a/recyclerview/recyclerview-selection/build.gradle
+++ b/recyclerview/recyclerview-selection/build.gradle
@@ -33,9 +33,9 @@
androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it's own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it's own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it's own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it's own MockMaker
androidTestImplementation(JUNIT)
}
diff --git a/recyclerview/recyclerview/build.gradle b/recyclerview/recyclerview/build.gradle
index a6fe293..b9dc0b6 100644
--- a/recyclerview/recyclerview/build.gradle
+++ b/recyclerview/recyclerview/build.gradle
@@ -19,9 +19,9 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(TRUTH)
androidTestImplementation(JUNIT)
androidTestImplementation(KOTLIN_STDLIB)
diff --git a/remotecallback/remotecallback/build.gradle b/remotecallback/remotecallback/build.gradle
index 2c46eb7..a0ad9c0 100644
--- a/remotecallback/remotecallback/build.gradle
+++ b/remotecallback/remotecallback/build.gradle
@@ -32,8 +32,8 @@
androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
androidTestAnnotationProcessor (project(":remotecallback:remotecallback-processor"))
}
diff --git a/room/integration-tests/autovaluetestapp/build.gradle b/room/integration-tests/autovaluetestapp/build.gradle
index aafd894..01ee90f 100644
--- a/room/integration-tests/autovaluetestapp/build.gradle
+++ b/room/integration-tests/autovaluetestapp/build.gradle
@@ -47,8 +47,8 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ESPRESSO_CORE)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it's own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it's own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it's own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it's own MockMaker
testImplementation(JUNIT)
}
diff --git a/room/integration-tests/testapp/build.gradle b/room/integration-tests/testapp/build.gradle
index edcd26b..f89faf2 100644
--- a/room/integration-tests/testapp/build.gradle
+++ b/room/integration-tests/testapp/build.gradle
@@ -114,8 +114,8 @@
androidTestImplementation(ANDROIDX_TEST_RULES)
androidTestImplementation(ESPRESSO_CORE)
androidTestImplementation(TRUTH)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it's own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it's own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it's own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it's own MockMaker
androidTestImplementation(project(":internal-testutils-truth"))
diff --git a/room/runtime/build.gradle b/room/runtime/build.gradle
index a20e760..6985986 100644
--- a/room/runtime/build.gradle
+++ b/room/runtime/build.gradle
@@ -58,8 +58,8 @@
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ESPRESSO_CORE)
androidTestImplementation(KOTLIN_STDLIB)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(project(":internal-testutils-truth")) // for assertThrows
androidTestImplementation("androidx.arch.core:core-testing:2.0.1")
diff --git a/settings.gradle b/settings.gradle
index b19d4ff..0d383ef 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -63,6 +63,7 @@
break
case "MEDIA":
filter.add(BuildType.MEDIA)
+ break
case "WEAR":
filter.add(BuildType.WEAR)
break
diff --git a/sharetarget/sharetarget/build.gradle b/sharetarget/sharetarget/build.gradle
index 3713624..e911dca 100644
--- a/sharetarget/sharetarget/build.gradle
+++ b/sharetarget/sharetarget/build.gradle
@@ -34,8 +34,8 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
}
androidx {
diff --git a/slices/benchmark/build.gradle b/slices/benchmark/build.gradle
index 19510e2..7b04353 100644
--- a/slices/benchmark/build.gradle
+++ b/slices/benchmark/build.gradle
@@ -35,9 +35,9 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
}
androidx {
diff --git a/slices/core/build.gradle b/slices/core/build.gradle
index a0669c4..90affdb 100644
--- a/slices/core/build.gradle
+++ b/slices/core/build.gradle
@@ -33,8 +33,8 @@
androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
annotationProcessor (project(":versionedparcelable:versionedparcelable-compiler"))
}
diff --git a/slices/remotecallback/build.gradle b/slices/remotecallback/build.gradle
index 2849219..c906165 100644
--- a/slices/remotecallback/build.gradle
+++ b/slices/remotecallback/build.gradle
@@ -34,8 +34,8 @@
androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
androidTestAnnotationProcessor project(":remotecallback:remotecallback-processor")
}
diff --git a/slices/test/build.gradle b/slices/test/build.gradle
index 28e5a52..351e96a 100644
--- a/slices/test/build.gradle
+++ b/slices/test/build.gradle
@@ -34,9 +34,9 @@
androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
}
androidx {
diff --git a/slices/view/build.gradle b/slices/view/build.gradle
index f88be95..48025cc 100644
--- a/slices/view/build.gradle
+++ b/slices/view/build.gradle
@@ -37,9 +37,9 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
}
androidx {
diff --git a/slidingpanelayout/slidingpanelayout/build.gradle b/slidingpanelayout/slidingpanelayout/build.gradle
index 86340b6..4ac36e3 100644
--- a/slidingpanelayout/slidingpanelayout/build.gradle
+++ b/slidingpanelayout/slidingpanelayout/build.gradle
@@ -16,7 +16,7 @@
androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
androidTestImplementation(KOTLIN_STDLIB)
androidTestImplementation(TRUTH)
androidTestImplementation(project(':internal-testutils-runtime'))
diff --git a/sqlite/sqlite-framework/src/main/java/androidx/sqlite/db/framework/FrameworkSQLiteDatabase.java b/sqlite/sqlite-framework/src/main/java/androidx/sqlite/db/framework/FrameworkSQLiteDatabase.java
index 0cc817b..c75894e 100644
--- a/sqlite/sqlite-framework/src/main/java/androidx/sqlite/db/framework/FrameworkSQLiteDatabase.java
+++ b/sqlite/sqlite-framework/src/main/java/androidx/sqlite/db/framework/FrameworkSQLiteDatabase.java
@@ -124,7 +124,7 @@
// Adding @RequiresApi(30) would prevent unbundled implementations from offering this
// functionality to lower API levels.
- @SuppressWarnings("UnsafeNewApiCall")
+ @SuppressWarnings("ClassVerificationFailure")
@Override
public void execPerConnectionSQL(@NonNull String sql, @Nullable Object[] bindArgs) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
diff --git a/startup/integration-tests/first-library/build.gradle b/startup/integration-tests/first-library/build.gradle
index 7b408f1..59ce01d 100644
--- a/startup/integration-tests/first-library/build.gradle
+++ b/startup/integration-tests/first-library/build.gradle
@@ -33,7 +33,7 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ESPRESSO_CORE)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has its own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has its own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has its own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has its own MockMaker
testImplementation(JUNIT)
}
diff --git a/startup/integration-tests/second-library/build.gradle b/startup/integration-tests/second-library/build.gradle
index 36ee190..760958b 100644
--- a/startup/integration-tests/second-library/build.gradle
+++ b/startup/integration-tests/second-library/build.gradle
@@ -32,7 +32,7 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ESPRESSO_CORE)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has its own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has its own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has its own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has its own MockMaker
testImplementation(JUNIT)
}
diff --git a/startup/startup-runtime/build.gradle b/startup/startup-runtime/build.gradle
index 75c3825..9b60091 100644
--- a/startup/startup-runtime/build.gradle
+++ b/startup/startup-runtime/build.gradle
@@ -46,8 +46,8 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ESPRESSO_CORE)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has its own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has its own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has its own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has its own MockMaker
testImplementation(JUNIT)
}
diff --git a/swiperefreshlayout/swiperefreshlayout/build.gradle b/swiperefreshlayout/swiperefreshlayout/build.gradle
index 3eb08fd..94f6bce 100644
--- a/swiperefreshlayout/swiperefreshlayout/build.gradle
+++ b/swiperefreshlayout/swiperefreshlayout/build.gradle
@@ -18,10 +18,10 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(ESPRESSO_CONTRIB, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(ESPRESSO_CONTRIB, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(project(":internal-testutils-espresso"))
androidTestImplementation(project(":internal-testutils-runtime"), {
exclude group: "androidx.swiperefreshlayout", module: "swiperefreshlayout"
diff --git a/testutils/testutils-espresso/build.gradle b/testutils/testutils-espresso/build.gradle
index 0ba77aa..314bef2 100644
--- a/testutils/testutils-espresso/build.gradle
+++ b/testutils/testutils-espresso/build.gradle
@@ -25,7 +25,7 @@
dependencies {
api("androidx.annotation:annotation:1.1.0")
- implementation(ESPRESSO_CORE, libs.exclude_for_espresso)
+ implementation(ESPRESSO_CORE, excludes.espresso)
implementation(KOTLIN_STDLIB)
}
diff --git a/testutils/testutils-mockito/build.gradle b/testutils/testutils-mockito/build.gradle
index ea8a7de..18aaea4 100644
--- a/testutils/testutils-mockito/build.gradle
+++ b/testutils/testutils-mockito/build.gradle
@@ -23,7 +23,7 @@
}
dependencies {
- api(MOCKITO_CORE, libs.exclude_bytebuddy)
+ api(MOCKITO_CORE, excludes.bytebuddy)
implementation(KOTLIN_STDLIB)
}
diff --git a/text/text/build.gradle b/text/text/build.gradle
index f29d53b..684036d 100644
--- a/text/text/build.gradle
+++ b/text/text/build.gradle
@@ -41,11 +41,11 @@
androidTestImplementation(ANDROIDX_TEST_RULES)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(ESPRESSO_CORE)
androidTestImplementation(JUNIT)
androidTestImplementation(TRUTH)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(MOCKITO_KOTLIN, {
exclude group: "org.mockito" // to keep control on the mockito version
})
diff --git a/textclassifier/textclassifier/build.gradle b/textclassifier/textclassifier/build.gradle
index 392d82b..bc5aabc 100644
--- a/textclassifier/textclassifier/build.gradle
+++ b/textclassifier/textclassifier/build.gradle
@@ -19,9 +19,9 @@
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
androidTestImplementation(TRUTH)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
}
android {
diff --git a/transition/transition/build.gradle b/transition/transition/build.gradle
index 7a472ef..9b95adc 100644
--- a/transition/transition/build.gradle
+++ b/transition/transition/build.gradle
@@ -23,9 +23,9 @@
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
androidTestImplementation(TRUTH)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(project(":fragment:fragment"))
androidTestImplementation("androidx.appcompat:appcompat:1.1.0")
androidTestImplementation(project(":internal-testutils-runtime"), {
diff --git a/vectordrawable/vectordrawable-animated/build.gradle b/vectordrawable/vectordrawable-animated/build.gradle
index 57a3bf7..30d3435 100644
--- a/vectordrawable/vectordrawable-animated/build.gradle
+++ b/vectordrawable/vectordrawable-animated/build.gradle
@@ -17,7 +17,7 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
}
android {
diff --git a/vectordrawable/vectordrawable-seekable/build.gradle b/vectordrawable/vectordrawable-seekable/build.gradle
index 7ac21aa..b40844f 100644
--- a/vectordrawable/vectordrawable-seekable/build.gradle
+++ b/vectordrawable/vectordrawable-seekable/build.gradle
@@ -18,7 +18,7 @@
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
androidTestImplementation(TRUTH)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
androidTestImplementation(project(":core:core-animation-testing"))
}
diff --git a/versionedparcelable/versionedparcelable/build.gradle b/versionedparcelable/versionedparcelable/build.gradle
index f4fd9d2..8a6cd7a 100644
--- a/versionedparcelable/versionedparcelable/build.gradle
+++ b/versionedparcelable/versionedparcelable/build.gradle
@@ -32,8 +32,8 @@
androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
androidTestImplementation(TRUTH)
androidTestAnnotationProcessor project(":versionedparcelable:versionedparcelable-compiler")
}
diff --git a/viewpager/viewpager/build.gradle b/viewpager/viewpager/build.gradle
index 7194986..0fa3c58 100644
--- a/viewpager/viewpager/build.gradle
+++ b/viewpager/viewpager/build.gradle
@@ -24,9 +24,9 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
}
androidx {
diff --git a/viewpager2/viewpager2/build.gradle b/viewpager2/viewpager2/build.gradle
index 313262f..96b5361 100644
--- a/viewpager2/viewpager2/build.gradle
+++ b/viewpager2/viewpager2/build.gradle
@@ -36,9 +36,9 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it's own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it's own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it's own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it's own MockMaker
androidTestImplementation(project(":internal-testutils-espresso"))
androidTestImplementation(project(":internal-testutils-appcompat"), {
exclude group: "androidx.viewpager2", module: "viewpager2"
diff --git a/wear/tiles/tiles-renderer/src/main/java/androidx/wear/tiles/manager/TileClient.kt b/wear/tiles/tiles-renderer/src/main/java/androidx/wear/tiles/manager/TileClient.kt
index fd0e37d..c557bdb 100644
--- a/wear/tiles/tiles-renderer/src/main/java/androidx/wear/tiles/manager/TileClient.kt
+++ b/wear/tiles/tiles-renderer/src/main/java/androidx/wear/tiles/manager/TileClient.kt
@@ -29,7 +29,6 @@
import android.widget.FrameLayout
import androidx.annotation.MainThread
import androidx.core.content.ContextCompat
-import androidx.wear.tiles.ViewerTileUpdateRequester
import androidx.wear.tiles.builders.LayoutElementBuilders
import androidx.wear.tiles.builders.ResourceBuilders
import androidx.wear.tiles.builders.TimelineBuilders
@@ -63,6 +62,11 @@
component: ComponentName,
private val parentView: ViewGroup
) : AutoCloseable {
+ private companion object {
+ private const val ACTION_REQUEST_TILE_UPDATE =
+ "androidx.wear.tiles.action.REQUEST_TILE_UPDATE"
+ }
+
private val job = Job()
private val coroutineScope = CoroutineScope(Dispatchers.Main + job)
@@ -194,7 +198,7 @@
}
private fun registerBroadcastReceiver() {
- val i = IntentFilter(ViewerTileUpdateRequester.ACTION_REQUEST_TILE_UPDATE)
+ val i = IntentFilter(Companion.ACTION_REQUEST_TILE_UPDATE)
context.registerReceiver(updateReceiver, i)
}
diff --git a/wear/tiles/tiles/api/current.txt b/wear/tiles/tiles/api/current.txt
index 5a36e7e..ee9c959 100644
--- a/wear/tiles/tiles/api/current.txt
+++ b/wear/tiles/tiles/api/current.txt
@@ -1,12 +1,6 @@
// Signature format: 4.0
package androidx.wear.tiles {
- public class SysUiTileUpdateRequester implements androidx.wear.tiles.TileUpdateRequester {
- ctor public SysUiTileUpdateRequester(android.content.Context);
- method public void requestUpdate(Class<? extends android.app.Service>);
- field public static final String ACTION_BIND_UPDATE_REQUESTER = "androidx.wear.tiles.action.BIND_UPDATE_REQUESTER";
- }
-
public abstract class TileProviderService extends android.app.Service {
ctor public TileProviderService();
method public static androidx.wear.tiles.TileUpdateRequester getUpdater(android.content.Context);
@@ -23,13 +17,7 @@
}
public interface TileUpdateRequester {
- method public void requestUpdate(Class<? extends android.app.Service>);
- }
-
- public class ViewerTileUpdateRequester implements androidx.wear.tiles.TileUpdateRequester {
- ctor public ViewerTileUpdateRequester(android.content.Context);
- method public void requestUpdate(Class<? extends android.app.Service>);
- field public static final String ACTION_REQUEST_TILE_UPDATE = "androidx.wear.tiles.action.REQUEST_TILE_UPDATE";
+ method public void requestUpdate(Class<? extends androidx.wear.tiles.TileProviderService>);
}
}
@@ -651,6 +639,8 @@
public static final class ModifiersBuilders.Padding.Builder {
method public androidx.wear.tiles.builders.ModifiersBuilders.Padding build();
+ method public androidx.wear.tiles.builders.ModifiersBuilders.Padding.Builder setAll(androidx.wear.tiles.builders.DimensionBuilders.DpProp);
+ method public androidx.wear.tiles.builders.ModifiersBuilders.Padding.Builder setAll(androidx.wear.tiles.builders.DimensionBuilders.DpProp.Builder);
method public androidx.wear.tiles.builders.ModifiersBuilders.Padding.Builder setBottom(androidx.wear.tiles.builders.DimensionBuilders.DpProp);
method public androidx.wear.tiles.builders.ModifiersBuilders.Padding.Builder setBottom(androidx.wear.tiles.builders.DimensionBuilders.DpProp.Builder);
method public androidx.wear.tiles.builders.ModifiersBuilders.Padding.Builder setEnd(androidx.wear.tiles.builders.DimensionBuilders.DpProp);
diff --git a/wear/tiles/tiles/api/public_plus_experimental_current.txt b/wear/tiles/tiles/api/public_plus_experimental_current.txt
index 127e950..5a4d2b4 100644
--- a/wear/tiles/tiles/api/public_plus_experimental_current.txt
+++ b/wear/tiles/tiles/api/public_plus_experimental_current.txt
@@ -1,12 +1,6 @@
// Signature format: 4.0
package androidx.wear.tiles {
- public class SysUiTileUpdateRequester implements androidx.wear.tiles.TileUpdateRequester {
- ctor public SysUiTileUpdateRequester(android.content.Context);
- method public void requestUpdate(Class<? extends android.app.Service>);
- field public static final String ACTION_BIND_UPDATE_REQUESTER = "androidx.wear.tiles.action.BIND_UPDATE_REQUESTER";
- }
-
public abstract class TileProviderService extends android.app.Service {
ctor public TileProviderService();
method public static androidx.wear.tiles.TileUpdateRequester getUpdater(android.content.Context);
@@ -23,18 +17,12 @@
}
public interface TileUpdateRequester {
- method public void requestUpdate(Class<? extends android.app.Service>);
+ method public void requestUpdate(Class<? extends androidx.wear.tiles.TileProviderService>);
}
@RequiresOptIn(level=androidx.annotation.RequiresOptIn.Level.ERROR) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD}) public @interface TilesExperimental {
}
- public class ViewerTileUpdateRequester implements androidx.wear.tiles.TileUpdateRequester {
- ctor public ViewerTileUpdateRequester(android.content.Context);
- method public void requestUpdate(Class<? extends android.app.Service>);
- field public static final String ACTION_REQUEST_TILE_UPDATE = "androidx.wear.tiles.action.REQUEST_TILE_UPDATE";
- }
-
}
package androidx.wear.tiles.builders {
@@ -656,6 +644,8 @@
public static final class ModifiersBuilders.Padding.Builder {
method public androidx.wear.tiles.builders.ModifiersBuilders.Padding build();
+ method public androidx.wear.tiles.builders.ModifiersBuilders.Padding.Builder setAll(androidx.wear.tiles.builders.DimensionBuilders.DpProp);
+ method public androidx.wear.tiles.builders.ModifiersBuilders.Padding.Builder setAll(androidx.wear.tiles.builders.DimensionBuilders.DpProp.Builder);
method public androidx.wear.tiles.builders.ModifiersBuilders.Padding.Builder setBottom(androidx.wear.tiles.builders.DimensionBuilders.DpProp);
method public androidx.wear.tiles.builders.ModifiersBuilders.Padding.Builder setBottom(androidx.wear.tiles.builders.DimensionBuilders.DpProp.Builder);
method public androidx.wear.tiles.builders.ModifiersBuilders.Padding.Builder setEnd(androidx.wear.tiles.builders.DimensionBuilders.DpProp);
diff --git a/wear/tiles/tiles/api/restricted_current.txt b/wear/tiles/tiles/api/restricted_current.txt
index 5a36e7e..ee9c959 100644
--- a/wear/tiles/tiles/api/restricted_current.txt
+++ b/wear/tiles/tiles/api/restricted_current.txt
@@ -1,12 +1,6 @@
// Signature format: 4.0
package androidx.wear.tiles {
- public class SysUiTileUpdateRequester implements androidx.wear.tiles.TileUpdateRequester {
- ctor public SysUiTileUpdateRequester(android.content.Context);
- method public void requestUpdate(Class<? extends android.app.Service>);
- field public static final String ACTION_BIND_UPDATE_REQUESTER = "androidx.wear.tiles.action.BIND_UPDATE_REQUESTER";
- }
-
public abstract class TileProviderService extends android.app.Service {
ctor public TileProviderService();
method public static androidx.wear.tiles.TileUpdateRequester getUpdater(android.content.Context);
@@ -23,13 +17,7 @@
}
public interface TileUpdateRequester {
- method public void requestUpdate(Class<? extends android.app.Service>);
- }
-
- public class ViewerTileUpdateRequester implements androidx.wear.tiles.TileUpdateRequester {
- ctor public ViewerTileUpdateRequester(android.content.Context);
- method public void requestUpdate(Class<? extends android.app.Service>);
- field public static final String ACTION_REQUEST_TILE_UPDATE = "androidx.wear.tiles.action.REQUEST_TILE_UPDATE";
+ method public void requestUpdate(Class<? extends androidx.wear.tiles.TileProviderService>);
}
}
@@ -651,6 +639,8 @@
public static final class ModifiersBuilders.Padding.Builder {
method public androidx.wear.tiles.builders.ModifiersBuilders.Padding build();
+ method public androidx.wear.tiles.builders.ModifiersBuilders.Padding.Builder setAll(androidx.wear.tiles.builders.DimensionBuilders.DpProp);
+ method public androidx.wear.tiles.builders.ModifiersBuilders.Padding.Builder setAll(androidx.wear.tiles.builders.DimensionBuilders.DpProp.Builder);
method public androidx.wear.tiles.builders.ModifiersBuilders.Padding.Builder setBottom(androidx.wear.tiles.builders.DimensionBuilders.DpProp);
method public androidx.wear.tiles.builders.ModifiersBuilders.Padding.Builder setBottom(androidx.wear.tiles.builders.DimensionBuilders.DpProp.Builder);
method public androidx.wear.tiles.builders.ModifiersBuilders.Padding.Builder setEnd(androidx.wear.tiles.builders.DimensionBuilders.DpProp);
diff --git a/wear/tiles/tiles/build.gradle b/wear/tiles/tiles/build.gradle
index d09b526..1856407 100644
--- a/wear/tiles/tiles/build.gradle
+++ b/wear/tiles/tiles/build.gradle
@@ -39,6 +39,7 @@
testImplementation(ANDROIDX_TEST_CORE)
testImplementation(ANDROIDX_TEST_RUNNER)
testImplementation(ANDROIDX_TEST_RULES)
+ testImplementation("androidx.concurrent:concurrent-futures:1.1.0")
testImplementation(ROBOLECTRIC)
testImplementation(MOCKITO_CORE)
}
diff --git a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/CompositeTileUpdateRequester.java b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/CompositeTileUpdateRequester.java
index 402a6e2..c97773d 100644
--- a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/CompositeTileUpdateRequester.java
+++ b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/CompositeTileUpdateRequester.java
@@ -16,8 +16,6 @@
package androidx.wear.tiles;
-import android.app.Service;
-
import androidx.annotation.NonNull;
import java.util.List;
@@ -36,7 +34,7 @@
}
@Override
- public void requestUpdate(@NonNull Class<? extends Service> tileProvider) {
+ public void requestUpdate(@NonNull Class<? extends TileProviderService> tileProvider) {
for (TileUpdateRequester requester : mUpdateRequesters) {
requester.requestUpdate(tileProvider);
}
diff --git a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/SysUiTileUpdateRequester.java b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/SysUiTileUpdateRequester.java
index 6e2c156..3965e0e7 100644
--- a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/SysUiTileUpdateRequester.java
+++ b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/SysUiTileUpdateRequester.java
@@ -40,7 +40,7 @@
/** Variant of {@link TileUpdateRequester} which requests an update from the Wear SysUI app. */
// TODO(b/173688156): Renovate this whole class, and especially work around all the locks.
-public class SysUiTileUpdateRequester implements TileUpdateRequester {
+class SysUiTileUpdateRequester implements TileUpdateRequester {
private static final String TAG = "HTUpdateRequester";
private static final String DEFAULT_TARGET_SYSUI = "com.google.android.wearable.app";
@@ -64,7 +64,7 @@
}
@Override
- public void requestUpdate(@NonNull Class<? extends Service> tileProvider) {
+ public void requestUpdate(@NonNull Class<? extends TileProviderService> tileProvider) {
synchronized (mLock) {
mPendingServices.add(tileProvider);
diff --git a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/TileUpdateRequester.java b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/TileUpdateRequester.java
index 4d868ae..02e3640 100644
--- a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/TileUpdateRequester.java
+++ b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/TileUpdateRequester.java
@@ -16,8 +16,6 @@
package androidx.wear.tiles;
-import android.app.Service;
-
import androidx.annotation.NonNull;
/**
@@ -26,5 +24,5 @@
*/
public interface TileUpdateRequester {
/** Notify the Tile Renderer that it should fetch a new Timeline from this Tile Provider. */
- void requestUpdate(@NonNull Class<? extends Service> tileProvider);
+ void requestUpdate(@NonNull Class<? extends TileProviderService> tileProvider);
}
diff --git a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/ViewerTileUpdateRequester.java b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/ViewerTileUpdateRequester.java
index fd33065..6ac26b7 100644
--- a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/ViewerTileUpdateRequester.java
+++ b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/ViewerTileUpdateRequester.java
@@ -16,7 +16,6 @@
package androidx.wear.tiles;
-import android.app.Service;
import android.content.Context;
import android.content.Intent;
@@ -26,7 +25,7 @@
* {@link TileUpdateRequester} which notifies the viewer that it should fetch a new version of the
* Timeline.
*/
-public class ViewerTileUpdateRequester implements TileUpdateRequester {
+class ViewerTileUpdateRequester implements TileUpdateRequester {
/**
* The intent action used so a Tile Provider can request that the platform fetches a new
* Timeline from it.
@@ -41,7 +40,7 @@
}
@Override
- public void requestUpdate(@NonNull Class<? extends Service> tileProvider) {
+ public void requestUpdate(@NonNull Class<? extends TileProviderService> tileProvider) {
mContext.sendBroadcast(buildUpdateIntent(mContext.getPackageName()));
}
diff --git a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/builders/ActionBuilders.java b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/builders/ActionBuilders.java
index 8d2f07b..aa76027 100644
--- a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/builders/ActionBuilders.java
+++ b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/builders/ActionBuilders.java
@@ -368,6 +368,33 @@
@NonNull
ActionProto.AndroidExtra toAndroidExtraProto();
+ /**
+ * Return an instance of one of this object's subtypes, from the protocol buffer
+ * representation.
+ *
+ * @hide
+ */
+ @RestrictTo(Scope.LIBRARY_GROUP)
+ @NonNull
+ static AndroidExtra fromAndroidExtraProto(@NonNull ActionProto.AndroidExtra proto) {
+ if (proto.hasStringVal()) {
+ return AndroidStringExtra.fromProto(proto.getStringVal());
+ }
+ if (proto.hasIntVal()) {
+ return AndroidIntExtra.fromProto(proto.getIntVal());
+ }
+ if (proto.hasLongVal()) {
+ return AndroidLongExtra.fromProto(proto.getLongVal());
+ }
+ if (proto.hasDoubleVal()) {
+ return AndroidDoubleExtra.fromProto(proto.getDoubleVal());
+ }
+ if (proto.hasBooleanVal()) {
+ return AndroidBooleanExtra.fromProto(proto.getBooleanVal());
+ }
+ throw new IllegalStateException("Proto was not a recognised instance of AndroidExtra");
+ }
+
/** Builder to create {@link AndroidExtra} objects. */
@SuppressLint("StaticFinalBuilder")
interface Builder {
@@ -615,6 +642,24 @@
@NonNull
ActionProto.Action toActionProto();
+ /**
+ * Return an instance of one of this object's subtypes, from the protocol buffer
+ * representation.
+ *
+ * @hide
+ */
+ @RestrictTo(Scope.LIBRARY_GROUP)
+ @NonNull
+ static Action fromActionProto(@NonNull ActionProto.Action proto) {
+ if (proto.hasLaunchAction()) {
+ return LaunchAction.fromProto(proto.getLaunchAction());
+ }
+ if (proto.hasLoadAction()) {
+ return LoadAction.fromProto(proto.getLoadAction());
+ }
+ throw new IllegalStateException("Proto was not a recognised instance of Action");
+ }
+
/** Builder to create {@link Action} objects. */
@SuppressLint("StaticFinalBuilder")
interface Builder {
diff --git a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/builders/DimensionBuilders.java b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/builders/DimensionBuilders.java
index 2cff2b5..ac0d7fa 100644
--- a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/builders/DimensionBuilders.java
+++ b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/builders/DimensionBuilders.java
@@ -518,6 +518,29 @@
@NonNull
DimensionProto.ContainerDimension toContainerDimensionProto();
+ /**
+ * Return an instance of one of this object's subtypes, from the protocol buffer
+ * representation.
+ *
+ * @hide
+ */
+ @RestrictTo(Scope.LIBRARY_GROUP)
+ @NonNull
+ static ContainerDimension fromContainerDimensionProto(
+ @NonNull DimensionProto.ContainerDimension proto) {
+ if (proto.hasLinearDimension()) {
+ return DpProp.fromProto(proto.getLinearDimension());
+ }
+ if (proto.hasExpandedDimension()) {
+ return ExpandedDimensionProp.fromProto(proto.getExpandedDimension());
+ }
+ if (proto.hasWrappedDimension()) {
+ return WrappedDimensionProp.fromProto(proto.getWrappedDimension());
+ }
+ throw new IllegalStateException(
+ "Proto was not a recognised instance of ContainerDimension");
+ }
+
/** Builder to create {@link ContainerDimension} objects. */
@SuppressLint("StaticFinalBuilder")
interface Builder {
@@ -539,6 +562,29 @@
@NonNull
DimensionProto.ImageDimension toImageDimensionProto();
+ /**
+ * Return an instance of one of this object's subtypes, from the protocol buffer
+ * representation.
+ *
+ * @hide
+ */
+ @RestrictTo(Scope.LIBRARY_GROUP)
+ @NonNull
+ static ImageDimension fromImageDimensionProto(
+ @NonNull DimensionProto.ImageDimension proto) {
+ if (proto.hasLinearDimension()) {
+ return DpProp.fromProto(proto.getLinearDimension());
+ }
+ if (proto.hasExpandedDimension()) {
+ return ExpandedDimensionProp.fromProto(proto.getExpandedDimension());
+ }
+ if (proto.hasProportionalDimension()) {
+ return ProportionalDimensionProp.fromProto(proto.getProportionalDimension());
+ }
+ throw new IllegalStateException(
+ "Proto was not a recognised instance of ImageDimension");
+ }
+
/** Builder to create {@link ImageDimension} objects. */
@SuppressLint("StaticFinalBuilder")
interface Builder {
@@ -560,6 +606,23 @@
@NonNull
DimensionProto.SpacerDimension toSpacerDimensionProto();
+ /**
+ * Return an instance of one of this object's subtypes, from the protocol buffer
+ * representation.
+ *
+ * @hide
+ */
+ @RestrictTo(Scope.LIBRARY_GROUP)
+ @NonNull
+ static SpacerDimension fromSpacerDimensionProto(
+ @NonNull DimensionProto.SpacerDimension proto) {
+ if (proto.hasLinearDimension()) {
+ return DpProp.fromProto(proto.getLinearDimension());
+ }
+ throw new IllegalStateException(
+ "Proto was not a recognised instance of SpacerDimension");
+ }
+
/** Builder to create {@link SpacerDimension} objects. */
@SuppressLint("StaticFinalBuilder")
interface Builder {
diff --git a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/builders/LayoutElementBuilders.java b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/builders/LayoutElementBuilders.java
index 060f09e..3d53863 100644
--- a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/builders/LayoutElementBuilders.java
+++ b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/builders/LayoutElementBuilders.java
@@ -105,10 +105,10 @@
*
* @hide
*/
- @OptIn(markerClass = TilesExperimental.class)
@RestrictTo(RestrictTo.Scope.LIBRARY)
@IntDef({FONT_WEIGHT_UNDEFINED, FONT_WEIGHT_NORMAL, FONT_WEIGHT_MEDIUM, FONT_WEIGHT_BOLD})
@Retention(RetentionPolicy.SOURCE)
+ @OptIn(markerClass = TilesExperimental.class)
public @interface FontWeight {}
/** Font weight is undefined. */
@@ -1309,6 +1309,24 @@
@NonNull
LayoutElementProto.Span toSpanProto();
+ /**
+ * Return an instance of one of this object's subtypes, from the protocol buffer
+ * representation.
+ *
+ * @hide
+ */
+ @RestrictTo(Scope.LIBRARY_GROUP)
+ @NonNull
+ static Span fromSpanProto(@NonNull LayoutElementProto.Span proto) {
+ if (proto.hasText()) {
+ return SpanText.fromProto(proto.getText());
+ }
+ if (proto.hasImage()) {
+ return SpanImage.fromProto(proto.getImage());
+ }
+ throw new IllegalStateException("Proto was not a recognised instance of Span");
+ }
+
/** Builder to create {@link Span} objects. */
@SuppressLint("StaticFinalBuilder")
interface Builder {
@@ -2379,6 +2397,43 @@
@NonNull
LayoutElementProto.LayoutElement toLayoutElementProto();
+ /**
+ * Return an instance of one of this object's subtypes, from the protocol buffer
+ * representation.
+ *
+ * @hide
+ */
+ @RestrictTo(Scope.LIBRARY_GROUP)
+ @NonNull
+ static LayoutElement fromLayoutElementProto(
+ @NonNull LayoutElementProto.LayoutElement proto) {
+ if (proto.hasColumn()) {
+ return Column.fromProto(proto.getColumn());
+ }
+ if (proto.hasRow()) {
+ return Row.fromProto(proto.getRow());
+ }
+ if (proto.hasBox()) {
+ return Box.fromProto(proto.getBox());
+ }
+ if (proto.hasSpacer()) {
+ return Spacer.fromProto(proto.getSpacer());
+ }
+ if (proto.hasText()) {
+ return Text.fromProto(proto.getText());
+ }
+ if (proto.hasImage()) {
+ return Image.fromProto(proto.getImage());
+ }
+ if (proto.hasArc()) {
+ return Arc.fromProto(proto.getArc());
+ }
+ if (proto.hasSpannable()) {
+ return Spannable.fromProto(proto.getSpannable());
+ }
+ throw new IllegalStateException("Proto was not a recognised instance of LayoutElement");
+ }
+
/** Builder to create {@link LayoutElement} objects. */
@SuppressLint("StaticFinalBuilder")
interface Builder {
@@ -2403,6 +2458,32 @@
@NonNull
LayoutElementProto.ArcLayoutElement toArcLayoutElementProto();
+ /**
+ * Return an instance of one of this object's subtypes, from the protocol buffer
+ * representation.
+ *
+ * @hide
+ */
+ @RestrictTo(Scope.LIBRARY_GROUP)
+ @NonNull
+ static ArcLayoutElement fromArcLayoutElementProto(
+ @NonNull LayoutElementProto.ArcLayoutElement proto) {
+ if (proto.hasText()) {
+ return ArcText.fromProto(proto.getText());
+ }
+ if (proto.hasLine()) {
+ return ArcLine.fromProto(proto.getLine());
+ }
+ if (proto.hasSpacer()) {
+ return ArcSpacer.fromProto(proto.getSpacer());
+ }
+ if (proto.hasAdapter()) {
+ return ArcAdapter.fromProto(proto.getAdapter());
+ }
+ throw new IllegalStateException(
+ "Proto was not a recognised instance of ArcLayoutElement");
+ }
+
/** Builder to create {@link ArcLayoutElement} objects. */
@SuppressLint("StaticFinalBuilder")
interface Builder {
diff --git a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/builders/ModifiersBuilders.java b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/builders/ModifiersBuilders.java
index 25c24de..abb9b04 100644
--- a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/builders/ModifiersBuilders.java
+++ b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/builders/ModifiersBuilders.java
@@ -287,6 +287,23 @@
return this;
}
+ /** Sets the padding for all sides of the content, in DP. */
+ @SuppressLint("MissingGetterMatchingBuilder")
+ @NonNull
+ public Builder setAll(@NonNull DpProp value) {
+ return setStart(value).setEnd(value).setTop(value).setBottom(value);
+ }
+
+ /** Sets the padding for all sides of the content, in DP. */
+ @SuppressLint("MissingGetterMatchingBuilder")
+ @NonNull
+ public Builder setAll(@NonNull DpProp.Builder valueBuilder) {
+ return setStart(valueBuilder)
+ .setEnd(valueBuilder)
+ .setTop(valueBuilder)
+ .setBottom(valueBuilder);
+ }
+
/** Builds an instance from accumulated values. */
@NonNull
public Padding build() {
diff --git a/wear/tiles/tiles/src/test/java/androidx/wear/tiles/CompositeTileUpdateRequesterTest.java b/wear/tiles/tiles/src/test/java/androidx/wear/tiles/CompositeTileUpdateRequesterTest.java
index 3331d23..15aa6a4 100644
--- a/wear/tiles/tiles/src/test/java/androidx/wear/tiles/CompositeTileUpdateRequesterTest.java
+++ b/wear/tiles/tiles/src/test/java/androidx/wear/tiles/CompositeTileUpdateRequesterTest.java
@@ -18,12 +18,17 @@
import static com.google.common.truth.Truth.assertThat;
-import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.concurrent.futures.ResolvableFuture;
+import androidx.wear.tiles.builders.ResourceBuilders;
+import androidx.wear.tiles.builders.TileBuilders;
+import androidx.wear.tiles.readers.RequestReaders;
+
+import com.google.common.util.concurrent.ListenableFuture;
import org.junit.Before;
import org.junit.Test;
@@ -60,15 +65,33 @@
}
private class FakeUpdateRequester implements TileUpdateRequester {
- @Nullable Class<? extends Service> mCalledService = null;
+ @Nullable Class<? extends TileProviderService> mCalledService = null;
@Override
- public void requestUpdate(@NonNull Class<? extends Service> tileProvider) {
+ public void requestUpdate(@NonNull Class<? extends TileProviderService> tileProvider) {
this.mCalledService = tileProvider;
}
}
- private class FakeService extends Service {
+ private class FakeService extends TileProviderService {
+ @NonNull
+ @Override
+ protected ListenableFuture<TileBuilders.Tile> onTileRequest(
+ @NonNull RequestReaders.TileRequest requestParams) {
+ ResolvableFuture<TileBuilders.Tile> f = ResolvableFuture.create();
+ f.set(null);
+ return f;
+ }
+
+ @NonNull
+ @Override
+ protected ListenableFuture<ResourceBuilders.Resources> onResourcesRequest(
+ @NonNull RequestReaders.ResourcesRequest requestParams) {
+ ResolvableFuture<ResourceBuilders.Resources> f = ResolvableFuture.create();
+ f.set(null);
+ return f;
+ }
+
@Nullable
@Override
public IBinder onBind(Intent intent) {
diff --git a/wear/wear-complications-data/src/test/java/androidx/wear/complications/ProviderInfoRetrieverTest.kt b/wear/wear-complications-data/src/test/java/androidx/wear/complications/ProviderInfoRetrieverTest.kt
index 6dbf82b..6f3382f 100644
--- a/wear/wear-complications-data/src/test/java/androidx/wear/complications/ProviderInfoRetrieverTest.kt
+++ b/wear/wear-complications-data/src/test/java/androidx/wear/complications/ProviderInfoRetrieverTest.kt
@@ -59,7 +59,7 @@
private val providerInfoRetriever = ProviderInfoRetriever(mockService)
@Test
- public fun requestPreviewComplicationData() {
+ public fun retrievePreviewComplicationData() {
runBlocking {
val component = ComponentName("provider.package", "provider.class")
val type = ComplicationType.LONG_TEXT
@@ -93,7 +93,7 @@
}
@Test
- public fun requestPreviewComplicationDataProviderReturnsNull() {
+ public fun retrievePreviewComplicationDataProviderReturnsNull() {
runBlocking {
val component = ComponentName("provider.package", "provider.class")
val type = ComplicationType.LONG_TEXT
@@ -116,7 +116,7 @@
}
@Test
- public fun requestPreviewComplicationDataApiNotSupported() {
+ public fun retrievePreviewComplicationDataApiNotSupported() {
runBlocking {
val component = ComponentName("provider.package", "provider.class")
val type = ComplicationType.LONG_TEXT
@@ -129,7 +129,7 @@
}
@Test
- public fun requestPreviewComplicationDataApiReturnsFalse() {
+ public fun retrievePreviewComplicationDataApiReturnsFalse() {
runBlocking {
val component = ComponentName("provider.package", "provider.class")
val type = ComplicationType.LONG_TEXT
diff --git a/wear/wear-ongoing/api/current.txt b/wear/wear-ongoing/api/current.txt
index cf3b4ea..779ba555 100644
--- a/wear/wear-ongoing/api/current.txt
+++ b/wear/wear-ongoing/api/current.txt
@@ -3,9 +3,19 @@
@RequiresApi(24) public final class OngoingActivity {
method public void apply(android.content.Context);
- method public static androidx.wear.ongoing.OngoingActivity? fromExistingOngoingActivity(android.content.Context, java.util.function.Predicate<androidx.wear.ongoing.OngoingActivityData!>);
- method public static androidx.wear.ongoing.OngoingActivity? fromExistingOngoingActivity(android.content.Context);
- method public static androidx.wear.ongoing.OngoingActivity? fromExistingOngoingActivity(android.content.Context, int);
+ method public android.graphics.drawable.Icon? getAnimatedIcon();
+ method public String? getCategory();
+ method public androidx.core.content.LocusIdCompat? getLocusId();
+ method public int getNotificationId();
+ method public int getOngoingActivityId();
+ method public android.graphics.drawable.Icon getStaticIcon();
+ method public androidx.wear.ongoing.OngoingActivityStatus? getStatus();
+ method public String? getTag();
+ method public long getTimestamp();
+ method public android.app.PendingIntent getTouchIntent();
+ method public static androidx.wear.ongoing.OngoingActivity? recoverOngoingActivity(android.content.Context, java.util.function.Predicate<androidx.wear.ongoing.OngoingActivityData!>);
+ method public static androidx.wear.ongoing.OngoingActivity? recoverOngoingActivity(android.content.Context);
+ method public static androidx.wear.ongoing.OngoingActivity? recoverOngoingActivity(android.content.Context, int);
method public void update(android.content.Context, androidx.wear.ongoing.OngoingActivityStatus);
}
diff --git a/wear/wear-ongoing/api/public_plus_experimental_current.txt b/wear/wear-ongoing/api/public_plus_experimental_current.txt
index c35669e..3c959c3 100644
--- a/wear/wear-ongoing/api/public_plus_experimental_current.txt
+++ b/wear/wear-ongoing/api/public_plus_experimental_current.txt
@@ -3,9 +3,19 @@
@RequiresApi(24) public final class OngoingActivity {
method public void apply(android.content.Context);
- method public static androidx.wear.ongoing.OngoingActivity? fromExistingOngoingActivity(android.content.Context, java.util.function.Predicate<androidx.wear.ongoing.OngoingActivityData!>);
- method public static androidx.wear.ongoing.OngoingActivity? fromExistingOngoingActivity(android.content.Context);
- method public static androidx.wear.ongoing.OngoingActivity? fromExistingOngoingActivity(android.content.Context, int);
+ method public android.graphics.drawable.Icon? getAnimatedIcon();
+ method public String? getCategory();
+ method public androidx.core.content.LocusIdCompat? getLocusId();
+ method public int getNotificationId();
+ method public int getOngoingActivityId();
+ method public android.graphics.drawable.Icon getStaticIcon();
+ method public androidx.wear.ongoing.OngoingActivityStatus? getStatus();
+ method public String? getTag();
+ method public long getTimestamp();
+ method public android.app.PendingIntent getTouchIntent();
+ method public static androidx.wear.ongoing.OngoingActivity? recoverOngoingActivity(android.content.Context, java.util.function.Predicate<androidx.wear.ongoing.OngoingActivityData!>);
+ method public static androidx.wear.ongoing.OngoingActivity? recoverOngoingActivity(android.content.Context);
+ method public static androidx.wear.ongoing.OngoingActivity? recoverOngoingActivity(android.content.Context, int);
method public void update(android.content.Context, androidx.wear.ongoing.OngoingActivityStatus);
}
diff --git a/wear/wear-ongoing/api/restricted_current.txt b/wear/wear-ongoing/api/restricted_current.txt
index c35669e..3c959c3 100644
--- a/wear/wear-ongoing/api/restricted_current.txt
+++ b/wear/wear-ongoing/api/restricted_current.txt
@@ -3,9 +3,19 @@
@RequiresApi(24) public final class OngoingActivity {
method public void apply(android.content.Context);
- method public static androidx.wear.ongoing.OngoingActivity? fromExistingOngoingActivity(android.content.Context, java.util.function.Predicate<androidx.wear.ongoing.OngoingActivityData!>);
- method public static androidx.wear.ongoing.OngoingActivity? fromExistingOngoingActivity(android.content.Context);
- method public static androidx.wear.ongoing.OngoingActivity? fromExistingOngoingActivity(android.content.Context, int);
+ method public android.graphics.drawable.Icon? getAnimatedIcon();
+ method public String? getCategory();
+ method public androidx.core.content.LocusIdCompat? getLocusId();
+ method public int getNotificationId();
+ method public int getOngoingActivityId();
+ method public android.graphics.drawable.Icon getStaticIcon();
+ method public androidx.wear.ongoing.OngoingActivityStatus? getStatus();
+ method public String? getTag();
+ method public long getTimestamp();
+ method public android.app.PendingIntent getTouchIntent();
+ method public static androidx.wear.ongoing.OngoingActivity? recoverOngoingActivity(android.content.Context, java.util.function.Predicate<androidx.wear.ongoing.OngoingActivityData!>);
+ method public static androidx.wear.ongoing.OngoingActivity? recoverOngoingActivity(android.content.Context);
+ method public static androidx.wear.ongoing.OngoingActivity? recoverOngoingActivity(android.content.Context, int);
method public void update(android.content.Context, androidx.wear.ongoing.OngoingActivityStatus);
}
diff --git a/wear/wear-ongoing/src/main/java/androidx/wear/ongoing/OngoingActivity.java b/wear/wear-ongoing/src/main/java/androidx/wear/ongoing/OngoingActivity.java
index 0879272..6c53230 100644
--- a/wear/wear-ongoing/src/main/java/androidx/wear/ongoing/OngoingActivity.java
+++ b/wear/wear-ongoing/src/main/java/androidx/wear/ongoing/OngoingActivity.java
@@ -50,11 +50,16 @@
* notificationManager.notify(notificationId, builder.build());
* }</pre>
*
+ * Note that if a Notification with that id was previously posted it will be replaced. If you
+ * need more than one Notification with the same ID you can use a String tag to differentiate
+ * them in both the {@link Builder#Builder(Context, String, int, NotificationCompat.Builder)} and
+ * {@link NotificationManager#notify(String, int, Notification)}
+ * <p>
* Afterward, {@link OngoingActivity#update(Context, OngoingActivityStatus) update} can be used to
* update the status.
* <p>
* If saving the {@link OngoingActivity} instance is not convenient, it can be recovered (after the
- * notification is posted) with {@link OngoingActivity#fromExistingOngoingActivity(Context)}
+ * notification is posted) with {@link OngoingActivity#recoverOngoingActivity(Context)}
*/
@RequiresApi(24)
public final class OngoingActivity {
@@ -132,8 +137,6 @@
* {@link OngoingActivity}. For example, in the WatchFace.
* Should be white with a transparent background, preferably an AnimatedVectorDrawable.
*/
- @SuppressWarnings("MissingGetterMatchingBuilder")
- // No getters needed on OngoingActivity - receiver will consume from OngoingActivityData.
@NonNull
public Builder setAnimatedIcon(@NonNull Icon animatedIcon) {
mAnimatedIcon = animatedIcon;
@@ -145,8 +148,6 @@
* {@link OngoingActivity}. For example, in the WatchFace.
* Should be white with a transparent background, preferably an AnimatedVectorDrawable.
*/
- @SuppressWarnings("MissingGetterMatchingBuilder")
- // No getters needed on OngoingActivity - receiver will consume from OngoingActivityData.
@NonNull
public Builder setAnimatedIcon(@DrawableRes int animatedIcon) {
mAnimatedIcon = Icon.createWithResource(mContext, animatedIcon);
@@ -158,8 +159,6 @@
* {@link OngoingActivity}, for example in the WatchFace in ambient mode.
* Should be white with a transparent background, preferably an VectorDrawable.
*/
- @SuppressWarnings("MissingGetterMatchingBuilder")
- // No getters needed on OngoingActivity - receiver will consume from OngoingActivityData.
@NonNull
public Builder setStaticIcon(@NonNull Icon staticIcon) {
mStaticIcon = staticIcon;
@@ -171,8 +170,6 @@
* {@link OngoingActivity}, for example in the WatchFace in ambient mode.
* Should be white with a transparent background, preferably an VectorDrawable.
*/
- @SuppressWarnings("MissingGetterMatchingBuilder")
- // No getters needed on OngoingActivity - receiver will consume from OngoingActivityData.
@NonNull
public Builder setStaticIcon(@DrawableRes int staticIcon) {
mStaticIcon = Icon.createWithResource(mContext, staticIcon);
@@ -183,8 +180,6 @@
* Set the initial status of this ongoing activity, the status may be displayed on the UI to
* show progress of the Ongoing Activity.
*/
- @SuppressWarnings("MissingGetterMatchingBuilder")
- // No getters needed on OngoingActivity - receiver will consume from OngoingActivityData.
@NonNull
public Builder setStatus(@NonNull OngoingActivityStatus status) {
mStatus = status;
@@ -195,8 +190,6 @@
* Set the intent to be used to go back to the activity when the user interacts with the
* Ongoing Activity in other surfaces (for example, taps the Icon on the WatchFace)
*/
- @SuppressWarnings("MissingGetterMatchingBuilder")
- // No getters needed on OngoingActivity - receiver will consume from OngoingActivityData.
@NonNull
public Builder setTouchIntent(@NonNull PendingIntent touchIntent) {
mTouchIntent = touchIntent;
@@ -207,8 +200,6 @@
* Set the corresponding LocusId of this {@link OngoingActivity}, this will be used by the
* launcher to identify the corresponding launcher item and display it accordingly.
*/
- @SuppressWarnings("MissingGetterMatchingBuilder")
- // No getters needed on OngoingActivity - receiver will consume from OngoingActivityData.
@NonNull
public Builder setLocusId(@NonNull LocusIdCompat locusId) {
mLocusId = locusId;
@@ -217,10 +208,8 @@
/**
* Give an id to this {@link OngoingActivity}, as a way to reference it in
- * {@link OngoingActivity#fromExistingOngoingActivity(Context, int)}
+ * {@link OngoingActivity#recoverOngoingActivity(Context, int)}
*/
- @SuppressWarnings("MissingGetterMatchingBuilder")
- // No getters needed on OngoingActivity - receiver will consume from OngoingActivityData.
@NonNull
public Builder setOngoingActivityId(int ongoingActivityId) {
mOngoingActivityId = ongoingActivityId;
@@ -231,8 +220,6 @@
* Set the category of this {@link OngoingActivity}, this may be used by the system to
* prioritize it.
*/
- @SuppressWarnings("MissingGetterMatchingBuilder")
- // No getters needed on OngoingActivity - receiver will consume from OngoingActivityData.
@NonNull
public Builder setCategory(@NonNull String category) {
mCategory = category;
@@ -291,6 +278,95 @@
}
/**
+ * Get the notificationId of the notification associated with this {@link OngoingActivity}.
+ */
+ public int getNotificationId() {
+ return mNotificationId;
+ }
+
+ /**
+ * Get the tag of the notification associated with this {@link OngoingActivity}, or null if
+ * there is none.
+ */
+ @Nullable
+ public String getTag() {
+ return mTag;
+ }
+
+ /**
+ * Get the animated icon that can be used on some surfaces to represent this
+ * {@link OngoingActivity}. For example, in the WatchFace.
+ */
+ @Nullable
+ public Icon getAnimatedIcon() {
+ return mData.getAnimatedIcon();
+ }
+
+ /**
+ * Get the static icon that can be used on some surfaces to represent this
+ * {@link OngoingActivity}. For example in the WatchFace in ambient mode. If not set, returns
+ * the small icon of the corresponding Notification.
+ */
+ @NonNull
+ public Icon getStaticIcon() {
+ return mData.getStaticIcon();
+ }
+
+ /**
+ * Get the status of this ongoing activity, the status may be displayed on the UI to
+ * show progress of the Ongoing Activity. If not set, returns the content text of the
+ * corresponding Notification.
+ */
+ @Nullable
+ public OngoingActivityStatus getStatus() {
+ return mData.getStatus();
+ }
+
+ /**
+ * Get the intent to be used to go back to the activity when the user interacts with the
+ * Ongoing Activity in other surfaces (for example, taps the Icon on the WatchFace). If not
+ * set, returns the touch intent of the corresponding Notification.
+ */
+ @NonNull
+ public PendingIntent getTouchIntent() {
+ return mData.getTouchIntent();
+ }
+
+ /**
+ * Get the LocusId of this {@link OngoingActivity}, this can be used by the launcher to
+ * identify the corresponding launcher item and display it accordingly. If not set, returns
+ * the one in the corresponding Notification.
+ */
+ @Nullable
+ public LocusIdCompat getLocusId() {
+ return mData.getLocusId();
+ }
+
+ /**
+ * Get the id to this {@link OngoingActivity}. This id is used to reference it in
+ * {@link #recoverOngoingActivity(Context, int)}
+ */
+ public int getOngoingActivityId() {
+ return mData.getOngoingActivityId();
+ }
+
+ /**
+ * Get the Category of this {@link OngoingActivity} if set, otherwise the category of the
+ * corresponding notification.
+ */
+ @Nullable
+ public String getCategory() {
+ return mData.getCategory();
+ }
+
+ /**
+ * Get the time (in {@link SystemClock#elapsedRealtime()} time) the OngoingActivity was built.
+ */
+ public long getTimestamp() {
+ return mData.getTimestamp();
+ }
+
+ /**
* Notify the system that this activity should be shown as an Ongoing Activity.
*
* This will modify the notification builder associated with this Ongoing Activity, so needs
@@ -334,7 +410,7 @@
* @return the Ongoing Activity or null if not found
*/
@Nullable
- public static OngoingActivity fromExistingOngoingActivity(
+ public static OngoingActivity recoverOngoingActivity(
@NonNull Context context,
@NonNull Predicate<OngoingActivityData> filter
) {
@@ -367,8 +443,8 @@
* @return the Ongoing Activity or null if not found
*/
@Nullable
- public static OngoingActivity fromExistingOngoingActivity(@NonNull Context context) {
- return fromExistingOngoingActivity(context, (data) -> true);
+ public static OngoingActivity recoverOngoingActivity(@NonNull Context context) {
+ return recoverOngoingActivity(context, (data) -> true);
}
/**
@@ -382,9 +458,9 @@
* @return the Ongoing Activity or null if not found
*/
@Nullable
- public static OngoingActivity fromExistingOngoingActivity(@NonNull Context context,
+ public static OngoingActivity recoverOngoingActivity(@NonNull Context context,
int ongoingActivityId) {
- return fromExistingOngoingActivity(context,
+ return recoverOngoingActivity(context,
(data) -> data.getOngoingActivityId() == ongoingActivityId);
}
diff --git a/wear/wear-ongoing/src/test/java/androidx/wear/ongoing/OngoingActivityTest.kt b/wear/wear-ongoing/src/test/java/androidx/wear/ongoing/OngoingActivityTest.kt
index e8b9974..4f7f098 100644
--- a/wear/wear-ongoing/src/test/java/androidx/wear/ongoing/OngoingActivityTest.kt
+++ b/wear/wear-ongoing/src/test/java/androidx/wear/ongoing/OngoingActivityTest.kt
@@ -125,12 +125,12 @@
@Test
fun testCreateFromExistingOngoingActivityNull() {
// Nothing to see here.
- assertNull(OngoingActivity.fromExistingOngoingActivity(context))
+ assertNull(OngoingActivity.recoverOngoingActivity(context))
// Same, with a normal notification posted.
val builder = NotificationCompat.Builder(context, ChannelId)
notificationManager.notify(NotificationId, builder.build())
- assertNull(OngoingActivity.fromExistingOngoingActivity(context))
+ assertNull(OngoingActivity.recoverOngoingActivity(context))
// Clean up.
notificationManager.cancel(NotificationId)
@@ -158,7 +158,7 @@
for (i in 1..n) {
val status = "New Status $i"
statuses.add(status)
- OngoingActivity.fromExistingOngoingActivity(context, i)!!
+ OngoingActivity.recoverOngoingActivity(context, i)!!
.update(context, OngoingActivityStatus.forPart(TextStatusPart(status)))
}
assertEquals(n, statuses.size) // Just in case.
@@ -219,7 +219,7 @@
// After posting, send an update.
val newStatus = OngoingActivityStatus.forPart(TimerStatusPart(12345))
- OngoingActivity.fromExistingOngoingActivity(context)!!.update(context, newStatus)
+ OngoingActivity.recoverOngoingActivity(context)!!.update(context, newStatus)
// Get the notification and check that the status, and only the status has been updated.
val notifications = notificationManager.activeNotifications
@@ -341,7 +341,7 @@
// After posting, send an update to the second OA and check the statuses.
val newStatus2 = OngoingActivityStatus.forPart(TextStatusPart("update2"))
- OngoingActivity.fromExistingOngoingActivity(context, 2)?.update(context, newStatus2)
+ OngoingActivity.recoverOngoingActivity(context, 2)?.update(context, newStatus2)
assertEquals("status1, update2", getStatuses())
diff --git a/wear/wear-watchface-client/build.gradle b/wear/wear-watchface-client/build.gradle
index 3c29c46..91ad998 100644
--- a/wear/wear-watchface-client/build.gradle
+++ b/wear/wear-watchface-client/build.gradle
@@ -42,8 +42,8 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(TRUTH)
testImplementation(ANDROIDX_TEST_EXT_JUNIT)
diff --git a/wear/wear-watchface-client/guava/build.gradle b/wear/wear-watchface-client/guava/build.gradle
index 3c0a1a5..a751ec3 100644
--- a/wear/wear-watchface-client/guava/build.gradle
+++ b/wear/wear-watchface-client/guava/build.gradle
@@ -37,8 +37,8 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(TRUTH)
}
diff --git a/wear/wear-watchface-complications-rendering/src/main/java/androidx/wear/watchface/complications/rendering/ComplicationRenderer.java b/wear/wear-watchface-complications-rendering/src/main/java/androidx/wear/watchface/complications/rendering/ComplicationRenderer.java
index 1445266..82dfc2f 100644
--- a/wear/wear-watchface-complications-rendering/src/main/java/androidx/wear/watchface/complications/rendering/ComplicationRenderer.java
+++ b/wear/wear-watchface-complications-rendering/src/main/java/androidx/wear/watchface/complications/rendering/ComplicationRenderer.java
@@ -129,9 +129,9 @@
Drawable mLargeImage;
// Drawables for rendering rounded images
- private final RoundedDrawable mRoundedBackgroundDrawable = new RoundedDrawable();
- private final RoundedDrawable mRoundedLargeImage = new RoundedDrawable();
- private final RoundedDrawable mRoundedSmallImage = new RoundedDrawable();
+ private RoundedDrawable mRoundedBackgroundDrawable = null;
+ private RoundedDrawable mRoundedLargeImage = null;
+ private RoundedDrawable mRoundedSmallImage = null;
// Text renderers
private final TextRenderer mMainTextRenderer = new TextRenderer();
@@ -218,6 +218,10 @@
}
if (data == null) {
mComplicationData = null;
+ // Free unnecessary RoundedDrawables.
+ mRoundedBackgroundDrawable = null;
+ mRoundedLargeImage = null;
+ mRoundedSmallImage = null;
return;
}
if (data.getType() == ComplicationData.TYPE_NO_DATA) {
@@ -244,6 +248,13 @@
loadDrawableIconAndImages();
}
calculateBounds();
+
+ // Based on the results of calculateBounds we know if mRoundedLargeImage or
+ // mSmallImageBounds are needed for rendering and can null the references if not required.
+ // NOTE mRoundedBackgroundDrawable has a different lifecycle which is based on the current
+ // paint mode so it doesn't make sense to clear it's reference here.
+ mRoundedLargeImage = null;
+ mRoundedSmallImage = null;
}
/**
@@ -322,10 +333,8 @@
if (mComplicationData == null
|| mComplicationData.getType() == ComplicationData.TYPE_EMPTY
|| mComplicationData.getType() == ComplicationData.TYPE_NOT_CONFIGURED
- || !mComplicationData.isActiveAt(currentTimeMillis)) {
- return;
- }
- if (mBounds.isEmpty()) {
+ || !mComplicationData.isActiveAt(currentTimeMillis)
+ || mBounds.isEmpty()) {
return;
}
// If in ambient mode but paint set is not usable with current ambient properties,
@@ -406,10 +415,15 @@
canvas.drawRoundRect(mBackgroundBoundsF, radius, radius, paintSet.mBackgroundPaint);
if (paintSet.mStyle.getBackgroundDrawable() != null
&& !paintSet.isInBurnInProtectionMode()) {
+ if (mRoundedBackgroundDrawable == null) {
+ mRoundedBackgroundDrawable = new RoundedDrawable();
+ }
mRoundedBackgroundDrawable.setDrawable(paintSet.mStyle.getBackgroundDrawable());
mRoundedBackgroundDrawable.setRadius(radius);
mRoundedBackgroundDrawable.setBounds(mBackgroundBounds);
mRoundedBackgroundDrawable.draw(canvas);
+ } else {
+ mRoundedBackgroundDrawable = null;
}
}
@@ -520,6 +534,9 @@
if (DEBUG_MODE) {
canvas.drawRect(mSmallImageBounds, mDebugPaint);
}
+ if (mRoundedSmallImage == null) {
+ mRoundedSmallImage = new RoundedDrawable();
+ }
if (!paintSet.isInBurnInProtectionMode()) {
mRoundedSmallImage.setDrawable(mSmallImage);
if (mSmallImage == null) {
@@ -552,6 +569,9 @@
}
// Draw the image if not in burn in protection mode (in active mode or burn in not enabled)
if (!paintSet.isInBurnInProtectionMode()) {
+ if (mRoundedLargeImage == null) {
+ mRoundedLargeImage = new RoundedDrawable();
+ }
mRoundedLargeImage.setDrawable(mLargeImage);
// Large image is always treated as photo style
mRoundedLargeImage.setRadius(getImageBorderRadius(paintSet.mStyle, mLargeImageBounds));
diff --git a/wear/wear-watchface-editor/build.gradle b/wear/wear-watchface-editor/build.gradle
index 8c4d011..f226b93 100644
--- a/wear/wear-watchface-editor/build.gradle
+++ b/wear/wear-watchface-editor/build.gradle
@@ -43,8 +43,8 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(KOTLIN_COROUTINES_TEST)
androidTestImplementation(TRUTH)
}
diff --git a/wear/wear-watchface-editor/guava/build.gradle b/wear/wear-watchface-editor/guava/build.gradle
index 5d7afd9..a11ce0d 100644
--- a/wear/wear-watchface-editor/guava/build.gradle
+++ b/wear/wear-watchface-editor/guava/build.gradle
@@ -36,8 +36,8 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(TRUTH)
}
diff --git a/wear/wear-watchface-style/src/main/java/androidx/wear/watchface/style/CurrentUserStyleRepository.kt b/wear/wear-watchface-style/src/main/java/androidx/wear/watchface/style/CurrentUserStyleRepository.kt
index 8654b4d..80387b8 100644
--- a/wear/wear-watchface-style/src/main/java/androidx/wear/watchface/style/CurrentUserStyleRepository.kt
+++ b/wear/wear-watchface-style/src/main/java/androidx/wear/watchface/style/CurrentUserStyleRepository.kt
@@ -142,26 +142,39 @@
* Describes the list of [UserStyleSetting]s the user can configure.
*
* @param userStyleSettings The user configurable style categories associated with this watch face.
- * Empty if the watch face doesn't support user styling.
+ * Empty if the watch face doesn't support user styling. Note we allow at most one
+ * [UserStyleSetting.ComplicationsUserStyleSetting] and one
+ * [UserStyleSetting.CustomValueUserStyleSetting]
+ * in the list.
*/
public class UserStyleSchema(
public val userStyleSettings: List<UserStyleSetting>
) {
init {
+ var complicationsUserStyleSettingCount = 0
var customValueUserStyleSettingCount = 0
for (setting in userStyleSettings) {
- if (setting is UserStyleSetting.CustomValueUserStyleSetting) {
- customValueUserStyleSettingCount++
+ when (setting) {
+ is UserStyleSetting.ComplicationsUserStyleSetting ->
+ complicationsUserStyleSettingCount++
+
+ is UserStyleSetting.CustomValueUserStyleSetting ->
+ customValueUserStyleSettingCount++
}
}
+ // This requirement makes it easier to implement companion editors.
+ require(complicationsUserStyleSettingCount <= 1) {
+ "At most only one ComplicationsUserStyleSetting is allowed"
+ }
+
// There's a hard limit to how big Schema + UserStyle can be and since this data is sent
// over bluetooth to the companion there will be performance issues well before we hit
// that the limit. As a result we want the total size of custom data to be kept small and
// we are initially restricting there to be at most one CustomValueUserStyleSetting.
- require(
- customValueUserStyleSettingCount <= 1
- ) { "At most only one CustomValueUserStyleSetting is allowed" }
+ require(customValueUserStyleSettingCount <= 1) {
+ "At most only one CustomValueUserStyleSetting is allowed"
+ }
}
/** @hide */
diff --git a/wear/wear-watchface-style/src/main/java/androidx/wear/watchface/style/UserStyleSetting.kt b/wear/wear-watchface-style/src/main/java/androidx/wear/watchface/style/UserStyleSetting.kt
index 789ddc8..55a881d 100644
--- a/wear/wear-watchface-style/src/main/java/androidx/wear/watchface/style/UserStyleSetting.kt
+++ b/wear/wear-watchface-style/src/main/java/androidx/wear/watchface/style/UserStyleSetting.kt
@@ -358,7 +358,8 @@
* The ComplicationsManager listens for style changes with this setting and when a
* [ComplicationsOption] is selected the overrides are automatically applied. Note its suggested
* that the default [ComplicationOverlay] (the first entry in the list) does not apply any
- * overrides.
+ * overrides. Only a single [ComplicationsUserStyleSetting] is permitted in the
+ * [UserStyleSchema].
*
* Not to be confused with complication provider selection.
*/
@@ -942,7 +943,8 @@
/**
* An application specific style setting. This style is ignored by the system editor. This is
- * expected to be used in conjunction with an on watch face editor.
+ * expected to be used in conjunction with an on watch face editor. Only a single
+ * [ComplicationsUserStyleSetting] is permitted in the [UserStyleSchema].
*/
public class CustomValueUserStyleSetting : UserStyleSetting {
internal companion object {
diff --git a/wear/wear-watchface-style/src/test/java/androidx/wear/watchface/style/CurrentUserStyleRepositoryTest.kt b/wear/wear-watchface-style/src/test/java/androidx/wear/watchface/style/CurrentUserStyleRepositoryTest.kt
index 3504aa6..359caeb 100644
--- a/wear/wear-watchface-style/src/test/java/androidx/wear/watchface/style/CurrentUserStyleRepositoryTest.kt
+++ b/wear/wear-watchface-style/src/test/java/androidx/wear/watchface/style/CurrentUserStyleRepositoryTest.kt
@@ -264,12 +264,35 @@
userStyleRepository.schema
)
- val customValue = userStyle.selectedOptions[customStyleSetting]!! as
- UserStyleSetting.CustomValueUserStyleSetting.CustomValueOption
+ val customValue = userStyle.selectedOptions[customStyleSetting]!! as CustomValueOption
assertThat(customValue.customValue.decodeToString()).isEqualTo("TEST 123")
}
@Test
+ public fun userStyle_multiple_ComplicationsUserStyleSetting_notAllowed() {
+ val customStyleSetting1 = CustomValueUserStyleSetting(
+ listOf(WatchFaceLayer.BASE),
+ "default".encodeToByteArray()
+ )
+ val customStyleSetting2 = CustomValueUserStyleSetting(
+ listOf(WatchFaceLayer.BASE),
+ "default".encodeToByteArray()
+ )
+
+ try {
+ UserStyleSchema(
+ listOf(customStyleSetting1, customStyleSetting2)
+ )
+ fail(
+ "Constructing a UserStyleSchema with more than one ComplicationsUserStyleSetting " +
+ "should fail"
+ )
+ } catch (e: Exception) {
+ // expected
+ }
+ }
+
+ @Test
public fun userStyle_multiple_CustomValueUserStyleSettings_notAllowed() {
val customStyleSetting1 = CustomValueUserStyleSetting(
listOf(WatchFaceLayer.BASE),
@@ -308,8 +331,7 @@
userStyleRepository.userStyle = UserStyle(
mapOf(
- customStyleSetting to
- CustomValueUserStyleSetting.CustomValueOption("test".encodeToByteArray())
+ customStyleSetting to CustomValueOption("test".encodeToByteArray())
)
)
@@ -370,9 +392,6 @@
.isEqualTo("12.3")
assertThat(LongRangeUserStyleSetting.LongRangeOption(123).toString())
.isEqualTo("123")
- assertThat(
- CustomValueUserStyleSetting.CustomValueOption("test".encodeToByteArray())
- .toString()
- ).isEqualTo("test")
+ assertThat(CustomValueOption("test".encodeToByteArray()).toString()).isEqualTo("test")
}
}
diff --git a/wear/wear-watchface/build.gradle b/wear/wear-watchface/build.gradle
index 0582637..340abf2 100644
--- a/wear/wear-watchface/build.gradle
+++ b/wear/wear-watchface/build.gradle
@@ -43,8 +43,8 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(TRUTH)
testImplementation(project(":wear:wear-watchface-complications-rendering"))
diff --git a/wear/wear-watchface/guava/build.gradle b/wear/wear-watchface/guava/build.gradle
index a70be6e..28f0610 100644
--- a/wear/wear-watchface/guava/build.gradle
+++ b/wear/wear-watchface/guava/build.gradle
@@ -34,14 +34,14 @@
androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(TRUTH)
testImplementation(ANDROIDX_TEST_CORE)
testImplementation(ANDROIDX_TEST_RUNNER)
testImplementation(ANDROIDX_TEST_RULES)
- testImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- testImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ testImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ testImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
testImplementation(ROBOLECTRIC)
testImplementation(TRUTH)
}
diff --git a/wear/wear/build.gradle b/wear/wear/build.gradle
index a1aa6ae..80eb984 100644
--- a/wear/wear/build.gradle
+++ b/wear/wear/build.gradle
@@ -23,9 +23,9 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
testImplementation(KOTLIN_STDLIB)
testImplementation(ANDROIDX_TEST_CORE)
diff --git a/webkit/integration-tests/testapp/build.gradle b/webkit/integration-tests/testapp/build.gradle
index fe4acbc..4caa18a 100644
--- a/webkit/integration-tests/testapp/build.gradle
+++ b/webkit/integration-tests/testapp/build.gradle
@@ -32,13 +32,13 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
- androidTestImplementation(ESPRESSO_CONTRIB, libs.exclude_for_espresso)
+ androidTestImplementation(ESPRESSO_CORE, excludes.espresso)
+ androidTestImplementation(ESPRESSO_CONTRIB, excludes.espresso)
androidTestImplementation(ESPRESSO_IDLING_RESOURCE)
- androidTestImplementation(ESPRESSO_WEB, libs.exclude_for_espresso)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy)
+ androidTestImplementation(ESPRESSO_WEB, excludes.espresso)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
// DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
}
rootProject.tasks.getByName("buildOnServer").dependsOn(project.path + ":assembleRelease")
diff --git a/webkit/webkit/build.gradle b/webkit/webkit/build.gradle
index a640c8d..a52b165 100644
--- a/webkit/webkit/build.gradle
+++ b/webkit/webkit/build.gradle
@@ -36,7 +36,7 @@
androidTestImplementation("androidx.concurrent:concurrent-futures:1.0.0")
// Hamcrest matchers:
- androidTestImplementation(ESPRESSO_CONTRIB, libs.exclude_for_espresso)
+ androidTestImplementation(ESPRESSO_CONTRIB, excludes.espresso)
}
ext {
diff --git a/window/window-extensions/build.gradle b/window/window-extensions/build.gradle
index 384720b..5ee89bc 100644
--- a/window/window-extensions/build.gradle
+++ b/window/window-extensions/build.gradle
@@ -37,8 +37,8 @@
androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
}
androidx {
diff --git a/window/window/build.gradle b/window/window/build.gradle
index a1d0366..6329f99 100644
--- a/window/window/build.gradle
+++ b/window/window/build.gradle
@@ -74,9 +74,9 @@
androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy)
- androidTestImplementation(MOCKITO_KOTLIN, libs.exclude_bytebuddy)
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
+ androidTestImplementation(MOCKITO_KOTLIN, excludes.bytebuddy)
androidTestImplementation(TRUTH)
androidTestImplementation(compileOnly(project(":window:window-extensions")))
androidTestImplementation(compileOnly(project(":window:window-sidecar")))
diff --git a/work/workmanager-gcm/build.gradle b/work/workmanager-gcm/build.gradle
index b87f85f..004c634 100644
--- a/work/workmanager-gcm/build.gradle
+++ b/work/workmanager-gcm/build.gradle
@@ -48,8 +48,8 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ESPRESSO_CORE)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has its own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has its own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has its own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has its own MockMaker
testImplementation(JUNIT)
}
diff --git a/work/workmanager-ktx/build.gradle b/work/workmanager-ktx/build.gradle
index fa3953a..e323c94 100644
--- a/work/workmanager-ktx/build.gradle
+++ b/work/workmanager-ktx/build.gradle
@@ -39,8 +39,8 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ESPRESSO_CORE)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has its own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has its own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has its own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has its own MockMaker
androidTestImplementation("androidx.room:room-testing:2.2.5")
testImplementation(JUNIT)
}
diff --git a/work/workmanager-multiprocess/build.gradle b/work/workmanager-multiprocess/build.gradle
index 76bcadb..596d4cb 100644
--- a/work/workmanager-multiprocess/build.gradle
+++ b/work/workmanager-multiprocess/build.gradle
@@ -50,8 +50,8 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ESPRESSO_CORE)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has its own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has its own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has its own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has its own MockMaker
androidTestImplementation(project(":internal-testutils-runtime"))
testImplementation(KOTLIN_STDLIB)
testImplementation(JUNIT)
diff --git a/work/workmanager-testing/build.gradle b/work/workmanager-testing/build.gradle
index 7018887..745ad5a 100644
--- a/work/workmanager-testing/build.gradle
+++ b/work/workmanager-testing/build.gradle
@@ -38,8 +38,8 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ESPRESSO_CORE)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has it"s own MockMaker
testImplementation(ANDROIDX_TEST_CORE)
testImplementation(JUNIT)
diff --git a/work/workmanager/build.gradle b/work/workmanager/build.gradle
index 2ba9ca2..c97b230 100644
--- a/work/workmanager/build.gradle
+++ b/work/workmanager/build.gradle
@@ -75,8 +75,8 @@
androidTestImplementation(projectOrArtifact(":lifecycle:lifecycle-runtime-testing"))
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ESPRESSO_CORE)
- androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has its own MockMaker
- androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has its own MockMaker
+ androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy) // DexMaker has its own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy) // DexMaker has its own MockMaker
androidTestImplementation(project(":internal-testutils-runtime"))
testImplementation(JUNIT)
lintPublish(project(":work:work-runtime-lint"))