Merge "Introduce start offset to repeatable" into androidx-main
diff --git a/benchmark/benchmark-macro/api/current.txt b/benchmark/benchmark-macro/api/current.txt
index 1bed5d9..8519b25 100644
--- a/benchmark/benchmark-macro/api/current.txt
+++ b/benchmark/benchmark-macro/api/current.txt
@@ -4,7 +4,7 @@
@RequiresApi(29) public final class Api29Kt {
}
- public abstract sealed class CompilationMode {
+ @RequiresApi(21) public abstract sealed class CompilationMode {
}
public static final class CompilationMode.BaselineProfile extends androidx.benchmark.macro.CompilationMode {
@@ -31,7 +31,7 @@
public final class ConfigurationErrorKt {
}
- public final class FrameTimingMetric extends androidx.benchmark.macro.Metric {
+ @RequiresApi(21) public final class FrameTimingMetric extends androidx.benchmark.macro.Metric {
ctor public FrameTimingMetric();
}
@@ -41,7 +41,7 @@
public final class MacrobenchmarkKt {
}
- public final class MacrobenchmarkScope {
+ @RequiresApi(21) public final class MacrobenchmarkScope {
ctor public MacrobenchmarkScope(String packageName, boolean launchWithClearTask);
method public void dropKernelPageCache();
method public void killProcess();
@@ -50,7 +50,7 @@
method public void startActivityAndWait(android.content.Intent intent);
}
- public abstract sealed class Metric {
+ @RequiresApi(21) public abstract sealed class Metric {
}
public final class MetricKt {
diff --git a/benchmark/benchmark-macro/api/public_plus_experimental_current.txt b/benchmark/benchmark-macro/api/public_plus_experimental_current.txt
index 1bed5d9..8519b25 100644
--- a/benchmark/benchmark-macro/api/public_plus_experimental_current.txt
+++ b/benchmark/benchmark-macro/api/public_plus_experimental_current.txt
@@ -4,7 +4,7 @@
@RequiresApi(29) public final class Api29Kt {
}
- public abstract sealed class CompilationMode {
+ @RequiresApi(21) public abstract sealed class CompilationMode {
}
public static final class CompilationMode.BaselineProfile extends androidx.benchmark.macro.CompilationMode {
@@ -31,7 +31,7 @@
public final class ConfigurationErrorKt {
}
- public final class FrameTimingMetric extends androidx.benchmark.macro.Metric {
+ @RequiresApi(21) public final class FrameTimingMetric extends androidx.benchmark.macro.Metric {
ctor public FrameTimingMetric();
}
@@ -41,7 +41,7 @@
public final class MacrobenchmarkKt {
}
- public final class MacrobenchmarkScope {
+ @RequiresApi(21) public final class MacrobenchmarkScope {
ctor public MacrobenchmarkScope(String packageName, boolean launchWithClearTask);
method public void dropKernelPageCache();
method public void killProcess();
@@ -50,7 +50,7 @@
method public void startActivityAndWait(android.content.Intent intent);
}
- public abstract sealed class Metric {
+ @RequiresApi(21) public abstract sealed class Metric {
}
public final class MetricKt {
diff --git a/benchmark/benchmark-macro/api/restricted_current.txt b/benchmark/benchmark-macro/api/restricted_current.txt
index 3568b81..25284a55 100644
--- a/benchmark/benchmark-macro/api/restricted_current.txt
+++ b/benchmark/benchmark-macro/api/restricted_current.txt
@@ -4,7 +4,7 @@
@RequiresApi(29) public final class Api29Kt {
}
- public abstract sealed class CompilationMode {
+ @RequiresApi(21) public abstract sealed class CompilationMode {
}
public static final class CompilationMode.BaselineProfile extends androidx.benchmark.macro.CompilationMode {
@@ -35,7 +35,7 @@
public final class ConfigurationErrorKt {
}
- public final class FrameTimingMetric extends androidx.benchmark.macro.Metric {
+ @RequiresApi(21) public final class FrameTimingMetric extends androidx.benchmark.macro.Metric {
ctor public FrameTimingMetric();
}
@@ -45,7 +45,7 @@
public final class MacrobenchmarkKt {
}
- public final class MacrobenchmarkScope {
+ @RequiresApi(21) public final class MacrobenchmarkScope {
ctor public MacrobenchmarkScope(String packageName, boolean launchWithClearTask);
method public void dropKernelPageCache();
method public void killProcess();
@@ -54,7 +54,7 @@
method public void startActivityAndWait(android.content.Intent intent);
}
- public abstract sealed class Metric {
+ @RequiresApi(21) public abstract sealed class Metric {
}
public final class MetricKt {
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/CompilationModeTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/CompilationModeTest.kt
index 84d0a07..6ceeb1c 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/CompilationModeTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/CompilationModeTest.kt
@@ -17,6 +17,7 @@
package androidx.benchmark.macro
import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.assertEquals
@@ -29,6 +30,7 @@
@RunWith(AndroidJUnit4::class)
@SmallTest
+@SdkSuppress(minSdkVersion = 21)
public class CompilationModeTest {
private val vmRunningInterpretedOnly: Boolean
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/MacrobenchmarkTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/MacrobenchmarkTest.kt
index 8efef1c..114cafd 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/MacrobenchmarkTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/MacrobenchmarkTest.kt
@@ -25,6 +25,7 @@
import kotlin.test.assertTrue
@RunWith(AndroidJUnit4::class)
+@SdkSuppress(minSdkVersion = 21)
@SmallTest
class MacrobenchmarkTest {
@Test
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/OutputsTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/OutputsTest.kt
index 1a72cd3..a56635d7 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/OutputsTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/OutputsTest.kt
@@ -18,6 +18,7 @@
import androidx.benchmark.Outputs
import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
@@ -46,6 +47,7 @@
}
@Test
+ @SdkSuppress(minSdkVersion = 21) // executeShellCommand
public fun dirUsableByAppAndShell_writeAppReadShell() {
val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
val dir = Outputs.dirUsableByAppAndShell
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoConfigTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoConfigTest.kt
index 7f7da87..365cf76 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoConfigTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoConfigTest.kt
@@ -53,12 +53,14 @@
assertFalse(ftraceConfig.atrace_categories.contains("memory"))
}
+ @SdkSuppress(minSdkVersion = 21)
@Test
fun validateAndEncode() {
// default config shouldn't throw
perfettoConfig(listOf(Packages.TEST)).validateAndEncode()
}
+ @SdkSuppress(minSdkVersion = 21)
@Test
fun validateAndEncode_invalidAtraceCategories() {
val invalidConfig = TraceConfig(
@@ -86,7 +88,7 @@
assertTrue(exception.message!!.contains("bad_category"))
}
- @SdkSuppress(maxSdkVersion = 27)
+ @SdkSuppress(minSdkVersion = 21, maxSdkVersion = 27)
@Test
fun validateAndEncode_invalidWildcard() {
val invalidConfig = TraceConfig(
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoTraceProcessorTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoTraceProcessorTest.kt
index 3726a28..9ae4f55 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoTraceProcessorTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoTraceProcessorTest.kt
@@ -19,6 +19,7 @@
import androidx.benchmark.macro.device
import androidx.benchmark.macro.perfetto.PerfettoHelper.Companion.isAbiSupported
import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.assertTrue
@@ -30,6 +31,7 @@
import kotlin.test.assertFailsWith
@SmallTest
+@SdkSuppress(minSdkVersion = 21)
@RunWith(AndroidJUnit4::class)
class PerfettoTraceProcessorTest {
@Test
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/ShellUtilsTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/ShellUtilsTest.kt
index 229ae61..3a53e7e 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/ShellUtilsTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/ShellUtilsTest.kt
@@ -29,6 +29,7 @@
import kotlin.test.assertNotNull
@MediumTest
+@SdkSuppress(minSdkVersion = 21)
@RunWith(AndroidJUnit4::class)
class ShellUtilsTest {
private val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
diff --git a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/CompilationMode.kt b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/CompilationMode.kt
index 72a6658..c0c2b63 100644
--- a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/CompilationMode.kt
+++ b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/CompilationMode.kt
@@ -18,6 +18,7 @@
import android.app.Instrumentation
import android.util.Log
+import androidx.annotation.RequiresApi
import androidx.annotation.RestrictTo
import androidx.benchmark.macro.CompilationMode.SpeedProfile
import androidx.profileinstaller.ProfileInstallReceiver
@@ -32,6 +33,7 @@
* For example, [SpeedProfile] will run a configurable number of profiling iterations to generate
* a profile, and use that to compile the target app.
*/
+@RequiresApi(21)
public sealed class CompilationMode(
// for modes other than [None], is argument passed `cmd package compile`
private val compileArgument: String?
@@ -95,6 +97,7 @@
*
* For more information: https://source.android.com/devices/tech/dalvik/jit-compiler
*/
+@RequiresApi(21)
internal fun CompilationMode.compile(packageName: String, block: () -> Unit) {
val instrumentation = InstrumentationRegistry.getInstrumentation()
val device = instrumentation.device()
@@ -219,6 +222,7 @@
/**
* Compiles the application.
*/
+@RequiresApi(21)
internal fun CompilationMode.compilePackage(instrumentation: Instrumentation, packageName: String) {
val device = instrumentation.device()
Log.d(TAG, "Compiling $packageName ($this)")
diff --git a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/Macrobenchmark.kt b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/Macrobenchmark.kt
index 56d76cb..b4fd16c 100644
--- a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/Macrobenchmark.kt
+++ b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/Macrobenchmark.kt
@@ -20,6 +20,7 @@
import android.content.pm.PackageManager
import android.os.Build
import android.util.Log
+import androidx.annotation.RequiresApi
import androidx.annotation.RestrictTo
import androidx.benchmark.Arguments
import androidx.benchmark.BenchmarkResult
@@ -92,6 +93,7 @@
*
* This function is a building block for public testing APIs
*/
+@RequiresApi(21)
private fun macrobenchmark(
uniqueName: String,
className: String,
@@ -247,6 +249,7 @@
*
* @suppress
*/
+@RequiresApi(21)
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public fun macrobenchmarkWithStartupMode(
uniqueName: String,
diff --git a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/MacrobenchmarkScope.kt b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/MacrobenchmarkScope.kt
index 192490e..219c5aa 100644
--- a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/MacrobenchmarkScope.kt
+++ b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/MacrobenchmarkScope.kt
@@ -18,6 +18,7 @@
import android.content.Intent
import android.util.Log
+import androidx.annotation.RequiresApi
import androidx.benchmark.macro.perfetto.executeShellScript
import androidx.benchmark.macro.perfetto.executeShellScriptWithStderr
import androidx.test.platform.app.InstrumentationRegistry
@@ -28,6 +29,7 @@
* Provides access to common operations in app automation, such as killing the app,
* or navigating home.
*/
+@RequiresApi(21)
public class MacrobenchmarkScope(
private val packageName: String,
/**
diff --git a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/Metric.kt b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/Metric.kt
index f40148e..3f56922 100644
--- a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/Metric.kt
+++ b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/Metric.kt
@@ -26,6 +26,7 @@
/**
* Metric interface.
*/
+@RequiresApi(21)
public sealed class Metric {
internal abstract fun configure(packageName: String)
@@ -41,6 +42,7 @@
internal abstract fun getMetrics(packageName: String, tracePath: String): MetricsWithUiState
}
+@RequiresApi(21)
public class FrameTimingMetric : Metric() {
private lateinit var packageName: String
private val helper = JankCollectionHelper()
diff --git a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/perfetto/PerfettoConfig.kt b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/perfetto/PerfettoConfig.kt
index c28a518..fd3fb62 100644
--- a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/perfetto/PerfettoConfig.kt
+++ b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/perfetto/PerfettoConfig.kt
@@ -17,6 +17,7 @@
package androidx.benchmark.macro.perfetto
import android.os.Build
+import androidx.annotation.RequiresApi
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import perfetto.protos.DataSourceConfig
@@ -150,6 +151,7 @@
),
)
+@RequiresApi(21) // needed for shell access
internal fun TraceConfig.validateAndEncode(): ByteArray {
val ftraceConfig = data_sources
.mapNotNull { it.config?.ftrace_config }
diff --git a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/perfetto/PerfettoTraceProcessor.kt b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/perfetto/PerfettoTraceProcessor.kt
index 271192d..d7a5ff0 100644
--- a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/perfetto/PerfettoTraceProcessor.kt
+++ b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/perfetto/PerfettoTraceProcessor.kt
@@ -17,6 +17,7 @@
package androidx.benchmark.macro.perfetto
import android.util.Log
+import androidx.annotation.RequiresApi
import androidx.benchmark.Outputs
import androidx.benchmark.macro.device
import androidx.benchmark.macro.userspaceTrace
@@ -27,6 +28,7 @@
/**
* Enables parsing perfetto traces on-device
*/
+@RequiresApi(21)
internal object PerfettoTraceProcessor {
private const val TAG = "PerfettoTraceProcessor"
diff --git a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/perfetto/ShellUtils.kt b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/perfetto/ShellUtils.kt
index a3125d2..3bc6c68 100644
--- a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/perfetto/ShellUtils.kt
+++ b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/perfetto/ShellUtils.kt
@@ -17,6 +17,7 @@
package androidx.benchmark.macro.perfetto
import android.os.Build
+import androidx.annotation.RequiresApi
import androidx.benchmark.Outputs
import androidx.test.uiautomator.UiDevice
import java.io.File
@@ -24,6 +25,7 @@
internal data class ShellOutput(val stdout: String, val stderr: String)
+@RequiresApi(21)
private fun UiDevice.chmodExecutable(absoluteFilePath: String) {
if (Build.VERSION.SDK_INT >= 23) {
executeShellCommand("chmod +x $absoluteFilePath")
@@ -43,6 +45,7 @@
* stdin/stderr is required, so that all stderr can be captured (instead of redirecting the
* last command), and stdin can be read by other commands in the script (instead of just the 1st).
*/
+@RequiresApi(21)
private fun UiDevice.executeShellScript(
script: String,
stdin: String?,
@@ -113,6 +116,7 @@
*
* @return ShellOutput, including stdout of full script, and stderr of last command.
*/
+@RequiresApi(21)
internal fun UiDevice.executeShellScriptWithStderr(
script: String,
stdin: String? = null
@@ -142,6 +146,7 @@
*
* @return Stdout string
*/
+@RequiresApi(21)
internal fun UiDevice.executeShellScript(script: String, stdin: String? = null): String {
return executeShellScript(script, stdin, false).first
}
@@ -149,6 +154,7 @@
/**
* Writes the inputStream to an executable file with the given name in `/data/local/tmp`
*/
+@RequiresApi(21)
internal fun UiDevice.createRunnableExecutable(name: String, inputStream: InputStream): String {
// dirUsableByAppAndShell is writable, but we can't execute there (as of Q),
// so we copy to /data/local/tmp
@@ -179,10 +185,12 @@
* Returns true if the shell session is rooted, and thus root commands can be run (e.g. atrace
* commands with root-only tags)
*/
+@RequiresApi(21)
internal fun UiDevice.isShellSessionRooted(): Boolean {
return executeShellCommand("getprop service.adb.root").trim() == "1"
}
+@RequiresApi(21)
private fun UiDevice.moveToTmpAndMakeExecutable(src: String, dst: String) {
// Note: we don't check for return values from the below, since shell based file
// permission errors generally crash our process.
@@ -190,6 +198,7 @@
chmodExecutable(dst)
}
+@RequiresApi(21)
internal fun UiDevice.isPackageAlive(packageName: String): Boolean {
if (Build.VERSION.SDK_INT >= 24) {
// On API 23 (first version to offer it) we observe that 'pidof'
diff --git a/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt b/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt
index 57c36fb..a065882 100644
--- a/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt
@@ -221,6 +221,10 @@
project.tasks.withType(KotlinCompile::class.java).configureEach { task ->
task.kotlinOptions.jvmTarget = "1.8"
project.configureJavaCompilationWarnings(task)
+
+ // Not directly impacting us, but a bunch of issues like KT-46512, probably prudent
+ // for us to just disable until Kotlin 1.5.10+ to avoid end users hitting users
+ task.kotlinOptions.freeCompilerArgs += listOf("-Xsam-conversions=class")
}
project.afterEvaluate {
val isAndroidProject = project.plugins.hasPlugin(LibraryPlugin::class.java) ||
diff --git a/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt b/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
index dd6364c..17becd1 100644
--- a/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
@@ -111,7 +111,7 @@
val SLICE_BENCHMARK = Version("1.1.0-alpha02")
val SLICE_BUILDERS_KTX = Version("1.0.0-alpha08")
val SLICE_REMOTECALLBACK = Version("1.0.0-alpha01")
- val SLIDINGPANELAYOUT = Version("1.2.0-alpha03")
+ val SLIDINGPANELAYOUT = Version("1.2.0-alpha04")
val STARTUP = Version("1.2.0-alpha01")
val SQLITE = Version("2.2.0-alpha03")
val SQLITE_INSPECTOR = Version("2.1.0-alpha01")
diff --git a/buildSrc/src/main/kotlin/androidx/build/docs/AndroidXDocsPlugin.kt b/buildSrc/src/main/kotlin/androidx/build/docs/AndroidXDocsPlugin.kt
index ede9cd3..8373004 100644
--- a/buildSrc/src/main/kotlin/androidx/build/docs/AndroidXDocsPlugin.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/docs/AndroidXDocsPlugin.kt
@@ -614,6 +614,10 @@
private val hiddenPackagesJava = setOf(
"androidx.compose.animation",
"androidx.compose.animation.core",
+ "androidx.compose.animation.graphics",
+ "androidx.compose.animation.graphics.res",
+ "androidx.compose.animation.graphics.vector",
+ "androidx.compose.animation.graphics.vector.compat",
"androidx.compose.foundation",
"androidx.compose.foundation.gestures",
"androidx.compose.foundation.interaction",
@@ -679,4 +683,11 @@
"androidx.compose.ui.util",
"androidx.compose.ui.viewinterop",
"androidx.compose.ui.window",
+ "androidx.activity.compose",
+ "androidx.hilt.navigation.compose",
+ "androidx.navigation.compose",
+ "androidx.paging.compose",
+ "androidx.wear.compose",
+ "androidx.wear.compose.foundation",
+ "androidx.wear.compose.material",
)
diff --git a/busytown/androidx-studio-integration.sh b/busytown/androidx-studio-integration.sh
index 1e5c319..5ba70ad 100755
--- a/busytown/androidx-studio-integration.sh
+++ b/busytown/androidx-studio-integration.sh
@@ -1,5 +1,4 @@
set -e
SCRIPT_PATH="$(cd $(dirname $0) && pwd)"
-# runErrorProne is disabled due to I77d9800990e2a46648f7ed2713c54398cd798a0d in AGP
-$SCRIPT_PATH/impl/build-studio-and-androidx.sh -Pandroidx.summarizeStderr --no-daemon -Pandroidx.allWarningsAsErrors listTaskOutputs bOS -Pandroidx.verifyUpToDate -x verifyDependencyVersions -x runErrorProne --stacktrace
+$SCRIPT_PATH/impl/build-studio-and-androidx.sh -Pandroidx.summarizeStderr --no-daemon -Pandroidx.allWarningsAsErrors listTaskOutputs bOS -Pandroidx.verifyUpToDate -x verifyDependencyVersions --stacktrace
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java
index b231ccb..3e74c77 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java
@@ -178,6 +178,15 @@
+ "are missed in the vendor library. " + e);
completer.set(getOrCreateExtensionsManager(
ExtensionsAvailability.LIBRARY_UNAVAILABLE_MISSING_IMPLEMENTATION));
+ } catch (RuntimeException e) {
+ // Catches all unexpected runtime exceptions and still returns an
+ // ExtensionsManager instance which performs default behavior.
+ Logger.e(TAG,
+ "Failed to initialize extensions. Something wents wrong when "
+ + "initializing the vendor library. "
+ + e);
+ completer.set(getOrCreateExtensionsManager(
+ ExtensionsAvailability.LIBRARY_UNAVAILABLE_ERROR_LOADING));
}
return "Initialize extensions";
diff --git a/car/app/app-samples/places/common/src/main/java/androidx/car/app/sample/places/common/PlacesCarAppService.java b/car/app/app-samples/places/common/src/main/java/androidx/car/app/sample/places/common/PlacesCarAppService.java
index 0d31407..044338a 100644
--- a/car/app/app-samples/places/common/src/main/java/androidx/car/app/sample/places/common/PlacesCarAppService.java
+++ b/car/app/app-samples/places/common/src/main/java/androidx/car/app/sample/places/common/PlacesCarAppService.java
@@ -16,12 +16,15 @@
package androidx.car.app.sample.places.common;
+import android.Manifest;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import androidx.annotation.NonNull;
import androidx.car.app.CarAppService;
import androidx.car.app.Screen;
+import androidx.car.app.ScreenManager;
import androidx.car.app.Session;
import androidx.car.app.validation.HostValidator;
@@ -40,7 +43,16 @@
@Override
@NonNull
public Screen onCreateScreen(@NonNull Intent intent) {
- return PlaceCategoryListScreen.create(getCarContext());
+ if (getCarContext().checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
+ == PackageManager.PERMISSION_GRANTED) {
+ return PlaceCategoryListScreen.create(getCarContext());
+ }
+
+ // If we do not have the location permission, show the request permission screen.
+ ScreenManager screenManager = getCarContext().getCarService(ScreenManager.class);
+ screenManager
+ .push(PlaceCategoryListScreen.create(getCarContext()));
+ return new RequestPermissionScreen(getCarContext(), () -> screenManager.pop());
}
};
}
diff --git a/car/app/app-samples/places/common/src/main/java/androidx/car/app/sample/places/common/RequestPermissionScreen.java b/car/app/app-samples/places/common/src/main/java/androidx/car/app/sample/places/common/RequestPermissionScreen.java
new file mode 100644
index 0000000..1a96701
--- /dev/null
+++ b/car/app/app-samples/places/common/src/main/java/androidx/car/app/sample/places/common/RequestPermissionScreen.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 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.car.app.sample.places.common;
+
+import static android.Manifest.permission.ACCESS_FINE_LOCATION;
+
+import androidx.annotation.NonNull;
+import androidx.car.app.CarContext;
+import androidx.car.app.CarToast;
+import androidx.car.app.Screen;
+import androidx.car.app.model.Action;
+import androidx.car.app.model.CarColor;
+import androidx.car.app.model.MessageTemplate;
+import androidx.car.app.model.OnClickListener;
+import androidx.car.app.model.ParkedOnlyOnClickListener;
+import androidx.car.app.model.Template;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Screen for asking the user to grant location permission. */
+public class RequestPermissionScreen extends Screen {
+
+ /** Callback called when the location permission is granted. */
+ public interface LocationPermissionCheckCallback {
+ /** Callback called when the location permission is granted. */
+ void onPermissionGranted();
+ }
+
+ LocationPermissionCheckCallback mLocationPermissionCheckCallback;
+
+ public RequestPermissionScreen(
+ @NonNull CarContext carContext, @NonNull LocationPermissionCheckCallback callback) {
+ super(carContext);
+ mLocationPermissionCheckCallback = callback;
+ }
+
+ @NonNull
+ @Override
+ public Template onGetTemplate() {
+ List<String> permissions = new ArrayList<>();
+ permissions.add(ACCESS_FINE_LOCATION);
+
+ String message = "This app needs access to location in order to show the map around you";
+
+ OnClickListener listener = ParkedOnlyOnClickListener.create(() ->
+ getCarContext().requestPermissions(
+ permissions,
+ (approved, rejected) -> {
+ CarToast.makeText(
+ getCarContext(),
+ String.format("Approved: %s Rejected: %s", approved, rejected),
+ CarToast.LENGTH_LONG).show();
+ if (!approved.isEmpty()) {
+ mLocationPermissionCheckCallback.onPermissionGranted();
+ finish();
+ }
+ }));
+
+ Action action = new Action.Builder()
+ .setTitle("Grant Access")
+ .setBackgroundColor(CarColor.GREEN)
+ .setOnClickListener(listener)
+ .build();
+
+ return new MessageTemplate.Builder(message).addAction(action).setHeaderAction(
+ Action.APP_ICON).build();
+ }
+}
diff --git a/car/app/app/src/main/java/androidx/car/app/hardware/CarHardwareManager.java b/car/app/app/src/main/java/androidx/car/app/hardware/CarHardwareManager.java
index 59d9f3f..dbb14bf7 100644
--- a/car/app/app/src/main/java/androidx/car/app/hardware/CarHardwareManager.java
+++ b/car/app/app/src/main/java/androidx/car/app/hardware/CarHardwareManager.java
@@ -24,10 +24,12 @@
import androidx.annotation.RestrictTo;
import androidx.car.app.CarContext;
import androidx.car.app.HostDispatcher;
+import androidx.car.app.HostException;
import androidx.car.app.annotations.RequiresCarApi;
import androidx.car.app.hardware.info.CarInfo;
import androidx.car.app.hardware.info.CarSensors;
import androidx.car.app.managers.Manager;
+import androidx.car.app.versioning.CarAppApiLevels;
import java.lang.reflect.Constructor;
@@ -59,13 +61,20 @@
*
* @throws IllegalStateException if none of the supported classes are found or if a supported
* class was found but the constructor was mismatched
+ * @throws HostException if the negotiated api level is less than
+ * {@link CarAppApiLevels#LEVEL_3}
* @hide
*/
@RestrictTo(LIBRARY)
@NonNull
static CarHardwareManager create(@NonNull CarContext context,
- @NonNull HostDispatcher hostDispatcher) throws IllegalStateException {
- // TODO(b/192493839) : Switch to using Manager.create
+ @NonNull HostDispatcher hostDispatcher) {
+ if (context.getCarAppApiLevel() < CarAppApiLevels.LEVEL_3) {
+ throw new HostException("Create CarHardwareManager failed",
+ new IllegalArgumentException("Attempted to retrieve CarHardwareManager "
+ + "service, but the host is less than " + CarAppApiLevels.LEVEL_3));
+ }
+
try { // Check for automotive library first.
Class<?> c = Class.forName("androidx.car.app.hardware.AutomotiveCarHardwareManager");
Constructor<?> ctor = c.getConstructor(Context.class);
@@ -78,7 +87,7 @@
throw new IllegalStateException("Mismatch with app-automotive artifact", e);
}
- try { // Check for automotive library first.
+ try { // Check for projected library.
Class<?> c = Class.forName("androidx.car.app.hardware.ProjectedCarHardwareManager");
Constructor<?> ctor = c.getConstructor(HostDispatcher.class);
Object object = ctor.newInstance(hostDispatcher);
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/collection/IdentityArrayMap.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/collection/IdentityArrayMap.kt
index 74e3053..cf481a3 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/collection/IdentityArrayMap.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/collection/IdentityArrayMap.kt
@@ -97,9 +97,10 @@
startIndex = index + 1,
endIndex = size
)
- keys[size] = null
- values[size] = null
- this.size = size - 1
+ val newSize = size - 1
+ keys[newSize] = null
+ values[newSize] = null
+ this.size = newSize
return true
}
return false
diff --git a/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/collection/IdentityArrayMapTests.kt b/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/collection/IdentityArrayMapTests.kt
index b4f9bec..f615fb9 100644
--- a/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/collection/IdentityArrayMapTests.kt
+++ b/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/collection/IdentityArrayMapTests.kt
@@ -105,4 +105,19 @@
}
}
}
+
+ @Test // b/195621739
+ fun canRemoveWhenFull() {
+ val map = IdentityArrayMap<Key, String>()
+ repeat(16) {
+ map[keys[it]] = it.toString()
+ }
+ repeat(16) {
+ val key = keys[it]
+ val removed = map.remove(key)
+ assertTrue(removed)
+ assertFalse(map.contains(key))
+ }
+ assertTrue(map.isEmpty())
+ }
}
\ No newline at end of file
diff --git a/core/OWNERS b/core/OWNERS
index 37b3e14..cb02012 100644
--- a/core/OWNERS
+++ b/core/OWNERS
@@ -1,4 +1,5 @@
# Bug component: 460834
[email protected]
[email protected]
[email protected]
[email protected]
diff --git a/development/build_log_simplifier/messages.ignore b/development/build_log_simplifier/messages.ignore
index bb040f9..f2684a0 100644
--- a/development/build_log_simplifier/messages.ignore
+++ b/development/build_log_simplifier/messages.ignore
@@ -523,6 +523,8 @@
@param bounds,
\@param defaultPolicy
@param complicationTapFilter
+in DClass UserStyle
+@param copySelectedOptions
in DClass Builder
Did you make a typo\? Are you trying to refer to something not visible to users\?
# Wire proto generation, task :generateDebugProtos
diff --git a/development/update_studio.sh b/development/update_studio.sh
index 668e2b8..e4d192c 100755
--- a/development/update_studio.sh
+++ b/development/update_studio.sh
@@ -1,7 +1,7 @@
#!/bin/bash
# Get versions
-AGP_VERSION=${1:-7.1.0-alpha06}
-STUDIO_VERSION_STRING=${2:-"Android Studio Bumblebee (2021.1.1) Canary 6"}
+AGP_VERSION=${1:-7.1.0-alpha07}
+STUDIO_VERSION_STRING=${2:-"Android Studio Bumblebee (2021.1.1) Canary 7"}
STUDIO_IFRAME_LINK=`curl "https://developer.android.com/studio/archive.html" | grep iframe | sed "s/.*src=\"\([a-zA-Z0-9\/\._]*\)\".*/https:\/\/android-dot-devsite-v2-prod.appspot.com\1/g"`
STUDIO_LINK=`curl -s $STUDIO_IFRAME_LINK | grep -C30 "$STUDIO_VERSION_STRING" | grep Linux | tail -n 1 | sed 's/.*a href="\(.*\).*"/\1/g'`
STUDIO_VERSION=`echo $STUDIO_LINK | sed "s/.*ide-zips\/\(.*\)\/android-studio-.*/\1/g"`
@@ -37,7 +37,7 @@
./development/importMaven/import_maven_artifacts.py -n "com.android.tools.utp:$ARTIFACT:$ADT_VERSION"
done
-ATP_VERSION=${4:-0.0.8-alpha07}
+ATP_VERSION=${4:-0.0.8-alpha06}
./development/importMaven/import_maven_artifacts.py -n "com.google.testing.platform:android-test-plugin:$ATP_VERSION"
./development/importMaven/import_maven_artifacts.py -n "com.google.testing.platform:launcher:$ATP_VERSION"
./development/importMaven/import_maven_artifacts.py -n "com.google.testing.platform:android-driver-instrumentation:$ATP_VERSION"
diff --git a/emoji2/emoji2-benchmark/src/androidTest/java/androidx/emoji2/benchmark/reflection/ReflectionImplementation.java b/emoji2/emoji2-benchmark/src/androidTest/java/androidx/emoji2/benchmark/reflection/ReflectionImplementation.java
deleted file mode 100644
index c0b7a72..0000000
--- a/emoji2/emoji2-benchmark/src/androidTest/java/androidx/emoji2/benchmark/reflection/ReflectionImplementation.java
+++ /dev/null
@@ -1,63 +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.benchmark.reflection;
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.reflect.Method;
-
-public class ReflectionImplementation extends ReflectionParent {
- @Override
- public ReflectionParent actualCall() {
- return super.actualCall();
- }
-
- ReflectionParent staticActualCall() throws Throwable {
- return ParentMethodHandles.staticCall(this);
- }
-
- MethodHandle doMethodLookup() throws NoSuchMethodException, IllegalAccessException {
- return ParentMethodHandles.doMethodLookup();
- }
-
- private static class ParentMethodHandles {
- private static final MethodHandle sMethodHandle;
-
- static {
- MethodHandle sMethodHandle1 = null;
- try {
- sMethodHandle1 = doMethodLookup();
- } catch (Throwable ignored) { }
- sMethodHandle = sMethodHandle1;
- }
-
- private static MethodHandle doMethodLookup() throws IllegalAccessException,
- NoSuchMethodException {
- MethodHandles.Lookup lookup = MethodHandles.lookup().in(ReflectionParent.class);
- Method method = ReflectionParent.class.getDeclaredMethod("actualCall");
- method.setAccessible(true);
- return lookup.unreflectSpecial(method, ReflectionParent.class);
- }
-
- public static ReflectionParent staticCall(ReflectionImplementation reflectionImplementation)
- throws Throwable {
- return (ReflectionParent) sMethodHandle.bindTo(reflectionImplementation)
- .invokeWithArguments();
- }
- }
-
-}
diff --git a/emoji2/emoji2-benchmark/src/androidTest/java/androidx/emoji2/benchmark/reflection/ReflectionParent.java b/emoji2/emoji2-benchmark/src/androidTest/java/androidx/emoji2/benchmark/reflection/ReflectionParent.java
deleted file mode 100644
index d297463..0000000
--- a/emoji2/emoji2-benchmark/src/androidTest/java/androidx/emoji2/benchmark/reflection/ReflectionParent.java
+++ /dev/null
@@ -1,23 +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.benchmark.reflection;
-
-public class ReflectionParent {
- public ReflectionParent actualCall() {
- return this;
- }
-}
diff --git a/emoji2/emoji2-benchmark/src/androidTest/java/androidx/emoji2/benchmark/reflection/ReflectionsBenchmark.java b/emoji2/emoji2-benchmark/src/androidTest/java/androidx/emoji2/benchmark/reflection/ReflectionsBenchmark.java
deleted file mode 100644
index c9e59fa..0000000
--- a/emoji2/emoji2-benchmark/src/androidTest/java/androidx/emoji2/benchmark/reflection/ReflectionsBenchmark.java
+++ /dev/null
@@ -1,77 +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.benchmark.reflection;
-
-import static org.junit.Assert.assertNotNull;
-
-import androidx.benchmark.BenchmarkState;
-import androidx.benchmark.junit4.BenchmarkRule;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.LargeTest;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.lang.invoke.MethodHandle;
-
-@RunWith(AndroidJUnit4.class)
-@LargeTest
-public class ReflectionsBenchmark {
- @Rule
- public BenchmarkRule benchmarkRule = new BenchmarkRule();
-
- @Test
- public void static_methodHandle() throws Throwable {
- BenchmarkState state = benchmarkRule.getState();
- ReflectionImplementation subject = new ReflectionImplementation();
- ReflectionParent result = null;
- while (state.keepRunning()) {
- result = subject.staticActualCall();
- }
- assertNotNull(result);
- }
-
- @Test
- public void regularJavaDispatch() {
- BenchmarkState state = benchmarkRule.getState();
- ReflectionImplementation subject = new ReflectionImplementation();
- ReflectionParent result = null;
- while (state.keepRunning()) {
- result = subject.actualCall();
- }
- assertNotNull(result);
- }
-
- /**
- * This test is not an accurate reflection of first lookup cost, as it will warm up caches
- * before the main benchmark starts.
- *
- * However, it is a good _lower bound_ of the cost to do this lookup, with the assumption
- * that real world lookups will always be the same cost or slower.
- */
- @Test
- public void doWarmedUpMethodLookup() throws NoSuchMethodException, IllegalAccessException {
- BenchmarkState state = benchmarkRule.getState();
- ReflectionImplementation subject = new ReflectionImplementation();
- MethodHandle result = null;
- while (state.keepRunning()) {
- result = subject.doMethodLookup();
- }
- assertNotNull(result);
- }
-}
diff --git a/emoji2/emoji2-benchmark/src/androidTest/java/androidx/emoji2/benchmark/text/NoFontTestEmojiConfig.java b/emoji2/emoji2-benchmark/src/androidTest/java/androidx/emoji2/benchmark/text/NoFontTestEmojiConfig.java
index f706f84..67ad432 100644
--- a/emoji2/emoji2-benchmark/src/androidTest/java/androidx/emoji2/benchmark/text/NoFontTestEmojiConfig.java
+++ b/emoji2/emoji2-benchmark/src/androidTest/java/androidx/emoji2/benchmark/text/NoFontTestEmojiConfig.java
@@ -21,9 +21,11 @@
import android.graphics.Typeface;
import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
import androidx.emoji2.text.EmojiCompat;
import androidx.emoji2.text.MetadataRepo;
+@RequiresApi(19)
public class NoFontTestEmojiConfig extends EmojiCompat.Config {
static EmojiCompat.Config emptyConfig() {
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 45e5b4e..7adf9d4 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -2,13 +2,13 @@
# -----------------------------------------------------------------------------
# All of the following should be updated in sync.
# -----------------------------------------------------------------------------
-androidGradlePlugin = "7.1.0-alpha06"
+androidGradlePlugin = "7.1.0-alpha07"
# NOTE: When updating the lint version we also need to update the `api` version
# supported by `IssueRegistry`'s.' For e.g. r.android.com/1331903
-androidLint = "30.1.0-alpha06"
+androidLint = "30.1.0-alpha07"
# Once you have a chosen version of AGP to upgrade to, go to
# https://developer.android.com/studio/archive and find the matching version of Studio.
-androidStudio = "2021.1.1.6"
+androidStudio = "2021.1.1.7"
# -----------------------------------------------------------------------------
androidLintMin = "27.2.1"
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewLayoutTest.java b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewLayoutTest.java
index 1f308a1..590e787 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewLayoutTest.java
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewLayoutTest.java
@@ -1880,6 +1880,7 @@
scrollInOtherOrientationTest(FLAG_VERTICAL | FLAG_FLING);
}
+ @FlakyTest(bugId = 195936088)
@SuppressWarnings("WrongConstant")
@Test
public void nestedDragVertical() throws Throwable {
diff --git a/room/room-compiler/build.gradle b/room/room-compiler/build.gradle
index d2b5199..10e2f25 100644
--- a/room/room-compiler/build.gradle
+++ b/room/room-compiler/build.gradle
@@ -19,7 +19,8 @@
import androidx.build.LibraryType
import androidx.build.SupportConfig
import androidx.build.SdkHelperKt
-import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation
+import java.util.zip.ZipEntry
+import java.util.zip.ZipFile
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
@@ -61,6 +62,8 @@
exclude(dependency("org.glassfish:.*"))
exclude(dependency("com.ibm.icu:.*"))
}
+ relocate("org.antlr", "androidx.room.jarjarred.org.antlr")
+ relocate("org.stringtemplate", "androidx.room.jarjarred.org.stringtemplate")
}
jar {
@@ -70,14 +73,6 @@
archiveClassifier = "before-jarjar"
}
-// relocate all shadow dependencies
-task relocateShadowJar(type: ConfigureShadowRelocation) {
- target = tasks.shadowJar
- prefix = "androidx.room.jarjarred"
-}
-
-tasks.shadowJar.dependsOn(tasks.relocateShadowJar)
-
configurations {
// replace the standard jar with the one built by 'shadowJar' in both api and runtime variants
apiElements.outgoing.artifacts.clear()
@@ -166,17 +161,27 @@
* their location.
*/
def validateJarContents(File jarFile) {
- FileTree jarFiles = project.zipTree(jarFile)
- def found = false
- jarFiles.files.each {
- if (it.path.contains("/org/antlr")) {
- found = true
- if (!it.path.contains("androidx/room/jarjarred/org/antlr")) {
- throw new GradleException("Any Antlr class included in the Room Compiler's" +
- " jar file should be moved into androidx/room/jarjarred.\n" +
- "Looks like $it has not been moved")
+ Boolean found = false
+ ZipFile zip = new ZipFile(jarFile)
+ try {
+ for (Enumeration list = zip.entries(); list.hasMoreElements(); ) {
+ String entry = ((ZipEntry) list.nextElement()).name
+ if (!entry.endsWith(".class")) continue
+ if (entry.contains("org/antlr")) {
+ found = true
+ if (!entry.contains("androidx/room/jarjarred/org/antlr")) {
+ throw new GradleException("Any Antlr class included in the Room Compiler's" +
+ " jar file should be moved into androidx/room/jarjarred.\n" +
+ "Looks like $entry has not been moved")
+ }
+ }
+ if (!entry.startsWith("androidx/room/") && !entry.startsWith("Jdbc_extKt")) {
+ throw new GradleException("Found a class that is not in androidx.room " +
+ "package: $entry")
}
}
+ } finally {
+ zip.close()
}
if (!found) {
throw new GradleException("Couldn't find any Antlr classes in room-compiler artifact" +
diff --git a/room/room-paging/src/androidTest/kotlin/androidx/room/paging/LimitOffsetPagingSourceTest.kt b/room/room-paging/src/androidTest/kotlin/androidx/room/paging/LimitOffsetPagingSourceTest.kt
index 0b2d513..4420a8b 100644
--- a/room/room-paging/src/androidTest/kotlin/androidx/room/paging/LimitOffsetPagingSourceTest.kt
+++ b/room/room-paging/src/androidTest/kotlin/androidx/room/paging/LimitOffsetPagingSourceTest.kt
@@ -29,6 +29,7 @@
import androidx.room.util.CursorUtil
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.FlakyTest
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.runBlocking
@@ -161,6 +162,7 @@
}
}
+ @FlakyTest(bugId = 195794422)
@Test
fun load_initialEmptyLoad() {
val pagingSource = LimitOffsetPagingSourceImpl(database)
diff --git a/security/security-crypto/api/current.ignore b/security/security-crypto/api/current.ignore
new file mode 100644
index 0000000..5cadc4b
--- /dev/null
+++ b/security/security-crypto/api/current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+ChangedThrows: androidx.security.crypto.EncryptedFile#openFileInput():
+ Method androidx.security.crypto.EncryptedFile.openFileInput added thrown exception java.io.FileNotFoundException
diff --git a/security/security-crypto/api/current.txt b/security/security-crypto/api/current.txt
index 5ce7749..5ac2ea1 100644
--- a/security/security-crypto/api/current.txt
+++ b/security/security-crypto/api/current.txt
@@ -2,7 +2,7 @@
package androidx.security.crypto {
public final class EncryptedFile {
- method public java.io.FileInputStream openFileInput() throws java.security.GeneralSecurityException, java.io.IOException;
+ method public java.io.FileInputStream openFileInput() throws java.io.FileNotFoundException, java.security.GeneralSecurityException, java.io.IOException;
method public java.io.FileOutputStream openFileOutput() throws java.security.GeneralSecurityException, java.io.IOException;
}
diff --git a/security/security-crypto/api/public_plus_experimental_current.txt b/security/security-crypto/api/public_plus_experimental_current.txt
index 5ce7749..5ac2ea1 100644
--- a/security/security-crypto/api/public_plus_experimental_current.txt
+++ b/security/security-crypto/api/public_plus_experimental_current.txt
@@ -2,7 +2,7 @@
package androidx.security.crypto {
public final class EncryptedFile {
- method public java.io.FileInputStream openFileInput() throws java.security.GeneralSecurityException, java.io.IOException;
+ method public java.io.FileInputStream openFileInput() throws java.io.FileNotFoundException, java.security.GeneralSecurityException, java.io.IOException;
method public java.io.FileOutputStream openFileOutput() throws java.security.GeneralSecurityException, java.io.IOException;
}
diff --git a/security/security-crypto/api/restricted_current.ignore b/security/security-crypto/api/restricted_current.ignore
new file mode 100644
index 0000000..5cadc4b
--- /dev/null
+++ b/security/security-crypto/api/restricted_current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+ChangedThrows: androidx.security.crypto.EncryptedFile#openFileInput():
+ Method androidx.security.crypto.EncryptedFile.openFileInput added thrown exception java.io.FileNotFoundException
diff --git a/security/security-crypto/api/restricted_current.txt b/security/security-crypto/api/restricted_current.txt
index 5ce7749..5ac2ea1 100644
--- a/security/security-crypto/api/restricted_current.txt
+++ b/security/security-crypto/api/restricted_current.txt
@@ -2,7 +2,7 @@
package androidx.security.crypto {
public final class EncryptedFile {
- method public java.io.FileInputStream openFileInput() throws java.security.GeneralSecurityException, java.io.IOException;
+ method public java.io.FileInputStream openFileInput() throws java.io.FileNotFoundException, java.security.GeneralSecurityException, java.io.IOException;
method public java.io.FileOutputStream openFileOutput() throws java.security.GeneralSecurityException, java.io.IOException;
}
diff --git a/security/security-crypto/src/androidTest/java/androidx/security/crypto/EncryptedFileTest.java b/security/security-crypto/src/androidTest/java/androidx/security/crypto/EncryptedFileTest.java
index b08a7bf..e2ed7a5 100644
--- a/security/security-crypto/src/androidTest/java/androidx/security/crypto/EncryptedFileTest.java
+++ b/security/security-crypto/src/androidTest/java/androidx/security/crypto/EncryptedFileTest.java
@@ -18,6 +18,9 @@
import static androidx.security.crypto.MasterKey.KEYSTORE_PATH_URI;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
import static java.nio.charset.StandardCharsets.UTF_8;
import android.content.Context;
@@ -41,6 +44,7 @@
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -102,7 +106,7 @@
EncryptedFile encryptedFile = new EncryptedFile.Builder(mContext,
new File(mContext.getFilesDir(),
- fileName), mMasterKey,
+ fileName), mMasterKey,
EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB)
.build();
@@ -152,7 +156,7 @@
} catch (IOException ex) {
inputFailed = true;
}
- Assert.assertTrue("File should have failed opening.", inputFailed);
+ assertTrue("File should have failed opening.", inputFailed);
EncryptedFile existingFileOutputCheck = new EncryptedFile.Builder(mContext,
new File(mContext.getFilesDir(), fileName), mMasterKey,
@@ -164,7 +168,7 @@
} catch (IOException ex) {
outputFailed = true;
}
- Assert.assertTrue("File should have failed writing.", outputFailed);
+ assertTrue("File should have failed writing.", outputFailed);
}
@@ -177,7 +181,7 @@
// Write
EncryptedFile encryptedFile = new EncryptedFile.Builder(new File(mContext.getFilesDir(),
- fileName), mContext, mMasterKey.getKeyAlias(),
+ fileName), mContext, mMasterKey.getKeyAlias(),
EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB)
.build();
@@ -227,7 +231,7 @@
} catch (IOException ex) {
inputFailed = true;
}
- Assert.assertTrue("File should have failed opening.", inputFailed);
+ assertTrue("File should have failed opening.", inputFailed);
EncryptedFile existingFileOutputCheck = new EncryptedFile.Builder(
new File(mContext.getFilesDir(), fileName), mContext, mMasterKey.getKeyAlias(),
@@ -239,8 +243,28 @@
} catch (IOException ex) {
outputFailed = true;
}
- Assert.assertTrue("File should have failed writing.", outputFailed);
+ assertTrue("File should have failed writing.", outputFailed);
+ }
+ @Test
+ public void testReadNonExistingFileThrows() throws Exception {
+ final File nonExisting = new File(mContext.getFilesDir(), "non-existing.data");
+ if (nonExisting.exists()) {
+ assertTrue(nonExisting.delete());
+ }
+ EncryptedFile encryptedFile = new EncryptedFile.Builder(
+ mContext,
+ nonExisting,
+ mMasterKey,
+ EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB)
+ .build();
+
+ try {
+ FileInputStream stream = encryptedFile.openFileInput();
+ fail("Successfully opened file that should not exist");
+ } catch (FileNotFoundException fnf) {
+ // Pass
+ }
}
@Test
@@ -251,7 +275,7 @@
// Write
EncryptedFile encryptedFile = new EncryptedFile.Builder(mContext,
new File(mContext.getFilesDir(),
- fileName), mMasterKey,
+ fileName), mMasterKey,
EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB)
.setKeysetAlias("CustomKEYALIAS")
.setKeysetPrefName("CUSTOMPREFNAME")
@@ -295,7 +319,7 @@
SharedPreferences sharedPreferences = mContext.getSharedPreferences("CUSTOMPREFNAME",
Context.MODE_PRIVATE);
boolean containsKeyset = sharedPreferences.contains("CustomKEYALIAS");
- Assert.assertTrue("Keyset should have existed.", containsKeyset);
+ assertTrue("Keyset should have existed.", containsKeyset);
}
@SuppressWarnings("deprecation")
diff --git a/security/security-crypto/src/main/java/androidx/security/crypto/EncryptedFile.java b/security/security-crypto/src/main/java/androidx/security/crypto/EncryptedFile.java
index fce4770..6b0bd91 100644
--- a/security/security-crypto/src/main/java/androidx/security/crypto/EncryptedFile.java
+++ b/security/security-crypto/src/main/java/androidx/security/crypto/EncryptedFile.java
@@ -35,6 +35,7 @@
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -238,13 +239,14 @@
*
* @return The input stream to read previously encrypted data.
* @throws GeneralSecurityException when a bad master key or keyset has been used
- * @throws IOException when the file was not found
+ * @throws FileNotFoundException when the file was not found
+ * @throws IOException when other I/O errors occur
*/
@NonNull
public FileInputStream openFileInput()
- throws GeneralSecurityException, IOException {
+ throws GeneralSecurityException, IOException, FileNotFoundException {
if (!mFile.exists()) {
- throw new IOException("file doesn't exist: " + mFile.getName());
+ throw new FileNotFoundException("file doesn't exist: " + mFile.getName());
}
FileInputStream fileInputStream = new FileInputStream(mFile);
InputStream decryptingStream = mStreamingAead.newDecryptingStream(fileInputStream,
diff --git a/wear/wear-watchface-client-guava/src/main/java/androidx/wear/watchface/client/ListenableWatchFaceControlClient.kt b/wear/wear-watchface-client-guava/src/main/java/androidx/wear/watchface/client/ListenableWatchFaceControlClient.kt
index 73d7f12..dc33854d 100644
--- a/wear/wear-watchface-client-guava/src/main/java/androidx/wear/watchface/client/ListenableWatchFaceControlClient.kt
+++ b/wear/wear-watchface-client-guava/src/main/java/androidx/wear/watchface/client/ListenableWatchFaceControlClient.kt
@@ -87,9 +87,8 @@
/**
* Returns a [ListenableFuture] for a [ListenableWatchFaceControlClient] which attempts to
- * connect to a watch face in the android package [watchFacePackageName].
- * Resolves as [ServiceNotBoundException] if the watch face control service can not
- * be bound.
+ * connect to a watch face in the android package [watchFacePackageName]. Resolves as
+ * [ServiceNotBoundException] if the watch face control service can not be bound.
*
* Note the returned future may resolve immediately on the calling thread or it may resolve
* asynchronously when the service is connected on a background thread.
@@ -135,6 +134,15 @@
* [ListenableFuture] wrapper around
* [WatchFaceControlClient.getOrCreateInteractiveWatchFaceClient].
* This is open to allow mocking.
+ *
+ * @param id The Id of the interactive instance to get or create.
+ * @param deviceConfig The [DeviceConfig] of the interactive instance (only used when creating)
+ * @param watchUiState The initial [WatchUiState] for the wearable.
+ * @param userStyle Optional [UserStyleData] to apply to the instance (whether or not it's
+ * created). If `null` then the pre-existing user style is preserved (if the instance is created
+ * this will be the [androidx.wear.watchface.style.UserStyleSchema]'s default).
+ * @param slotIdToComplicationData The initial [androidx.wear.watchface.ComplicationSlot] data,
+ * or `null` if unavailable.
*/
public open fun listenableGetOrCreateInteractiveWatchFaceClient(
id: String,
diff --git a/wear/wear-watchface-client/src/main/java/androidx/wear/watchface/client/InteractiveWatchFaceClient.kt b/wear/wear-watchface-client/src/main/java/androidx/wear/watchface/client/InteractiveWatchFaceClient.kt
index 9396ed3..d14f5f1 100644
--- a/wear/wear-watchface-client/src/main/java/androidx/wear/watchface/client/InteractiveWatchFaceClient.kt
+++ b/wear/wear-watchface-client/src/main/java/androidx/wear/watchface/client/InteractiveWatchFaceClient.kt
@@ -126,6 +126,8 @@
/**
* Returns the ID of the [androidx.wear.watchface.ComplicationSlot] at the given coordinates or
* `null` if there isn't one.
+ *
+ * Note this currently doesn't support Edge complications.
*/
@SuppressWarnings("AutoBoxing")
@Throws(RemoteException::class)
diff --git a/wear/wear-watchface-client/src/main/java/androidx/wear/watchface/client/WatchFaceControlClient.kt b/wear/wear-watchface-client/src/main/java/androidx/wear/watchface/client/WatchFaceControlClient.kt
index 2c7812b..6e441c9 100644
--- a/wear/wear-watchface-client/src/main/java/androidx/wear/watchface/client/WatchFaceControlClient.kt
+++ b/wear/wear-watchface-client/src/main/java/androidx/wear/watchface/client/WatchFaceControlClient.kt
@@ -38,7 +38,6 @@
import androidx.wear.watchface.control.data.WallpaperInteractiveWatchFaceInstanceParams
import androidx.wear.watchface.data.IdAndComplicationDataWireFormat
import androidx.wear.watchface.data.WatchUiState
-import androidx.wear.watchface.style.UserStyle
import androidx.wear.watchface.style.UserStyleData
import androidx.wear.watchface.style.data.UserStyleWireFormat
import kotlinx.coroutines.CompletableDeferred
@@ -168,8 +167,9 @@
* @param id The ID for the requested [InteractiveWatchFaceClient].
* @param deviceConfig The [DeviceConfig] for the wearable.
* @param watchUiState The initial [WatchUiState] for the wearable.
- * @param userStyle The initial style map encoded as [UserStyleData] (see [UserStyle]), or
- * `null` if the default should be used.
+ * @param userStyle Optional [UserStyleData] to apply to the instance (whether or not it's
+ * created). If `null` then the pre-existing user style is preserved (if the instance is created
+ * this will be the [androidx.wear.watchface.style.UserStyleSchema]'s default).
* @param slotIdToComplicationData The initial [androidx.wear.watchface.ComplicationSlot] data,
* or `null` if unavailable.
* @return The [InteractiveWatchFaceClient], this should be closed when finished.
diff --git a/wear/wear-watchface-complications-rendering/src/main/java/androidx/wear/watchface/complications/rendering/ComplicationDrawable.kt b/wear/wear-watchface-complications-rendering/src/main/java/androidx/wear/watchface/complications/rendering/ComplicationDrawable.kt
index bdbf5aa..d90af48 100644
--- a/wear/wear-watchface-complications-rendering/src/main/java/androidx/wear/watchface/complications/rendering/ComplicationDrawable.kt
+++ b/wear/wear-watchface-complications-rendering/src/main/java/androidx/wear/watchface/complications/rendering/ComplicationDrawable.kt
@@ -192,10 +192,10 @@
internal var complicationRenderer: ComplicationRenderer? = null
private set
- /** Returns complication style for active mode. */
+ /** Returns complication style for active mode. */
public val activeStyle: ComplicationStyle
- /** Returns complication style for ambient mode. */
+ /** Returns complication style for ambient mode. */
public val ambientStyle: ComplicationStyle
private val mainThreadHandler = Handler(Looper.getMainLooper())
@@ -206,17 +206,17 @@
private val rendererInvalidateListener = OnInvalidateListener { invalidateSelf() }
/**
- * The time in milliseconds since the epoch used for rendering [ComplicationData]
- * with time dependent text.
+ * The time in milliseconds since the epoch used for rendering [ComplicationData] with time
+ * dependent text.
*/
public var currentTimeMillis: Long = 0
- /** Whether the complication is rendered in ambient mode. */
+ /** Whether the complication is rendered in ambient mode. */
public var isInAmbientMode: Boolean = false
/**
- * Whether the complication, when rendering in ambient mode, should apply a style
- * suitable for low bit ambient mode.
+ * Whether the complication, when rendering in ambient mode, should apply a style suitable for
+ * low bit ambient mode.
*/
public var isLowBitAmbient: Boolean = false
@@ -227,8 +227,8 @@
public var isBurnInProtectionOn: Boolean = false
/**
- * Whether the complication is currently highlighted. This may be called by a watch face
- * when a complication is tapped.
+ * Whether the complication is currently highlighted. This may be called by a watch face when
+ * a complication is tapped.
*
* If watch face is in ambient mode, highlight will not be visible even if this is set to
* `true`, because it may cause burn-in or power inefficiency.
@@ -238,7 +238,7 @@
private var isInflatedFromXml = false
private var alreadyStyled = false
- /** Default constructor. */
+ /** Default constructor. */
public constructor() {
activeStyle = ComplicationStyle()
ambientStyle = ComplicationStyle()
@@ -246,7 +246,9 @@
/**
* Creates a ComplicationDrawable using the given context. If this constructor is used, calling
- * [.setContext] may not be necessary.
+ * [setContext] may not be necessary.
+ *
+ * @param context The [Context] used to render the complication.
*/
public constructor(context: Context) : this() {
setContext(context)
@@ -269,12 +271,12 @@
}
/**
- * Sets the context used to render the complication. If a context is not set,
- * ComplicationDrawable will throw an [IllegalStateException] if one of [draw], [setBounds],
- * or [setComplicationData] is called.
+ * Sets the [Context] used to render the complication. If a context is not set,
+ * ComplicationDrawable will throw an [IllegalStateException] if one of [draw], [setBounds], or
+ * [setComplicationData] is called.
*
* While this can be called from any context, ideally, a
- * androidx.wear.watchface.WatchFaceService object should be passed here to allow creating
+ * [androidx.wear.watchface.WatchFaceService] object should be passed here to allow creating
* permission dialogs by the [onTap] method, in case current watch face doesn't have the
* permission to receive complication data.
*
@@ -282,8 +284,10 @@
* be called before calling any of the methods mentioned above.
*
* If this ComplicationDrawable is not inflated from an XML file, this method will reset the
- * style to match the default values, so if [ComplicationDrawable()] is used to construct a
- * ComplicationDrawable, this method should be called right after.
+ * style to match the default values, so if ComplicationDrawable(drawable: ComplicationDrawable)
+ * is used to construct a ComplicationDrawable, this method should be called right after.
+ *
+ * @param context The [Context] used to render the complication.
*/
public fun setContext(context: Context) {
if (context == this.context) {
@@ -556,8 +560,8 @@
}
/**
- * Sets the complication data to be drawn. If `complicationData` is `null`, nothing
- * will be drawn when [draw] is called.
+ * Sets the complication data to be drawn. If `complicationData` is `null`, nothing will be
+ * drawn when [draw] is called.
*
* @param complicationData The [ComplicationData] to set
* @param loadDrawablesAsync If true any drawables should be loaded asynchronously,
@@ -695,10 +699,10 @@
"ComplicationDrawable does not have a context. Use setContext(Context) to set it first."
}
}
+
/**
* The text to be rendered when [ComplicationData] is of type [NO_DATA]. If `noDataText` is
- * null, an empty text will be
- * rendered.
+ * null, an empty text will be rendered.
*/
public var noDataText: CharSequence? = null
set(noDataText) {
@@ -724,7 +728,7 @@
return drawable
}
- /** Sets the style to default values using resources. */
+ /** Sets the style to default values using resources. */
@JvmStatic
internal fun setStyleToDefaultValues(style: ComplicationStyle, r: Resources) {
style.backgroundColor = r.getColor(R.color.complicationDrawable_backgroundColor, null)
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 2c0dadd..868cee7 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
@@ -174,7 +174,7 @@
/**
* Initializes complication renderer.
*
- * @param context Current context.
+ * @param context Current [Context].
* @param activeStyle ComplicationSlot style to be used when in active mode.
* @param ambientStyle ComplicationSlot style to be used when in ambient mode.
*/
diff --git a/wear/wear-watchface-editor-guava/src/main/java/androidx/wear/watchface/editor/ListenableEditorSession.kt b/wear/wear-watchface-editor-guava/src/main/java/androidx/wear/watchface/editor/ListenableEditorSession.kt
index e746e76..0c30a81 100644
--- a/wear/wear-watchface-editor-guava/src/main/java/androidx/wear/watchface/editor/ListenableEditorSession.kt
+++ b/wear/wear-watchface-editor-guava/src/main/java/androidx/wear/watchface/editor/ListenableEditorSession.kt
@@ -53,15 +53,15 @@
*
* If watch face editor takes more than 4s to create a watch face, returned future will be
* resolved with [TimeoutCancellationException] exception.
+ *
+ * @param activity The [ComponentActivity] associated with the EditorSession.
+ * @param editIntent [Intent] sent by SysUI to launch the editing session.
*/
@SuppressWarnings("ExecutorRegistration")
@JvmStatic
@UiThread
public fun listenableCreateOnWatchEditorSession(
- /** The [ComponentActivity] associated with the EditorSession. */
activity: ComponentActivity,
-
- /** [Intent] sent by SysUI to launch the editing session. */
editIntent: Intent
): ListenableFuture<ListenableEditorSession?> {
val result = ResolvableFuture.create<ListenableEditorSession?>()
@@ -85,17 +85,20 @@
return result
}
- /** Constructs an [ListenableEditorSession] for a remote watch face editor. */
+ /**
+ * Constructs an [ListenableEditorSession] for a remote watch face editor.
+ *
+ * @param activity The [ComponentActivity] associated with the EditorSession.
+ * @param editIntent [Intent] sent by SysUI to launch the editing session.
+ * @param headlessWatchFaceClient The [HeadlessWatchFaceClient] that backs the constructed
+ * EditorSession.
+ */
@JvmStatic
@RequiresApi(27)
@UiThread
public fun createHeadlessEditorSession(
- /** The [ComponentActivity] associated with the EditorSession. */
activity: ComponentActivity,
-
- /** [Intent] sent by SysUI to launch the editing session. */
editIntent: Intent,
-
headlessWatchFaceClient: HeadlessWatchFaceClient
): ListenableEditorSession = ListenableEditorSession(
EditorSession.createHeadlessEditorSession(
diff --git a/wear/wear-watchface-editor/src/main/java/androidx/wear/watchface/editor/EditorSession.kt b/wear/wear-watchface-editor/src/main/java/androidx/wear/watchface/editor/EditorSession.kt
index 28be503..39ad69f 100644
--- a/wear/wear-watchface-editor/src/main/java/androidx/wear/watchface/editor/EditorSession.kt
+++ b/wear/wear-watchface-editor/src/main/java/androidx/wear/watchface/editor/EditorSession.kt
@@ -82,10 +82,10 @@
*
* For EditorSessions backed by a headless instance (see [createHeadlessEditorSession] and
* [EditorRequest.headlessDeviceConfig]), style changes are not applied to the interactive
- * instance and it's up to the system to apply them. For EditorSessions backed by an
- * interactive instance style changes are applied immediately. Its possible the system might fail to
- * persist the style changes (e.g. to data base write failure or a crash) and if this happens its
- * the responsibility of the system to revert the style change.
+ * instance and it's up to the system to apply them. For EditorSessions backed by an interactive
+ * instance style changes are applied immediately. Its possible the system might fail to persist
+ * the style changes (e.g. to data base write failure or a crash) and if this happens it's the
+ * responsibility of the system to revert the style change.
*/
public interface EditorSession : AutoCloseable {
/** The [ComponentName] of the watch face being edited. */
@@ -99,8 +99,10 @@
@get:RequiresApi(Build.VERSION_CODES.R)
public val watchFaceId: WatchFaceId
- /** The current [UserStyle]. Assigning to this will cause the style to update. However, styling
- * changes to the watch face will be reverted upon exit. */
+ /**
+ * The current [UserStyle]. Assigning to this will cause the style to update. However, styling
+ * changes to the watch face will be reverted upon exit.
+ */
public var userStyle: UserStyle
/** The UTC reference preview time for this watch face in milliseconds since the epoch. */
diff --git a/wear/wear-watchface-editor/src/main/java/androidx/wear/watchface/editor/WatchFaceEditorContract.kt b/wear/wear-watchface-editor/src/main/java/androidx/wear/watchface/editor/WatchFaceEditorContract.kt
index 2cd6547..1e95ae4 100644
--- a/wear/wear-watchface-editor/src/main/java/androidx/wear/watchface/editor/WatchFaceEditorContract.kt
+++ b/wear/wear-watchface-editor/src/main/java/androidx/wear/watchface/editor/WatchFaceEditorContract.kt
@@ -53,8 +53,7 @@
* @param renderParameters The [RenderParameters] to use when rendering the screen shot
* @param calendarTimeMillis The UTC time in milliseconds since the epoch to render with. If
* [EditorSession.DEFAULT_PREVIEW_TIME_MILLIS] is passed then the watch face's default preview time
- * will be
- * used.
+ * will be used.
*/
public class PreviewScreenshotParams(
public val renderParameters: RenderParameters,
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 73891ce..cbe0b02 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
@@ -34,14 +34,11 @@
* instance with [MutableUserStyle.toUserStyle].
*
* @param selectedOptions The [UserStyleSetting.Option] selected for each [UserStyleSetting]
+ * @param copySelectedOptions Whether to create a copy of the provided [selectedOptions]. If
+ * `false`, no mutable copy of the [selectedOptions] map should be retained outside this class.
*/
public class UserStyle private constructor(
- /** The selected option for each setting. */
selectedOptions: Map<UserStyleSetting, UserStyleSetting.Option>,
- /**
- * Whether to create a copy of the provided [selectedOptions]. If false, no mutable copy of
- * the [selectedOptions] map should be retained outside this class.
- */
copySelectedOptions: Boolean
) : Iterable<Map.Entry<UserStyleSetting, UserStyleSetting.Option>> {
private val selectedOptions =
@@ -322,8 +319,7 @@
* @param userStyleSettings The user configurable style categories associated with this watch face.
* Empty if the watch face doesn't support user styling. Note we allow at most one
* [UserStyleSetting.ComplicationSlotsUserStyleSetting] and one
- * [UserStyleSetting.CustomValueUserStyleSetting]
- * in the list.
+ * [UserStyleSetting.CustomValueUserStyleSetting] in the list.
*/
public class UserStyleSchema(
public val userStyleSettings: List<UserStyleSetting>
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 86c8c07..cca7fe4 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
@@ -261,8 +261,8 @@
* an arbitrary value depending on the nature of the style setting.
*
* @property id Machine readable [Id] for the style setting. Identifier for the option (or the
- * option itself for [CustomValueUserStyleSetting.CustomValueOption]), must be unique
- * within the UserStyleSetting. Short ids are encouraged.
+ * option itself for [CustomValueUserStyleSetting.CustomValueOption]), must be unique within
+ * the UserStyleSetting. Short ids are encouraged.
*/
public abstract class Option(public val id: Id) {
/**
@@ -278,6 +278,8 @@
/**
* Machine readable identifier for [Option]s. The length of this identifier may not exceed
* [MAX_LENGTH].
+ *
+ * @param value The [ByteArray] value of this Id.
*/
public class Id(public val value: ByteArray) {
/**
@@ -482,9 +484,11 @@
/** Returns the default value. */
public fun getDefaultValue(): Boolean = (options[defaultOptionIndex] as BooleanOption).value
- /** Represents a true or false option in the [BooleanUserStyleSetting]. */
+ /**
+ * Represents a true or false option in the [BooleanUserStyleSetting].
+ * @param value The boolean value this instance represents.
+ */
public class BooleanOption private constructor(
- /** The boolean value this instance represents. */
public val value: Boolean
) : Option(
Id(ByteArray(1).apply { this[0] = if (value) 1 else 0 })
@@ -560,8 +564,13 @@
@get:SuppressWarnings("AutoBoxing")
public val accessibilityTraversalIndex: Int? = null
) {
+ /**
+ * Constructs a [ComplicationSlotOverlay].Builder.
+ *
+ * @param complicationSlotId The id of the [androidx.wear.watchface.ComplicationSlot]
+ * to configure.
+ */
public class Builder(
- /** The id of the [androidx.wear.watchface.ComplicationSlot] to configure. */
private val complicationSlotId: Int
) {
private var enabled: Boolean? = null
@@ -1487,8 +1496,8 @@
)
/**
- * An application specific custom value. NB the [CustomValueOption.customValue] is the
- * same as the [CustomValueOption.id].
+ * An application specific custom value. NB the [CustomValueOption.customValue] is the same
+ * as the [CustomValueOption.id].
*/
public class CustomValueOption : Option {
/* The [ByteArray] value for this option which is the same as the [id]. */
diff --git a/wear/wear-watchface/src/main/java/androidx/wear/watchface/Renderer.kt b/wear/wear-watchface/src/main/java/androidx/wear/watchface/Renderer.kt
index 083f409..0da2f9f 100644
--- a/wear/wear-watchface/src/main/java/androidx/wear/watchface/Renderer.kt
+++ b/wear/wear-watchface/src/main/java/androidx/wear/watchface/Renderer.kt
@@ -316,9 +316,9 @@
* @param interactiveDrawModeUpdateDelayMillis The interval in milliseconds between frames in
* interactive [DrawMode]s. To render at 60hz set to 16. Note when battery is low, the frame
* rate will be clamped to 10fps. Watch faces are recommended to use lower frame rates if
- * possible for better battery life. Variable frame rates can also help preserve battery
- * life, e.g. if a watch face has a short animation once per second it can adjust the frame
- * rate inorder to sleep when not animating.
+ * possible for better battery life. Variable frame rates can also help preserve battery life,
+ * e.g. if a watch face has a short animation once per second it can adjust the framerate
+ * inorder to sleep when not animating.
*/
public abstract class CanvasRenderer @WorkerThread constructor(
surfaceHolder: SurfaceHolder,
diff --git a/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFace.kt b/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFace.kt
index 7599696..b6f9261 100644
--- a/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFace.kt
+++ b/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFace.kt
@@ -64,7 +64,7 @@
import kotlin.math.max
// Human reaction time is limited to ~100ms.
-private const val MIN_PERCEPTABLE_DELAY_MILLIS = 100
+private const val MIN_PERCEPTIBLE_DELAY_MILLIS = 100
// Zero is a special value meaning we will accept the system's choice for the
// display frame rate, which is the default behavior if this function isn't called.
@@ -628,20 +628,17 @@
}
internal fun invalidateIfNotAnimating() {
- // Ensure we render a frame if the ComplicationSlot needs rendering, e.g.
- // because it loaded an image. However if we're animating there's no need
- // to trigger an extra invalidation.
+ // Ensure we render a frame if the ComplicationSlot needs rendering, e.g. because it loaded
+ // an image. However if we're animating there's no need to trigger an extra invalidation.
if (!renderer.shouldAnimate() || computeDelayTillNextFrame(
nextDrawTimeMillis,
systemTimeProvider.getSystemTimeMillis()
- ) > MIN_PERCEPTABLE_DELAY_MILLIS
+ ) > MIN_PERCEPTIBLE_DELAY_MILLIS
) {
watchFaceHostApi.invalidate()
}
}
- internal fun createWFEditorDelegate() = WFEditorDelegate() as WatchFace.EditorDelegate
-
internal inner class WFEditorDelegate : WatchFace.EditorDelegate {
override val userStyleSchema: UserStyleSchema
get() = currentUserStyleRepository.schema
@@ -716,9 +713,8 @@
(batteryPercent < INITIAL_LOW_BATTERY_THRESHOLD) && !isCharging
}
- /**
- * Called by the system in response to remote configuration, on the main thread.
- */
+ /** Called by the system in response to remote configuration. */
+ @UiThread
internal fun onSetStyleInternal(style: UserStyle) {
// No need to echo the userStyle back.
inOnSetStyle = true
@@ -778,9 +774,8 @@
}
}
- /**
- * Sets the calendar's time in milliseconds adjusted by the mock time controls.
- */
+ /** Sets the calendar's time in milliseconds adjusted by the mock time controls. */
+ @UiThread
private fun setCalendarTime(timeMillis: Long) {
// This adjustment allows time to be sped up or slowed down and to wrap between two
// instants. This is useful when developing animations that occur infrequently (e.g.
@@ -860,7 +855,7 @@
// Drop frames if needed (happens when onDraw is slow).
if (nextFrameTimeMillis <= currentTimeMillis) {
// Compute the next runtime after currentTimeMillis with the same phase as
- // beginFrameTimeMillis to keep the animation smooth.
+ // beginFrameTimeMillis to keep the animation smooth.
val phaseAdjust =
updateRateMillis +
((nextFrameTimeMillis - currentTimeMillis) % updateRateMillis)
diff --git a/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFaceHostApi.kt b/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFaceHostApi.kt
index f25d5ad..4d940fe 100644
--- a/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFaceHostApi.kt
+++ b/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFaceHostApi.kt
@@ -90,16 +90,16 @@
* that may be used before your watch face has the permission, use a safe complication data
* source instead.
*
- * A complication data source not satisfying the above conditions may still be set as a default using
- * this method, but the watch face will receive placeholder data of type
+ * A complication data source not satisfying the above conditions may still be set as a default
+ * using this method, but the watch face will receive placeholder data of type
* [ComplicationData.TYPE_NO_PERMISSION] until the permission has been granted.
*
* @param complicationSlotId The [ComplicationSlot] id.
* @param dataSources data sources The list of non-system complication data sources to try in
* order before falling back to
* fallbackSystemProvider. This list may be null.
- * @param fallbackSystemProvider The system complication data source to use if none of the complication data sources could be
- * used.
+ * @param fallbackSystemProvider The system complication data source to use if none of the
+ * complication data sources could be used.
* @param type The type of complication data that should be provided. Must be one of the types
* defined in [ComplicationData].
*/
diff --git a/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFaceService.kt b/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFaceService.kt
index 3a5fdff..dde6ffa 100644
--- a/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFaceService.kt
+++ b/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFaceService.kt
@@ -736,7 +736,7 @@
internal var pendingUserStyle: UserStyleWireFormat? = null
/**
- * Whether or not we allow watchfaces to animate. In some tests or for headless
+ * Whether or not we allow watch faces to animate. In some tests or for headless
* rendering (for remote config) we don't want this.
*/
internal var allowWatchfaceToAnimate = allowWatchFaceToAnimate()
@@ -911,7 +911,7 @@
ambientUpdateWakelock.acquire()
// It's unlikely an ambient tick would be sent to a watch face that hasn't loaded
// yet. The watch face will render at least once upon loading so we don't need to do
- // anyhting special here.
+ // anything special here.
getWatchFaceImplOrNull()?.renderer?.invalidate()
ambientUpdateWakelock.acquire(SURFACE_DRAW_TIMEOUT_MS)
}
@@ -997,14 +997,6 @@
}
}
- internal fun clearComplicationData() {
- val watchFaceImpl = getWatchFaceImplOrNull()
- require(watchFaceImpl != null) {
- "WatchFace must have been created first"
- }
- watchFaceImpl.clearComplicationData()
- }
-
@UiThread
internal fun setComplicationDataList(
complicationDataWireFormats: MutableList<IdAndComplicationDataWireFormat>
@@ -1440,7 +1432,7 @@
initStyleAndComplicationsDone.complete(Unit)
// validateSchemaWireSize is fairly expensive so only perform it for
- // interactive watchfaces.
+ // interactive watch faces.
if (!watchState.isHeadless) {
validateSchemaWireSize(currentUserStyleRepository.schema)
}
@@ -1508,7 +1500,7 @@
initStyleAndComplicationsDone.await()
// Its possible a second getOrCreateInteractiveWatchFaceClient call came in before
- // the watch face for the first one had finished initalizing, in that case we want
+ // the watch face for the first one had finished initializing, in that case we want
// to apply the updated style. NB pendingUserStyle is accessed on the UiThread so
// there shouldn't be any problems with race conditions.
pendingUserStyle?.let {