diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-03-16 10:21:04 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2022-03-16 10:21:04 +0000 |
commit | 38c02ea495b416f7db83faaefb8674d94f0c2dfc (patch) | |
tree | 18e662e84eb3adb0b9ae94c7c89bf49ac696ca60 | |
parent | aeac272715afdfd0af7e59df263a10134ea73aac (diff) | |
parent | 0617d4e2170d973e676f16d2b501c2d0b486da43 (diff) | |
download | support-snap-temp-L19200000953722026.tar.gz |
Merge "Snap for 8296668 from 61f57943a7be8ed44856a4c2d48135ef0ac99b45 to androidx-mediarouter-release" into androidx-mediarouter-releasesnap-temp-L31600000953713088snap-temp-L19200000953722026
42 files changed, 863 insertions, 1583 deletions
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/view/menu/BaseMenuWrapper.java b/appcompat/appcompat/src/main/java/androidx/appcompat/view/menu/BaseMenuWrapper.java index 8d3141ce2f5..ad954d0b846 100644 --- a/appcompat/appcompat/src/main/java/androidx/appcompat/view/menu/BaseMenuWrapper.java +++ b/appcompat/appcompat/src/main/java/androidx/appcompat/view/menu/BaseMenuWrapper.java @@ -45,7 +45,7 @@ abstract class BaseMenuWrapper { } // First check if we already have a wrapper for this item - MenuItem wrappedItem = mMenuItems.get(supportMenuItem); + MenuItem wrappedItem = mMenuItems.get(menuItem); if (null == wrappedItem) { // ... if not, create one and add it to our map diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXRootImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXRootImplPlugin.kt index 6a34e514042..fce3f3a8881 100644 --- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXRootImplPlugin.kt +++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXRootImplPlugin.kt @@ -28,11 +28,10 @@ import androidx.build.uptodatedness.TaskUpToDateValidator import com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION import com.android.build.gradle.AppPlugin import com.android.build.gradle.LibraryPlugin -import java.io.File -import java.util.Locale -import java.util.concurrent.ConcurrentHashMap +import org.gradle.api.GradleException import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalogsExtension import org.gradle.api.artifacts.component.ModuleComponentSelector import org.gradle.api.plugins.JavaPlugin import org.gradle.api.tasks.bundling.Zip @@ -40,6 +39,9 @@ import org.gradle.api.tasks.bundling.ZipEntryCompression import org.gradle.build.event.BuildEventsListenerRegistry import org.gradle.kotlin.dsl.KotlinClosure1 import org.gradle.kotlin.dsl.extra +import java.io.File +import java.util.Locale +import java.util.concurrent.ConcurrentHashMap abstract class AndroidXRootImplPlugin : Plugin<Project> { @Suppress("UnstableApiUsage") @@ -263,11 +265,22 @@ abstract class AndroidXRootImplPlugin : Plugin<Project> { } private fun Project.setDependencyVersions() { - androidx.build.dependencies.kotlinVersion = getVersionByName("kotlin") - androidx.build.dependencies.kotlinNativeVersion = getVersionByName("kotlinNative") - androidx.build.dependencies.kspVersion = getVersionByName("ksp") - androidx.build.dependencies.agpVersion = getVersionByName("androidGradlePlugin") - androidx.build.dependencies.guavaVersion = getVersionByName("guavaJre") + val libs = project.extensions.getByType( + VersionCatalogsExtension::class.java + ).find("libs").get() + fun getVersion(key: String): String { + val version = libs.findVersion(key) + return if (version.isPresent) { + version.get().requiredVersion + } else { + throw GradleException("Could not find a version for `$key`") + } + } + androidx.build.dependencies.kotlinVersion = getVersion("kotlin") + androidx.build.dependencies.kotlinNativeVersion = getVersion("kotlinNative") + androidx.build.dependencies.kspVersion = getVersion("ksp") + androidx.build.dependencies.agpVersion = getVersion("androidGradlePlugin") + androidx.build.dependencies.guavaVersion = getVersion("guavaJre") } companion object { diff --git a/buildSrc/private/src/main/kotlin/androidx/build/ListTaskOutputsTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/ListTaskOutputsTask.kt index 005ba3a16a1..20ee6fbcc05 100644 --- a/buildSrc/private/src/main/kotlin/androidx/build/ListTaskOutputsTask.kt +++ b/buildSrc/private/src/main/kotlin/androidx/build/ListTaskOutputsTask.kt @@ -123,9 +123,6 @@ val taskNamesKnownToDuplicateOutputs = setOf( // To-be removed when we can use updateLintBaselineDebug "replaceLintBaseline", "updateLintBaselineDebug", - // b/224564238 - "updateLintBaselineWithExpandProjectionDebug", - "updateLintBaselineWithExpandProjectionRelease" ) fun shouldValidateTaskOutput(task: Task): Boolean { diff --git a/buildSrc/private/src/main/kotlin/androidx/build/VersionCatalogExtensions.kt b/buildSrc/private/src/main/kotlin/androidx/build/VersionCatalogExtensions.kt deleted file mode 100644 index 7839332bac4..00000000000 --- a/buildSrc/private/src/main/kotlin/androidx/build/VersionCatalogExtensions.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2022 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.build - -import org.gradle.api.GradleException -import org.gradle.api.Project -import org.gradle.api.artifacts.MinimalExternalModuleDependency -import org.gradle.api.artifacts.VersionCatalogsExtension - -fun Project.getLibraryByName(name: String): MinimalExternalModuleDependency { - val libs = project.extensions.getByType( - VersionCatalogsExtension::class.java - ).find("libs").get() - val library = libs.findLibrary(name) - return if (library.isPresent) { - library.get().get() - } else { - throw GradleException("Could not find a library for `$name`") - } -} - -fun Project.getVersionByName(name: String): String { - val libs = project.extensions.getByType( - VersionCatalogsExtension::class.java - ).find("libs").get() - val version = libs.findVersion(name) - return if (version.isPresent) { - version.get().requiredVersion - } else { - throw GradleException("Could not find a version for `$name`") - } -} diff --git a/buildSrc/private/src/main/kotlin/androidx/build/docs/AndroidXDocsImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/docs/AndroidXDocsImplPlugin.kt index ba334db3a09..0cc094c779a 100644 --- a/buildSrc/private/src/main/kotlin/androidx/build/docs/AndroidXDocsImplPlugin.kt +++ b/buildSrc/private/src/main/kotlin/androidx/build/docs/AndroidXDocsImplPlugin.kt @@ -29,13 +29,9 @@ import androidx.build.getBuildId import androidx.build.getCheckoutRoot import androidx.build.getDistributionDirectory import androidx.build.getKeystore -import androidx.build.getLibraryByName import com.android.build.api.attributes.BuildTypeAttr import com.android.build.gradle.LibraryExtension import com.android.build.gradle.LibraryPlugin -import java.io.File -import java.io.FileNotFoundException -import javax.inject.Inject import org.gradle.api.DefaultTask import org.gradle.api.Plugin import org.gradle.api.Project @@ -65,6 +61,9 @@ import org.gradle.kotlin.dsl.named import org.gradle.kotlin.dsl.register import org.jetbrains.dokka.gradle.DokkaAndroidTask import org.jetbrains.dokka.gradle.PackageOptions +import java.io.File +import java.io.FileNotFoundException +import javax.inject.Inject /** * Plugin that allows to build documentation for a given set of prebuilt and tip of tree projects. @@ -338,11 +337,12 @@ abstract class AndroidXDocsImplPlugin : Plugin<Project> { val generatedDocsDir = project.file("${project.buildDir}/dackkaDocs") val dackkaConfiguration = project.configurations.create("dackka").apply { - dependencies.add(project.dependencies.create(project.getLibraryByName("dackka"))) + dependencies.add(project.dependencies.create(DACKKA_DEPENDENCY)) } val dackkaTask = project.tasks.register("dackkaDocs", DackkaTask::class.java) { task -> task.apply { + dependsOn(dackkaConfiguration) dependsOn(unzipDocsTask) dependsOn(unzipSamplesTask) @@ -641,6 +641,7 @@ abstract class SourcesVariantRule : ComponentMetadataRule { } } +private const val DACKKA_DEPENDENCY = "com.google.devsite:dackka:0.0.15" private const val DOCLAVA_DEPENDENCY = "com.android:doclava:1.0.6" // List of packages to exclude from both Java and Kotlin refdoc generation diff --git a/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt b/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt index 83e8fa4fa5c..7df8cf5dd38 100644 --- a/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt +++ b/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt @@ -17,14 +17,11 @@ package androidx.build.metalava import androidx.build.checkapi.ApiLocation -import androidx.build.getLibraryByName import androidx.build.java.JavaCompileInputs import androidx.build.logging.TERMINAL_RED import androidx.build.logging.TERMINAL_RESET -import java.io.ByteArrayOutputStream -import java.io.File -import javax.inject.Inject import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalogsExtension import org.gradle.api.file.FileCollection import org.gradle.api.provider.ListProperty import org.gradle.api.provider.SetProperty @@ -32,6 +29,9 @@ import org.gradle.process.ExecOperations import org.gradle.workers.WorkAction import org.gradle.workers.WorkParameters import org.gradle.workers.WorkerExecutor +import java.io.ByteArrayOutputStream +import java.io.File +import javax.inject.Inject // MetalavaRunner stores common configuration for executing Metalava @@ -92,7 +92,13 @@ abstract class MetalavaWorkAction @Inject constructor( fun Project.getMetalavaClasspath(): FileCollection { val configuration = configurations.findByName("metalava") ?: configurations.create("metalava") { - it.dependencies.add(dependencies.create(getLibraryByName("metalava"))) + val libs = project.extensions.getByType( + VersionCatalogsExtension::class.java + ).find("libs").get() + val dependency = dependencies.create( + libs.findLibrary("metalava").get().get() + ) + it.dependencies.add(dependency) } return project.files(configuration) } diff --git a/buildSrc/private/src/main/kotlin/androidx/build/studio/StudioTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/studio/StudioTask.kt index 25c9186c53a..2029b1894fa 100644 --- a/buildSrc/private/src/main/kotlin/androidx/build/studio/StudioTask.kt +++ b/buildSrc/private/src/main/kotlin/androidx/build/studio/StudioTask.kt @@ -18,7 +18,6 @@ package androidx.build.studio import androidx.build.StudioType import androidx.build.getSupportRootFolder -import androidx.build.getVersionByName import com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION import java.io.File import java.nio.file.Files @@ -27,6 +26,7 @@ import javax.inject.Inject import org.gradle.api.DefaultTask import org.gradle.api.GradleException import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalogsExtension import org.gradle.api.internal.tasks.userinput.UserInputHandler import org.gradle.api.plugins.ExtraPropertiesExtension import org.gradle.api.tasks.Internal @@ -69,7 +69,19 @@ abstract class StudioTask : DefaultTask() { protected open val installParentDir: File = project.rootDir private val studioVersion by lazy { - project.getVersionByName("androidStudio") + val libs = project.extensions.getByType( + VersionCatalogsExtension::class.java + ).find("libs").get() + + fun getVersion(key: String): String { + val version = libs.findVersion(key) + return if (version.isPresent) { + version.get().requiredVersion + } else { + throw GradleException("Could not find a version for `$key`") + } + } + getVersion("androidStudio") } /** diff --git a/camera/camera-video/src/androidTest/java/androidx/camera/video/RecorderTest.kt b/camera/camera-video/src/androidTest/java/androidx/camera/video/RecorderTest.kt index ef032cea85e..29ed1e27479 100644 --- a/camera/camera-video/src/androidTest/java/androidx/camera/video/RecorderTest.kt +++ b/camera/camera-video/src/androidTest/java/androidx/camera/video/RecorderTest.kt @@ -43,14 +43,11 @@ import androidx.camera.testing.CameraXUtil import androidx.camera.testing.GarbageCollectionUtil import androidx.camera.testing.LabTestRule import androidx.camera.testing.SurfaceTextureProvider -import androidx.camera.testing.asFlow import androidx.camera.video.VideoRecordEvent.Finalize.ERROR_FILE_SIZE_LIMIT_REACHED import androidx.camera.video.VideoRecordEvent.Finalize.ERROR_INVALID_OUTPUT_OPTIONS -import androidx.camera.video.VideoRecordEvent.Finalize.ERROR_RECORDER_ERROR import androidx.camera.video.VideoRecordEvent.Finalize.ERROR_SOURCE_INACTIVE import androidx.camera.video.internal.compat.quirk.DeactivateEncoderSurfaceBeforeStopEncoderQuirk import androidx.camera.video.internal.compat.quirk.DeviceQuirks -import androidx.camera.video.internal.encoder.InvalidConfigException import androidx.core.util.Consumer import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 @@ -59,16 +56,7 @@ import androidx.test.filters.SdkSuppress import androidx.test.platform.app.InstrumentationRegistry import androidx.test.rule.GrantPermissionRule import androidx.testutils.assertThrows -import androidx.testutils.fail import com.google.common.truth.Truth.assertThat -import java.io.File -import java.util.concurrent.Executor -import java.util.concurrent.Semaphore -import java.util.concurrent.TimeUnit -import kotlinx.coroutines.flow.dropWhile -import kotlinx.coroutines.flow.first -import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.withTimeoutOrNull import org.junit.After import org.junit.Assume.assumeFalse import org.junit.Assume.assumeTrue @@ -89,6 +77,10 @@ import org.mockito.Mockito.never import org.mockito.Mockito.timeout import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions +import java.io.File +import java.util.concurrent.Executor +import java.util.concurrent.Semaphore +import java.util.concurrent.TimeUnit private const val FINALIZE_TIMEOUT = 5000L @@ -1074,67 +1066,7 @@ class RecorderTest { } } - @Test - fun canRecoverFromErrorState(): Unit = runBlocking { - // Create a video encoder factory that will fail on first 2 create encoder requests. - // Recorder initialization should fail by 1st encoder creation fail. - // 1st recording request should fail by 2nd encoder creation fail. - // 2nd recording request should be successful. - var createEncoderRequestCount = 0 - val recorder = Recorder.Builder() - .setVideoEncoderFactory { executor, config -> - if (createEncoderRequestCount < 2) { - createEncoderRequestCount++ - throw InvalidConfigException("Create video encoder fail on purpose.") - } else { - Recorder.DEFAULT_ENCODER_FACTORY.createEncoder(executor, config) - } - }.build().apply { onSourceStateChanged(VideoOutput.SourceState.INACTIVE) } - - invokeSurfaceRequest(recorder) - val file = File.createTempFile("CameraX", ".tmp").apply { deleteOnExit() } - - // Wait STREAM_ID_ERROR which indicates Recorder enter the error state. - withTimeoutOrNull(3000) { - recorder.streamInfo.asFlow().dropWhile { it!!.id != StreamInfo.STREAM_ID_ERROR }.first() - } ?: fail("Do not observe STREAM_ID_ERROR from StreamInfo observer.") - - // 1st recording request - clearInvocations(videoRecordEventListener) - recorder.prepareRecording(context, FileOutputOptions.Builder(file).build()) - .withAudioEnabled() - .start(CameraXExecutors.directExecutor(), videoRecordEventListener).let { - val captor = ArgumentCaptor.forClass(VideoRecordEvent::class.java) - verify(videoRecordEventListener, timeout(3000)).accept(captor.capture()) - val finalize = captor.value as VideoRecordEvent.Finalize - assertThat(finalize.error).isEqualTo(ERROR_RECORDER_ERROR) - } - - // 2nd recording request - clearInvocations(videoRecordEventListener) - recorder.prepareRecording(context, FileOutputOptions.Builder(file).build()) - .withAudioEnabled() - .start(CameraXExecutors.directExecutor(), videoRecordEventListener).let { - val inOrder = inOrder(videoRecordEventListener) - inOrder.verify(videoRecordEventListener, timeout(3000L)) - .accept(any(VideoRecordEvent.Start::class.java)) - inOrder.verify(videoRecordEventListener, timeout(15000L).atLeast(5)) - .accept(any(VideoRecordEvent.Status::class.java)) - - it.stopSafely() - - inOrder.verify(videoRecordEventListener, timeout(FINALIZE_TIMEOUT)) - .accept(any(VideoRecordEvent.Finalize::class.java)) - } - - file.delete() - } - private fun invokeSurfaceRequest() { - invokeSurfaceRequest(recorder) - } - - private fun invokeSurfaceRequest(recorder: Recorder) { instrumentation.runOnMainSync { preview.setSurfaceProvider { request: SurfaceRequest -> recorder.onSurfaceRequested(request) diff --git a/camera/camera-video/src/main/java/androidx/camera/video/Recorder.java b/camera/camera-video/src/main/java/androidx/camera/video/Recorder.java index c799b8f4920..297b2e24549 100644 --- a/camera/camera-video/src/main/java/androidx/camera/video/Recorder.java +++ b/camera/camera-video/src/main/java/androidx/camera/video/Recorder.java @@ -46,7 +46,6 @@ import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import androidx.annotation.RequiresPermission; import androidx.annotation.RestrictTo; -import androidx.annotation.VisibleForTesting; import androidx.camera.core.AspectRatio; import androidx.camera.core.Logger; import androidx.camera.core.SurfaceRequest; @@ -79,7 +78,6 @@ import androidx.camera.video.internal.encoder.EncodeException; import androidx.camera.video.internal.encoder.EncodedData; import androidx.camera.video.internal.encoder.Encoder; import androidx.camera.video.internal.encoder.EncoderCallback; -import androidx.camera.video.internal.encoder.EncoderFactory; import androidx.camera.video.internal.encoder.EncoderImpl; import androidx.camera.video.internal.encoder.InvalidConfigException; import androidx.camera.video.internal.encoder.OutputConfig; @@ -237,8 +235,7 @@ public final class Recorder implements VideoOutput { State.INITIALIZING, // Waiting for camera before starting recording. State.IDLING, // Waiting for sequential executor to start pending recording. State.RESETTING, // Waiting for camera/encoders to reset before starting. - State.STOPPING, // Waiting for previous recording to finalize before starting. - State.ERROR // Waiting for re-initialization before starting. + State.STOPPING // Waiting for previous recording to finalize before starting. )); /** @@ -275,8 +272,6 @@ public final class Recorder implements VideoOutput { private static final int PENDING = 1; private static final int NOT_PENDING = 0; private static final long SOURCE_NON_STREAMING_TIMEOUT = 1000L; - @VisibleForTesting - static final EncoderFactory DEFAULT_ENCODER_FACTORY = EncoderImpl::new; private final MutableStateObservable<StreamInfo> mStreamInfo; // Used only by getExecutor() @@ -286,8 +281,6 @@ public final class Recorder implements VideoOutput { private final Executor mExecutor; @SuppressWarnings("WeakerAccess") /* synthetic accessor */ final Executor mSequentialExecutor; - private final EncoderFactory mVideoEncoderFactory; - private final EncoderFactory mAudioEncoderFactory; private final Object mLock = new Object(); //////////////////////////////////////////////////////////////////////////////////////////////// @@ -299,9 +292,6 @@ public final class Recorder implements VideoOutput { // should be null. @GuardedBy("mLock") private State mNonPendingState = null; - @SuppressWarnings("WeakerAccess") /* synthetic accessor */ - @GuardedBy("mLock") - int mStreamId = StreamInfo.STREAM_ID_ANY; @GuardedBy("mLock") @SuppressWarnings("WeakerAccess") /* synthetic accessor */ RecordingRecord mActiveRecordingRecord = null; @@ -313,6 +303,8 @@ public final class Recorder implements VideoOutput { @GuardedBy("mLock") private SourceState mSourceState = SourceState.INACTIVE; @GuardedBy("mLock") + private Throwable mErrorCause; + @GuardedBy("mLock") private long mLastGeneratedRecordingId = 0L; @GuardedBy("mLock") private CallbackToFutureAdapter.Completer<Void> mSourceNonStreamingCompleter = null; @@ -334,8 +326,6 @@ public final class Recorder implements VideoOutput { @SuppressWarnings("WeakerAccess") /* synthetic accessor */ Integer mVideoTrackIndex = null; @SuppressWarnings("WeakerAccess") /* synthetic accessor */ - SurfaceRequest mSurfaceRequest; - @SuppressWarnings("WeakerAccess") /* synthetic accessor */ Surface mSurface = null; @SuppressWarnings("WeakerAccess") /* synthetic accessor */ MediaMuxer mMediaMuxer = null; @@ -344,11 +334,11 @@ public final class Recorder implements VideoOutput { @SuppressWarnings("WeakerAccess") /* synthetic accessor */ AudioSource mAudioSource = null; @SuppressWarnings("WeakerAccess") /* synthetic accessor */ - Encoder mVideoEncoder = null; + EncoderImpl mVideoEncoder = null; @SuppressWarnings("WeakerAccess") /* synthetic accessor */ OutputConfig mVideoOutputConfig = null; @SuppressWarnings("WeakerAccess") /* synthetic accessor */ - Encoder mAudioEncoder = null; + EncoderImpl mAudioEncoder = null; @SuppressWarnings("WeakerAccess") /* synthetic accessor */ OutputConfig mAudioOutputConfig = null; @SuppressWarnings("WeakerAccess") /* synthetic accessor */ @@ -378,25 +368,21 @@ public final class Recorder implements VideoOutput { boolean mIsAudioSourceSilenced = false; //--------------------------------------------------------------------------------------------// - Recorder(@Nullable Executor executor, @NonNull MediaSpec mediaSpec, - @NonNull EncoderFactory videoEncoderFactory, - @NonNull EncoderFactory audioEncoderFactory) { + Recorder(@Nullable Executor executor, @NonNull MediaSpec mediaSpec) { mUserProvidedExecutor = executor; mExecutor = executor != null ? executor : CameraXExecutors.ioExecutor(); mSequentialExecutor = CameraXExecutors.newSequentialExecutor(mExecutor); mMediaSpec = MutableStateObservable.withInitialState(composeRecorderMediaSpec(mediaSpec)); mStreamInfo = MutableStateObservable.withInitialState( - StreamInfo.of(mStreamId, internalStateToStreamState(mState))); - mVideoEncoderFactory = videoEncoderFactory; - mAudioEncoderFactory = audioEncoderFactory; + StreamInfo.of(generateStreamId(), internalStateToStreamState(mState))); } @Override public void onSurfaceRequested(@NonNull SurfaceRequest request) { synchronized (mLock) { Logger.d(TAG, "Surface is requested in state: " + mState + ", Current surface: " - + mStreamId); + + generateStreamId()); switch (mState) { case STOPPING: // Fall-through @@ -407,8 +393,7 @@ public final class Recorder implements VideoOutput { case PENDING_PAUSED: // Fall-through case INITIALIZING: - mSequentialExecutor.execute( - () -> initializeInternal(mSurfaceRequest = request)); + mSequentialExecutor.execute(() -> initializeInternal(request)); break; case IDLING: // Fall-through @@ -418,16 +403,8 @@ public final class Recorder implements VideoOutput { throw new IllegalStateException("Surface was requested when the Recorder had " + "been initialized with state " + mState); case ERROR: - Logger.w(TAG, "Surface was requested when the Recorder had encountered error."); - setState(State.INITIALIZING); - mSequentialExecutor.execute(() -> { - if (mSurfaceRequest != null) { - // If the surface request is already complete, this is a no-op. - mSurfaceRequest.willNotProvideSurface(); - } - initializeInternal(mSurfaceRequest = request); - }); - break; + throw new IllegalStateException("Surface was requested when the Recorder had " + + "encountered error " + mErrorCause); } } } @@ -716,8 +693,6 @@ public final class Recorder implements VideoOutput { // Fall-through case INITIALIZING: // Fall-through - case ERROR: - // Fall-through case IDLING: if (mState == State.IDLING) { Preconditions.checkState( @@ -735,17 +710,6 @@ public final class Recorder implements VideoOutput { if (mState == State.IDLING) { setState(State.PENDING_RECORDING); mSequentialExecutor.execute(this::tryServicePendingRecording); - } else if (mState == State.ERROR) { - setState(State.PENDING_RECORDING); - // Retry initialization. - mSequentialExecutor.execute(() -> { - if (mSurfaceRequest == null) { - throw new AssertionError( - "surface request is required to retry " - + "initialization."); - } - initializeInternal(mSurfaceRequest); - }); } else { setState(State.PENDING_RECORDING); // The recording will automatically start once the initialization @@ -756,6 +720,10 @@ public final class Recorder implements VideoOutput { errorCause = e; } break; + case ERROR: + error = ERROR_RECORDER_ERROR; + errorCause = mErrorCause; + break; } } } @@ -1004,7 +972,7 @@ public final class Recorder implements VideoOutput { } @ExecutedBy("mSequentialExecutor") - private void initializeInternal(@NonNull SurfaceRequest surfaceRequest) { + private void initializeInternal(SurfaceRequest surfaceRequest) { if (mSurface != null) { // There's a valid surface. Provide it directly. surfaceRequest.provideSurface(mSurface, mSequentialExecutor, this::onSurfaceClosed); @@ -1060,7 +1028,8 @@ public final class Recorder implements VideoOutput { break; case ERROR: Logger.e(TAG, - "onInitialized() was invoked when the Recorder had encountered error"); + "onInitialized() was invoked when the Recorder had encountered error " + + mErrorCause); break; case PENDING_PAUSED: startRecordingPaused = true; @@ -1270,7 +1239,7 @@ public final class Recorder implements VideoOutput { AudioEncoderConfig audioEncoderConfig = resolveAudioEncoderConfig(audioMimeInfo, audioSourceSettings, mediaSpec.getAudioSpec()); try { - mAudioEncoder = mAudioEncoderFactory.createEncoder(mExecutor, audioEncoderConfig); + mAudioEncoder = new EncoderImpl(mExecutor, audioEncoderConfig); } catch (InvalidConfigException e) { throw new ResourceCreationException(e); } @@ -1323,8 +1292,9 @@ public final class Recorder implements VideoOutput { mediaSpec.getVideoSpec(), surfaceRequest.getResolution()); try { - mVideoEncoder = mVideoEncoderFactory.createEncoder(mExecutor, config); + mVideoEncoder = new EncoderImpl(mExecutor, config); } catch (InvalidConfigException e) { + surfaceRequest.willNotProvideSurface(); Logger.e(TAG, "Unable to initialize video encoder.", e); onEncoderSetupError(new ResourceCreationException(e)); return; @@ -1337,9 +1307,10 @@ public final class Recorder implements VideoOutput { ((Encoder.SurfaceInput) encoderInput).setOnSurfaceUpdateListener( mSequentialExecutor, surface -> { + Logger.d(TAG, + "Encoder surface updated: " + surface.hashCode() + ", Current surface: " + + generateStreamId()); synchronized (mLock) { - Logger.d(TAG, "Encoder surface updated: " + surface.hashCode() - + ", Current surface: " + mStreamId); switch (mState) { case PENDING_RECORDING: // Fall-through @@ -1374,15 +1345,19 @@ public final class Recorder implements VideoOutput { @NonNull SurfaceRequest surfaceRequest) { if (mSurface != surface) { Surface currentSurface = mSurface; - setSurface(surface); + mSurface = surface; if (currentSurface == null) { // Provide the surface to the first surface request. surfaceRequest.provideSurface(surface, mSequentialExecutor, this::onSurfaceClosed); onInitialized(); } else { - // Encoder updates the surface while there's already an active surface. - // setSurface() will update the StreamInfo with the new stream ID, which will - // trigger VideoCapture to send a new surface request. + // Encoder updates the surface while there's already an active surface. Update + // the StreamInfo with the new stream ID, which will trigger VideoCapture to send + // a new surface request. + synchronized (mLock) { + mStreamInfo.setState( + StreamInfo.of(generateStreamId(), internalStateToStreamState(mState))); + } } } else { Logger.d(TAG, "Video encoder provides the same surface."); @@ -1391,7 +1366,8 @@ public final class Recorder implements VideoOutput { @ExecutedBy("mSequentialExecutor") private void onSurfaceClosed(@NonNull SurfaceRequest.Result result) { - Logger.d(TAG, "Surface closed: " + result.getSurface().hashCode()); + Logger.d(TAG, "Surface closed: " + result.getSurface().hashCode() + ", Current surface: " + + generateStreamId()); Surface resultSurface = result.getSurface(); // The latest surface will be released by the encoder when encoder is released. if (mSurface != resultSurface) { @@ -1399,7 +1375,7 @@ public final class Recorder implements VideoOutput { } else { // Reset the Recorder when the latest surface is terminated. reset(); - setSurface(null); + mSurface = null; } } @@ -1415,8 +1391,8 @@ public final class Recorder implements VideoOutput { mPendingRecordingRecord = null; // Fall-through case INITIALIZING: - setStreamId(StreamInfo.STREAM_ID_ERROR); setState(State.ERROR); + mErrorCause = cause; break; case ERROR: // Already in an error state. Ignore new error. @@ -1933,9 +1909,7 @@ public final class Recorder implements VideoOutput { Futures.addCallback(sourceNonStreamingFuture, new FutureCallback<Void>() { @Override public void onSuccess(@Nullable Void result) { - if (mVideoEncoder instanceof EncoderImpl) { - ((EncoderImpl) mVideoEncoder).signalSourceStopped(); - } + mVideoEncoder.signalSourceStopped(); } @Override @@ -1946,9 +1920,7 @@ public final class Recorder implements VideoOutput { // Even in the case of error, we tell the encoder the source has stopped // because devices with this quirk require that the codec produce a new // surface. - if (mVideoEncoder instanceof EncoderImpl) { - ((EncoderImpl) mVideoEncoder).signalSourceStopped(); - } + mVideoEncoder.signalSourceStopped(); } } }, mSequentialExecutor); @@ -2372,28 +2344,7 @@ public final class Recorder implements VideoOutput { if (streamState == null) { streamState = internalStateToStreamState(mState); } - mStreamInfo.setState(StreamInfo.of(mStreamId, streamState)); - } - - @ExecutedBy("mSequentialExecutor") - private void setSurface(@Nullable Surface surface) { - if (mSurface == surface) { - return; - } - mSurface = surface; - synchronized (mLock) { - setStreamId(surface != null ? surface.hashCode() : StreamInfo.STREAM_ID_ANY); - } - } - - @GuardedBy("mLock") - private void setStreamId(int streamId) { - if (mStreamId == streamId) { - return; - } - Logger.d(TAG, "Transitioning streamId: " + mStreamId + " --> " + streamId); - mStreamId = streamId; - mStreamInfo.setState(StreamInfo.of(streamId, internalStateToStreamState(mState))); + mStreamInfo.setState(StreamInfo.of(generateStreamId(), streamState)); } /** @@ -2417,7 +2368,7 @@ public final class Recorder implements VideoOutput { if (mNonPendingState != state) { mNonPendingState = state; mStreamInfo.setState( - StreamInfo.of(mStreamId, internalStateToStreamState(state))); + StreamInfo.of(generateStreamId(), internalStateToStreamState(state))); } } @@ -2465,6 +2416,11 @@ public final class Recorder implements VideoOutput { return defaultMuxerFormat; } + @ExecutedBy("mSequentialExecutor") + private Integer generateStreamId() { + return mSurface == null ? StreamInfo.STREAM_ID_ANY : mSurface.hashCode(); + } + @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java @AutoValue abstract static class RecordingRecord implements AutoCloseable { @@ -2790,8 +2746,6 @@ public final class Recorder implements VideoOutput { private final MediaSpec.Builder mMediaSpecBuilder; private Executor mExecutor = null; - private EncoderFactory mVideoEncoderFactory = DEFAULT_ENCODER_FACTORY; - private EncoderFactory mAudioEncoderFactory = DEFAULT_ENCODER_FACTORY; /** * Constructor for {@code Recorder.Builder}. @@ -2869,22 +2823,6 @@ public final class Recorder implements VideoOutput { return this; } - /** @hide */ - @RestrictTo(RestrictTo.Scope.LIBRARY) - @NonNull - Builder setVideoEncoderFactory(@NonNull EncoderFactory videoEncoderFactory) { - mVideoEncoderFactory = videoEncoderFactory; - return this; - } - - /** @hide */ - @RestrictTo(RestrictTo.Scope.LIBRARY) - @NonNull - Builder setAudioEncoderFactory(@NonNull EncoderFactory audioEncoderFactory) { - mAudioEncoderFactory = audioEncoderFactory; - return this; - } - /** * Builds the {@link Recorder} instance. * @@ -2894,8 +2832,7 @@ public final class Recorder implements VideoOutput { */ @NonNull public Recorder build() { - return new Recorder(mExecutor, mMediaSpecBuilder.build(), mVideoEncoderFactory, - mAudioEncoderFactory); + return new Recorder(mExecutor, mMediaSpecBuilder.build()); } } } diff --git a/camera/camera-video/src/main/java/androidx/camera/video/StreamInfo.java b/camera/camera-video/src/main/java/androidx/camera/video/StreamInfo.java index 6c0a522b7bf..327bf2a739a 100644 --- a/camera/camera-video/src/main/java/androidx/camera/video/StreamInfo.java +++ b/camera/camera-video/src/main/java/androidx/camera/video/StreamInfo.java @@ -19,6 +19,7 @@ package androidx.camera.video; import android.view.Surface; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import androidx.annotation.RestrictTo; import androidx.camera.core.SurfaceRequest; @@ -27,11 +28,6 @@ import androidx.camera.core.impl.Observable; import com.google.auto.value.AutoValue; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - /** * A class that contains the information of an video output stream. * @@ -42,18 +38,11 @@ import java.util.Set; @AutoValue public abstract class StreamInfo { - /** The stream hasn't been setup. */ - static final int STREAM_ID_ANY = 0; - - /** The stream setup fails. */ - static final int STREAM_ID_ERROR = -1; + static final Integer STREAM_ID_ANY = 0; static final StreamInfo STREAM_INFO_ANY_INACTIVE = StreamInfo.of(STREAM_ID_ANY, StreamState.INACTIVE); - static final Set<Integer> NON_SURFACE_STREAM_ID = Collections.unmodifiableSet( - new HashSet<>(Arrays.asList(STREAM_ID_ANY, STREAM_ID_ERROR))); - static final Observable<StreamInfo> ALWAYS_ACTIVE_OBSERVABLE = ConstantObservable.withValue(StreamInfo.of(STREAM_ID_ANY, StreamState.ACTIVE)); /** @@ -76,7 +65,7 @@ public abstract class StreamInfo { } @NonNull - static StreamInfo of(int id, @NonNull StreamState streamState) { + static StreamInfo of(@Nullable Integer id, @NonNull StreamState streamState) { return new AutoValue_StreamInfo(id, streamState); } @@ -88,10 +77,10 @@ public abstract class StreamInfo { * {@link SurfaceRequest} has to be issued in order to obtain a new {@link Surface} to * continue drawing frames to the {@link VideoOutput}. * - * <p>The ID will be {@link #STREAM_ID_ANY} if the stream hasn't been setup and the ID will be - * {@link #STREAM_ID_ERROR} if the stream setup fails. + * <p>The ID will be {@link #STREAM_ID_ANY} if the stream hasn't been setup. */ - public abstract int getId(); + @NonNull + public abstract Integer getId(); /** * Gets the stream state which can be used to determine if the video output is ready for diff --git a/camera/camera-video/src/main/java/androidx/camera/video/VideoCapabilities.java b/camera/camera-video/src/main/java/androidx/camera/video/VideoCapabilities.java index e39a21cdd6d..ecc33f6de45 100644 --- a/camera/camera-video/src/main/java/androidx/camera/video/VideoCapabilities.java +++ b/camera/camera-video/src/main/java/androidx/camera/video/VideoCapabilities.java @@ -30,7 +30,6 @@ import androidx.camera.core.impl.CamcorderProfileProxy; import androidx.camera.core.impl.CameraInfoInternal; import androidx.camera.core.impl.utils.CompareSizesByArea; import androidx.camera.video.internal.compat.quirk.DeviceQuirks; -import androidx.camera.video.internal.compat.quirk.ExcludeStretchedVideoQualityQuirk; import androidx.camera.video.internal.compat.quirk.VideoEncoderCrashQuirk; import androidx.camera.video.internal.compat.quirk.VideoQualityNotSupportQuirk; import androidx.camera.video.internal.compat.quirk.VideoQualityQuirk; @@ -203,8 +202,7 @@ public final class VideoCapabilities { private boolean isDeviceValidQuality(@NonNull Quality quality) { List<Class<? extends VideoQualityQuirk>> quirkList = Arrays.asList( - ExcludeStretchedVideoQualityQuirk.class, VideoQualityNotSupportQuirk.class, - VideoEncoderCrashQuirk.class); + VideoQualityNotSupportQuirk.class, VideoEncoderCrashQuirk.class); for (Class<? extends VideoQualityQuirk> quirkClass : quirkList) { VideoQualityQuirk quirk = DeviceQuirks.get(quirkClass); diff --git a/camera/camera-video/src/main/java/androidx/camera/video/VideoCapture.java b/camera/camera-video/src/main/java/androidx/camera/video/VideoCapture.java index df4de245539..6506e6468f6 100644 --- a/camera/camera-video/src/main/java/androidx/camera/video/VideoCapture.java +++ b/camera/camera-video/src/main/java/androidx/camera/video/VideoCapture.java @@ -31,7 +31,6 @@ import static androidx.camera.core.internal.TargetConfig.OPTION_TARGET_CLASS; import static androidx.camera.core.internal.TargetConfig.OPTION_TARGET_NAME; import static androidx.camera.core.internal.ThreadConfig.OPTION_BACKGROUND_EXECUTOR; import static androidx.camera.core.internal.UseCaseEventConfig.OPTION_USE_CASE_EVENT_CALLBACK; -import static androidx.camera.video.StreamInfo.STREAM_ID_ERROR; import static androidx.camera.video.impl.VideoCaptureConfig.OPTION_VIDEO_OUTPUT; import android.graphics.Rect; @@ -223,6 +222,7 @@ public final class VideoCapture<T extends VideoOutput> extends UseCase { * * @hide */ + @SuppressWarnings("unchecked") @RestrictTo(Scope.LIBRARY_GROUP) @Override public void onStateAttached() { @@ -271,10 +271,7 @@ public final class VideoCapture<T extends VideoOutput> extends UseCase { } } - mStreamInfo = fetchObservableValue(getOutput().getStreamInfo(), - StreamInfo.STREAM_INFO_ANY_INACTIVE); mSessionConfigBuilder = createPipeline(cameraId, config, suggestedResolution); - applyStreamInfoToSessionConfigBuilder(mSessionConfigBuilder, mStreamInfo); updateSessionConfig(mSessionConfigBuilder.build()); // VideoCapture has to be active to apply SessionConfig's template type. notifyActive(); @@ -312,6 +309,7 @@ public final class VideoCapture<T extends VideoOutput> extends UseCase { * * @hide */ + @SuppressWarnings("unchecked") @RestrictTo(Scope.LIBRARY_GROUP) @Override public void onStateDetached() { @@ -423,8 +421,17 @@ public final class VideoCapture<T extends VideoOutput> extends UseCase { mDeferrableSurface.setContainerClass(MediaCodec.class); SessionConfig.Builder sessionConfigBuilder = SessionConfig.Builder.createFrom(config); + if (fetchObservableValue(getOutput().getStreamInfo(), + StreamInfo.STREAM_INFO_ANY_INACTIVE).getStreamState() == StreamState.ACTIVE) { + sessionConfigBuilder.addSurface(mDeferrableSurface); + getOutput().onSourceStateChanged(VideoOutput.SourceState.ACTIVE_STREAMING); + } else { + sessionConfigBuilder.addNonRepeatingSurface(mDeferrableSurface); + getOutput().onSourceStateChanged(VideoOutput.SourceState.ACTIVE_NON_STREAMING); + } sessionConfigBuilder.addErrorListener( (sessionConfig, error) -> resetPipeline(cameraId, config, resolution)); + sessionConfigBuilder.addRepeatingCameraCaptureCallback(new CameraCaptureCallback() { @Override public void onCaptureCompleted(@NonNull CameraCaptureResult cameraCaptureResult) { @@ -473,7 +480,6 @@ public final class VideoCapture<T extends VideoOutput> extends UseCase { if (isCurrentCamera(cameraId)) { // Only reset the pipeline when the bound camera is the same. mSessionConfigBuilder = createPipeline(cameraId, config, resolution); - applyStreamInfoToSessionConfigBuilder(mSessionConfigBuilder, mStreamInfo); updateSessionConfig(mSessionConfigBuilder.build()); notifyReset(); } @@ -525,35 +531,80 @@ public final class VideoCapture<T extends VideoOutput> extends UseCase { // VideoCapture is unbound. return; } - Logger.d(TAG, "Stream info update: old: " + mStreamInfo + " new: " + streamInfo); + if (mStreamInfo.getStreamState() != streamInfo.getStreamState()) { + mSessionConfigBuilder.clearSurfaces(); + boolean isStreamActive = streamInfo.getStreamState() == StreamState.ACTIVE; + if (isStreamActive) { + mSessionConfigBuilder.addSurface(mDeferrableSurface); + } else { + mSessionConfigBuilder.addNonRepeatingSurface(mDeferrableSurface); + } - StreamInfo currentStreamInfo = mStreamInfo; - mStreamInfo = streamInfo; + AtomicReference<CallbackToFutureAdapter.Completer<Void>> surfaceUpdateCompleter = + new AtomicReference<>(); + ListenableFuture<Void> surfaceUpdateFuture = + CallbackToFutureAdapter.getFuture(completer -> { + // Use the completer as the tag to identify the update. + mSessionConfigBuilder.addTag(SURFACE_UPDATE_KEY, completer.hashCode()); + synchronized (mLock) { + if (mSurfaceUpdateCompleter != null) { + // A newer update is issued before the previous update is + // completed. Fail the previous future. + mSurfaceUpdateCompleter.setException(new RuntimeException( + "A newer surface update is completed.")); + } + mSurfaceUpdateCompleter = completer; + surfaceUpdateCompleter.set(completer); + } + return SURFACE_UPDATE_KEY; + }); + + ScheduledFuture<?> timeoutFuture = + CameraXExecutors.myLooperExecutor().schedule(() -> { + if (!surfaceUpdateFuture.isDone()) { + surfaceUpdateCompleter.get().setException(new TimeoutException( + "The surface isn't updated within: " + + SURFACE_UPDATE_TIMEOUT)); + synchronized (mLock) { + if (mSurfaceUpdateCompleter == surfaceUpdateCompleter.get()) { + mSurfaceUpdateCompleter = null; + } + } + } + }, SURFACE_UPDATE_TIMEOUT, TimeUnit.MILLISECONDS); + + Futures.addCallback(surfaceUpdateFuture, new FutureCallback<Void>() { + @Override + public void onSuccess(@Nullable Void result) { + getOutput().onSourceStateChanged( + isStreamActive ? VideoOutput.SourceState.ACTIVE_STREAMING + : VideoOutput.SourceState.ACTIVE_NON_STREAMING); + timeoutFuture.cancel(true); + } + + @Override + public void onFailure(Throwable t) { + Logger.d(TAG, "The surface update future didn't complete.", t); + getOutput().onSourceStateChanged( + isStreamActive ? VideoOutput.SourceState.ACTIVE_STREAMING + : VideoOutput.SourceState.ACTIVE_NON_STREAMING); + timeoutFuture.cancel(true); + } + }, CameraXExecutors.directExecutor()); - // Doing resetPipeline() includes notifyReset/notifyUpdated(). Doing NotifyReset() - // includes notifyUpdated(). So we just take actions on higher order item for - // optimization. - if (!StreamInfo.NON_SURFACE_STREAM_ID.contains(currentStreamInfo.getId()) - && !StreamInfo.NON_SURFACE_STREAM_ID.contains(streamInfo.getId()) - && currentStreamInfo.getId() != streamInfo.getId()) { + updateSessionConfig(mSessionConfigBuilder.build()); + notifyUpdated(); + } + Integer currentStreamId = mStreamInfo.getId(); + if (!currentStreamId.equals(StreamInfo.STREAM_ID_ANY) && !currentStreamId.equals( + streamInfo.getId())) { // Reset pipeline if the stream ids are different, which means there's a new // surface ready to be requested. resetPipeline(getCameraId(), (VideoCaptureConfig<T>) getCurrentConfig(), getAttachedSurfaceResolution()); - } else if ((currentStreamInfo.getId() != STREAM_ID_ERROR - && streamInfo.getId() == STREAM_ID_ERROR) - || (currentStreamInfo.getId() == STREAM_ID_ERROR - && streamInfo.getId() != STREAM_ID_ERROR)) { - // If id switch to STREAM_ID_ERROR, it means VideoOutput is failed to setup video - // stream. The surface should be removed from camera. Vice versa. - applyStreamInfoToSessionConfigBuilder(mSessionConfigBuilder, streamInfo); - updateSessionConfig(mSessionConfigBuilder.build()); - notifyReset(); - } else if (currentStreamInfo.getStreamState() != streamInfo.getStreamState()) { - applyStreamInfoToSessionConfigBuilder(mSessionConfigBuilder, streamInfo); - updateSessionConfig(mSessionConfigBuilder.build()); - notifyUpdated(); + return; } + mStreamInfo = streamInfo; } @Override @@ -562,87 +613,6 @@ public final class VideoCapture<T extends VideoOutput> extends UseCase { } }; - @UiThread - @SuppressWarnings("WeakerAccess") /* synthetic accessor */ - void applyStreamInfoToSessionConfigBuilder(@NonNull SessionConfig.Builder sessionConfigBuilder, - @NonNull StreamInfo streamInfo) { - final boolean isStreamError = streamInfo.getId() == StreamInfo.STREAM_ID_ERROR; - final boolean isStreamActive = streamInfo.getStreamState() == StreamState.ACTIVE; - if (isStreamError && isStreamActive) { - throw new IllegalStateException( - "Unexpected stream state, stream is error but active"); - } - - sessionConfigBuilder.clearSurfaces(); - if (!isStreamError) { - if (isStreamActive) { - sessionConfigBuilder.addSurface(mDeferrableSurface); - } else { - sessionConfigBuilder.addNonRepeatingSurface(mDeferrableSurface); - } - } else { - // Don't attach surface when stream is invalid. - } - - setupSurfaceUpdateNotifier(sessionConfigBuilder, isStreamActive); - } - - private void setupSurfaceUpdateNotifier(@NonNull SessionConfig.Builder sessionConfigBuilder, - boolean isStreamActive) { - AtomicReference<CallbackToFutureAdapter.Completer<Void>> surfaceUpdateCompleter = - new AtomicReference<>(); - ListenableFuture<Void> surfaceUpdateFuture = - CallbackToFutureAdapter.getFuture(completer -> { - // Use the completer as the tag to identify the update. - sessionConfigBuilder.addTag(SURFACE_UPDATE_KEY, completer.hashCode()); - synchronized (mLock) { - if (mSurfaceUpdateCompleter != null) { - // A newer update is issued before the previous update is - // completed. Fail the previous future. - mSurfaceUpdateCompleter.setException(new RuntimeException( - "A newer surface update is completed.")); - } - mSurfaceUpdateCompleter = completer; - surfaceUpdateCompleter.set(completer); - } - return SURFACE_UPDATE_KEY; - }); - - ScheduledFuture<?> timeoutFuture = - CameraXExecutors.myLooperExecutor().schedule(() -> { - if (!surfaceUpdateFuture.isDone()) { - surfaceUpdateCompleter.get().setException(new TimeoutException( - "The surface isn't updated within: " - + SURFACE_UPDATE_TIMEOUT)); - synchronized (mLock) { - if (mSurfaceUpdateCompleter == surfaceUpdateCompleter.get()) { - mSurfaceUpdateCompleter = null; - } - } - } - }, SURFACE_UPDATE_TIMEOUT, TimeUnit.MILLISECONDS); - - Futures.addCallback(surfaceUpdateFuture, new FutureCallback<Void>() { - @Override - public void onSuccess(@Nullable Void result) { - onCompletion(); - } - - @Override - public void onFailure(Throwable t) { - Logger.d(TAG, "The surface update future didn't complete.", t); - onCompletion(); - } - - private void onCompletion() { - getOutput().onSourceStateChanged( - isStreamActive ? VideoOutput.SourceState.ACTIVE_STREAMING - : VideoOutput.SourceState.ACTIVE_NON_STREAMING); - timeoutFuture.cancel(true); - } - }, CameraXExecutors.directExecutor()); - } - /** * Set {@link ImageOutputConfig#OPTION_SUPPORTED_RESOLUTIONS} according to the resolution found * by the {@link QualitySelector} in VideoOutput. diff --git a/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/DeviceQuirksLoader.java b/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/DeviceQuirksLoader.java index 12d4dec7fc3..d5e98954cd4 100644 --- a/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/DeviceQuirksLoader.java +++ b/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/DeviceQuirksLoader.java @@ -62,9 +62,6 @@ public class DeviceQuirksLoader { if (VideoEncoderCrashQuirk.load()) { quirks.add(new VideoEncoderCrashQuirk()); } - if (ExcludeStretchedVideoQualityQuirk.load()) { - quirks.add(new ExcludeStretchedVideoQualityQuirk()); - } return quirks; } diff --git a/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/ExcludeStretchedVideoQualityQuirk.java b/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/ExcludeStretchedVideoQualityQuirk.java deleted file mode 100644 index 7128625d6dc..00000000000 --- a/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/ExcludeStretchedVideoQualityQuirk.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2022 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.video.internal.compat.quirk; - -import android.os.Build; - -import androidx.annotation.NonNull; -import androidx.annotation.RequiresApi; -import androidx.camera.video.Quality; - -/** - * Bug Id: 202792648 - * Description: The captured video is stretched while selecting the quality is greater or - * equality to FHD resolution. - * Device(s): Samsung J4 (sm-j400g) - */ -@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java -public class ExcludeStretchedVideoQualityQuirk implements VideoQualityQuirk { - static boolean load() { - return isSamsungJ4(); - } - - private static boolean isSamsungJ4() { - return "Samsung".equalsIgnoreCase(Build.BRAND) && "SM-J400G".equalsIgnoreCase(Build.MODEL); - } - - /** Checks if the given Quality type is a problematic quality. */ - @Override - public boolean isProblematicVideoQuality(@NonNull Quality quality) { - if (isSamsungJ4()) { - return quality == Quality.FHD || quality == Quality.UHD; - } - return false; - } -} diff --git a/camera/camera-video/src/main/java/androidx/camera/video/internal/encoder/EncoderFactory.java b/camera/camera-video/src/main/java/androidx/camera/video/internal/encoder/EncoderFactory.java deleted file mode 100644 index 829df86fa95..00000000000 --- a/camera/camera-video/src/main/java/androidx/camera/video/internal/encoder/EncoderFactory.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2022 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.video.internal.encoder; - -import androidx.annotation.NonNull; - -import java.util.concurrent.Executor; - -/** Factory to create {@link Encoder} */ -public interface EncoderFactory { - - /** Factory method to create {@link Encoder}. */ - @NonNull - Encoder createEncoder(@NonNull Executor executor, @NonNull EncoderConfig encoderConfig) - throws InvalidConfigException; -} diff --git a/collection/collection/src/jvmMain/java/androidx/collection/ArraySet.java b/collection/collection/src/jvmMain/java/androidx/collection/ArraySet.java index e85e8e13279..eead69d9abc 100644 --- a/collection/collection/src/jvmMain/java/androidx/collection/ArraySet.java +++ b/collection/collection/src/jvmMain/java/androidx/collection/ArraySet.java @@ -56,6 +56,28 @@ public final class ArraySet<E> implements Collection<E>, Set<E> { */ private static final int BASE_SIZE = 4; + /** + * Maximum number of entries to have in array caches. + */ + private static final int CACHE_SIZE = 10; + + /** + * Caches of small array objects to avoid spamming garbage. The cache + * Object[] variable is a pointer to a linked list of array objects. + * The first entry in the array is a pointer to the next array in the + * list; the second entry is a pointer to the int[] hash code array for it. + */ + private static @Nullable Object[] sBaseCache; + private static int sBaseCacheSize; + private static @Nullable Object[] sTwiceBaseCache; + private static int sTwiceBaseCacheSize; + /** + * Separate locks for each cache since each can be accessed independently of the other without + * risk of a deadlock. + */ + private static final Object sBaseCacheLock = new Object(); + private static final Object sTwiceBaseCacheLock = new Object(); + private int[] mHashes; @SuppressWarnings("WeakerAccess") /* synthetic access */ Object[] mArray; @@ -146,12 +168,110 @@ public final class ArraySet<E> implements Collection<E>, Set<E> { return ~end; } + @SuppressWarnings("ArrayToString") private void allocArrays(final int size) { + if (size == (BASE_SIZE * 2)) { + synchronized (sTwiceBaseCacheLock) { + if (sTwiceBaseCache != null) { + final Object[] array = sTwiceBaseCache; + try { + mArray = array; + sTwiceBaseCache = (Object[]) array[0]; + mHashes = (int[]) array[1]; + if (mHashes != null) { + array[0] = array[1] = null; + sTwiceBaseCacheSize--; + if (DEBUG) { + System.out.println(TAG + " Retrieving 2x cache " + mHashes + + " now have " + sTwiceBaseCacheSize + " entries"); + } + return; + } + } catch (ClassCastException e) { + } + // Whoops! Someone trampled the array (probably due to not protecting + // their access with a lock). Our cache is corrupt; report and give up. + System.out.println(TAG + " Found corrupt ArraySet cache: [0]=" + array[0] + + " [1]=" + array[1]); + sTwiceBaseCache = null; + sTwiceBaseCacheSize = 0; + } + } + } else if (size == BASE_SIZE) { + synchronized (sBaseCacheLock) { + if (sBaseCache != null) { + final Object[] array = sBaseCache; + try { + mArray = array; + sBaseCache = (Object[]) array[0]; + mHashes = (int[]) array[1]; + if (mHashes != null) { + array[0] = array[1] = null; + sBaseCacheSize--; + if (DEBUG) { + System.out.println(TAG + " Retrieving 1x cache " + mHashes + + " now have " + sBaseCacheSize + " entries"); + } + return; + } + } catch (ClassCastException e) { + } + // Whoops! Someone trampled the array (probably due to not protecting + // their access with a lock). Our cache is corrupt; report and give up. + System.out.println(TAG + " Found corrupt ArraySet cache: [0]=" + array[0] + + " [1]=" + array[1]); + sBaseCache = null; + sBaseCacheSize = 0; + } + } + } + mHashes = new int[size]; mArray = new Object[size]; } /** + * Make sure <b>NOT</b> to call this method with arrays that can still be modified. In other + * words, don't pass mHashes or mArray in directly. + */ + @SuppressWarnings("ArrayToString") + private static void freeArrays(final int[] hashes, final Object[] array, final int size) { + if (hashes.length == (BASE_SIZE * 2)) { + synchronized (sTwiceBaseCacheLock) { + if (sTwiceBaseCacheSize < CACHE_SIZE) { + array[0] = sTwiceBaseCache; + array[1] = hashes; + for (int i = size - 1; i >= 2; i--) { + array[i] = null; + } + sTwiceBaseCache = array; + sTwiceBaseCacheSize++; + if (DEBUG) { + System.out.println(TAG + " Storing 2x cache " + array + " now have " + + sTwiceBaseCacheSize + " entries"); + } + } + } + } else if (hashes.length == BASE_SIZE) { + synchronized (sBaseCacheLock) { + if (sBaseCacheSize < CACHE_SIZE) { + array[0] = sBaseCache; + array[1] = hashes; + for (int i = size - 1; i >= 2; i--) { + array[i] = null; + } + sBaseCache = array; + sBaseCacheSize++; + if (DEBUG) { + System.out.println(TAG + " Storing 1x cache " + array + " now have " + + sBaseCacheSize + " entries"); + } + } + } + } + } + + /** * Create a new empty ArraySet. The default capacity of an array map is 0, and * will grow once items are added to it. */ @@ -211,9 +331,13 @@ public final class ArraySet<E> implements Collection<E>, Set<E> { @Override public void clear() { if (mSize != 0) { + final int[] ohashes = mHashes; + final Object[] oarray = mArray; + final int osize = mSize; mHashes = ContainerHelpers.EMPTY_INTS; mArray = ContainerHelpers.EMPTY_OBJECTS; mSize = 0; + freeArrays(ohashes, oarray, osize); } if (mSize != 0) { throw new ConcurrentModificationException(); @@ -234,6 +358,7 @@ public final class ArraySet<E> implements Collection<E>, Set<E> { System.arraycopy(ohashes, 0, mHashes, 0, mSize); System.arraycopy(oarray, 0, mArray, 0, mSize); } + freeArrays(ohashes, oarray, mSize); } if (mSize != oSize) { throw new ConcurrentModificationException(); @@ -322,6 +447,8 @@ public final class ArraySet<E> implements Collection<E>, Set<E> { System.arraycopy(ohashes, 0, mHashes, 0, ohashes.length); System.arraycopy(oarray, 0, mArray, 0, oarray.length); } + + freeArrays(ohashes, oarray, oSize); } if (index < oSize) { diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Button.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Button.kt index c9d98e7fb52..3341c8cbbf5 100644 --- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Button.kt +++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Button.kt @@ -36,6 +36,7 @@ import androidx.compose.material3.tokens.FilledButtonTokens import androidx.compose.material3.tokens.FilledTonalButtonTokens import androidx.compose.material3.tokens.OutlinedButtonTokens import androidx.compose.material3.tokens.TextButtonTokens +import androidx.compose.material3.tokens.TypographyTokens import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.Immutable @@ -129,7 +130,7 @@ fun Button( enabled = enabled, ) { CompositionLocalProvider(LocalContentColor provides contentColor) { - ProvideTextStyle(value = MaterialTheme.typography.labelLarge) { + ProvideTextStyle(value = TypographyTokens.LabelLarge) { Row( Modifier.defaultMinSize( minWidth = ButtonDefaults.MinWidth, @@ -164,7 +165,8 @@ fun Button( * - See [OutlinedButton] for a medium-emphasis button with a border. * - See [TextButton] for a low-emphasis button with no border. * - * The default text style for internal [Text] components will be set to [Typography.labelLarge]. + * The default text style for internal [Text] components will be set to + * [TypographyTokens.LabelLarge]. * * @param onClick Will be called when the user clicks the button. * @param modifier Modifier to be applied to the button. @@ -232,7 +234,8 @@ fun ElevatedButton( * - See [OutlinedButton] for a medium-emphasis button with a border. * - See [TextButton] for a low-emphasis button with no border. * - * The default text style for internal [Text] components will be set to [Typography.labelLarge]. + * The default text style for internal [Text] components will be set to + * [TypographyTokens.LabelLarge]. * * @param onClick Will be called when the user clicks the button. * @param modifier Modifier to be applied to the button. @@ -298,7 +301,8 @@ fun FilledTonalButton( * - See [OutlinedButton] for a medium-emphasis button with a border. * - See [TextButton] for a low-emphasis button with no border. * - * The default text style for internal [Text] components will be set to [Typography.labelLarge]. + * The default text style for internal [Text] components will be set to + * [TypographyTokens.LabelLarge]. * * @param onClick Will be called when the user clicks the button. * @param modifier Modifier to be applied to the button. @@ -364,7 +368,8 @@ fun OutlinedButton( * - See [FilledTonalButton] for a middle ground between [OutlinedButton] and [Button]. * - See [OutlinedButton] for a medium-emphasis button with a border. * - * The default text style for internal [Text] components will be set to [Typography.labelLarge]. + * The default text style for internal [Text] components will be set to + * [TypographyTokens.LabelLarge]. * * @param onClick Will be called when the user clicks the button. * @param modifier Modifier to be applied to the button. diff --git a/development/diagnose-build-failure/diagnose-build-failure.sh b/development/diagnose-build-failure/diagnose-build-failure.sh index eaaed58a2fa..aabbd3724d0 100755 --- a/development/diagnose-build-failure/diagnose-build-failure.sh +++ b/development/diagnose-build-failure/diagnose-build-failure.sh @@ -136,7 +136,7 @@ function getBuildCommand() { if [ "$expectedMessage" == "" ]; then testCommand="$* 2>&1" else - testCommand="$* >log 2>&1; $vgrep \"$expectedMessage\" log $grepOptions" + testCommand="$* >log 2>&1; $vgrep '$expectedMessage' log $grepOptions" fi echo "$testCommand" } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d336b6948b4..a427b5f2c6a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -66,7 +66,6 @@ apacheCommonsCodec = { module = "commons-codec:commons-codec", version = "1.15" assertj = { module = "org.assertj:assertj-core", version = "3.11.1" } checkerframework = { module = "org.checkerframework:checker-qual", version = "2.5.3" } constraintLayout = { module = "androidx.constraintlayout:constraintlayout", version = "2.0.1"} -dackka = { module = "com.google.devsite:dackka", version = "0.0.15" } dagger = { module = "com.google.dagger:dagger", version.ref = "dagger" } daggerCompiler = { module = "com.google.dagger:dagger-compiler", version.ref = "dagger" } dexmakerMockito = { module = "com.linkedin.dexmaker:dexmaker-mockito", version.ref = "dexmaker" } @@ -95,7 +94,7 @@ jsr250 = { module = "javax.annotation:javax.annotation-api", version = "1.2" } junit = { module = "junit:junit", version = "4.13.2" } gcmNetworkManager = { module = "com.google.android.gms:play-services-gcm", version = "17.0.0" } googleCompileTesting = { module = "com.google.testing.compile:compile-testing", version = "0.18" } -gson = { module = "com.google.code.gson:gson", version = "2.9.0" } +gson = { module = "com.google.code.gson:gson", version = "2.8.0" } guava = { module = "com.google.guava:guava", version.ref = "guavaJre" } guavaAndroid = { module = "com.google.guava:guava", version = "29.0-android" } guavaListenableFuture = { module = "com.google.guava:listenablefuture", version = "1.0" } diff --git a/gradle/verification-keyring.keys b/gradle/verification-keyring.keys index 64d9964a9b5..87dee1940a1 100644 --- a/gradle/verification-keyring.keys +++ b/gradle/verification-keyring.keys @@ -11881,32 +11881,6 @@ bBI= -----END PGP PUBLIC KEY BLOCK----- pub 47DCFC2A59F59B5B -sub FCB1A11865F6A17A ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: BCPG v1.68 - -mQENBFVB0KABCAC8YRgcTIomAMw865DHxS/tbFgqN9i7M+tgpih1ETJbb4enhIBj -Upeq+MoFCtxN86zGu2gsA4DOMEXVCReJ4O5n0F8E03+NUraCnJjbXLW9eEyRQRaU -sYXDn/3SpXQyZGP0XemHUfG2Gok77mqiqbYGO5PwQoTX09X1a1wvM/GUYS8I5dUh -UY6MwB3IEXaoNIccuNs3exm9ojmnvLO4VZuXcLOizlqxq6+8VbEP9qr06UNLsPDH -vdqLxIUpZWSyYnUQZIrkctsUvlxQMnB/PpzAN9hKvyps6quQv8tD+dyPreT1TJGM -ej4OcJXkQNmDxXu0/GP7X5yPsunKy3MLabutABEBAAG5AQ0EVUHQoAEIAO5EGsMH -zoamrTlkeCb1kTqYJN00BPUCRijj5CJZGsU8LNHMmqeInTHGaERE1alwqRYlnMFa -sA204UFIScd+hBp9z+JgcjTdsC2MNOXzeJ6H4rjO9PL+4Rukldg3LGB8il0+nXO6 -WQ1ksgrRDL9N0k/d60z2hozPl9JY+4AYDg8mCwLR3AIDrgBZA2VNpNQnxlp5tOkG -fFI/hAX+nxqdLHPWskhkMfWrMleqVWvrZLC7iVQrB3rE+1KdNXMLWwULH0g4eHgL -mHpqjYh0tB/BCPDxKM8LA3ZiWLV8BsqD9K716I7979KYKyYH7HCbMj63O2o7FljD -D/x7D0K+g1eDnFMAEQEAAYkBHwQYAQoACQUCVUHQoAIbDAAKCRBH3PwqWfWbWywL -B/9eLiVoRupsRtvJSGlqrDW7+n3ERVQStfNp9mc4k2Ufc74Kr3RWQl+JiQNeCbWz -1e0jJeCbecAnI/pay9mYPcsArKRlw6fYA0XM2HhuLmRzlDrj9bBdEB7Y1DwpeL68 -3IKPQR8eNLYPN2KpJeOvOCZNRrFxpo1/ZK53V6WKWcY6r2RMvlHK5c3wcAMTIhVj -2x8UWlMgJSQAxfOwAvNwsrYQp3vPjMJ0edYDcF+lQfXuRvAiYSiO/TJeDcbvW7IS -Yr0x+F9YR8tVmeEU6WIffkIl/5lFqREi/9zBxNufP+LeJEppmbomyB+/DO+nuT38 -lY2QXQHYHLkAWBidKfXO6kjO -=airW ------END PGP PUBLIC KEY BLOCK----- - -pub 47DCFC2A59F59B5B uid Kevin Wooten <kevin@wooten.com> sub FCB1A11865F6A17A diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 13a3ddaf768..603f4756a7b 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -241,7 +241,6 @@ </trusted-key> <trusted-key id="afa2b1823fc021bfd08c211fd5f4c07a434ab3da" group="com.squareup"/> <trusted-key id="afcc4c7594d09e2182c60e0f7a01b0f236e5430f" group="com.google.code.gson"/> - <trusted-key id="c7be5bcc9fec15518cfda882b0f3710fa64900e7" group="com.google.code.gson"/> <trusted-key id="b02335aa54ccf21e52bbf9abd9c565aa72ba2fdd" group="io.grpc"/> <trusted-key id="b4c70893b62babe8" group="org.apache.logging.log4j"/> <trusted-key id="b57bd58ef6d0a713" group="com.google.protobuf"/> diff --git a/libraryversions.toml b/libraryversions.toml index 2bed73d5d57..0cf015e117c 100644 --- a/libraryversions.toml +++ b/libraryversions.toml @@ -15,7 +15,7 @@ BUILDSRC_TESTS = "1.0.0-alpha01" CAMERA = "1.1.0-beta03" CAMERA_PIPE = "1.0.0-alpha01" CARDVIEW = "1.1.0-alpha01" -CAR_APP = "1.2.0-rc01" +CAR_APP = "1.2.0-beta03" COLLECTION = "1.3.0-alpha01" COLLECTION2 = "1.3.0-alpha01" COMPOSE = "1.2.0-alpha06" @@ -107,7 +107,7 @@ SWIPEREFRESHLAYOUT = "1.2.0-alpha01" TESTEXT = "1.0.0-alpha01" TESTSCREENSHOT = "1.0.0-alpha01" TEXT = "1.0.0-alpha01" -TEXTCLASSIFIER = "1.0.0-alpha04" +TEXTCLASSIFIER = "1.0.0-alpha03" TRACING = "1.1.0-beta03" TRACING_PERFETTO = "1.0.0-alpha01" TRANSITION = "1.5.0-alpha01" diff --git a/lint-checks/src/main/java/androidx/build/lint/BanInlineOptIn.kt b/lint-checks/src/main/java/androidx/build/lint/BanInlineOptIn.kt deleted file mode 100644 index a8192626a8f..00000000000 --- a/lint-checks/src/main/java/androidx/build/lint/BanInlineOptIn.kt +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2022 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.build.lint - -import com.android.tools.lint.client.api.UElementHandler -import com.android.tools.lint.detector.api.Category -import com.android.tools.lint.detector.api.Detector -import com.android.tools.lint.detector.api.Implementation -import com.android.tools.lint.detector.api.Incident -import com.android.tools.lint.detector.api.Issue -import com.android.tools.lint.detector.api.JavaContext -import com.android.tools.lint.detector.api.Scope -import com.android.tools.lint.detector.api.Severity -import org.jetbrains.uast.UMethod - -@Suppress("UnstableApiUsage") -class BanInlineOptIn : Detector(), Detector.UastScanner { - - override fun getApplicableUastTypes() = listOf(UMethod::class.java) - - override fun createUastHandler(context: JavaContext): UElementHandler { - return MethodChecker(context) - } - - private inner class MethodChecker(val context: JavaContext) : UElementHandler() { - override fun visitMethod(node: UMethod) { - val hasOptInAnnotation = context.evaluator.getAnnotation(node, "kotlin.OptIn") != null - - if (context.evaluator.isInline(node) && hasOptInAnnotation) { - val incident = Incident(context, ISSUE) - .location(context.getNameLocation((node))) - .message("Inline functions cannot opt into experimental APIs.") - .scope(node) - context.report(incident) - } - } - } - - companion object { - val ISSUE = Issue.create( - id = "BanInlineOptIn", - briefDescription = "Uses @OptIn annotation on an inline function", - explanation = "Use of the @OptIn annotation is not allowed on inline functions," + - " as libraries using this method will inline the reference to the opted-in" + - " class. This can potentially create a compatibility issue.", - category = Category.CORRECTNESS, - priority = 5, - severity = Severity.ERROR, - implementation = Implementation( - BanInlineOptIn::class.java, - Scope.JAVA_FILE_SCOPE - ) - ) - } -}
\ No newline at end of file diff --git a/lint-checks/src/test/java/androidx/build/lint/BanInlineOptInTest.kt b/lint-checks/src/test/java/androidx/build/lint/BanInlineOptInTest.kt deleted file mode 100644 index e58fb16155f..00000000000 --- a/lint-checks/src/test/java/androidx/build/lint/BanInlineOptInTest.kt +++ /dev/null @@ -1,65 +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. - */ - -@file:Suppress("UnstableApiUsage") - -package androidx.build.lint - -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 - -@RunWith(JUnit4::class) -class BanInlineOptInTest : AbstractLintDetectorTest( - useDetector = BanInlineOptIn(), - useIssues = listOf(BanInlineOptIn.ISSUE), -) { - - @Test - fun `Detect inline function with an OptIn annotation`() { - val input = kotlin( - """ -@RequiresOptIn -annotation class ExperimentalSampleAnnotation - -@OptIn(ExperimentalSampleAnnotation::class) -inline fun String.myInlineFun() = this.length - """.trimIndent() - ) - - /* ktlint-disable max-line-length */ - val expected = """ -src/ExperimentalSampleAnnotation.kt:5: Error: Inline functions cannot opt into experimental APIs. [BanInlineOptIn] -inline fun String.myInlineFun() = this.length - ~~~~~~~~~~~ -1 errors, 0 warnings - """.trimIndent() - /* ktlint-enable max-line-length */ - - check(input).expect(expected) - } - - @Test - fun `Detect inline function without an OptIn annotation`() { - val input = kotlin( - """ -inline fun String.myInlineFun() = this.length - """.trimIndent() - ) - - check(input).expectClean() - } -} diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/PageFetcherSnapshotTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/PageFetcherSnapshotTest.kt index 63f22552451..ce718760287 100644 --- a/paging/paging-common/src/test/kotlin/androidx/paging/PageFetcherSnapshotTest.kt +++ b/paging/paging-common/src/test/kotlin/androidx/paging/PageFetcherSnapshotTest.kt @@ -29,12 +29,6 @@ import androidx.paging.PagingSource.LoadResult.Page import androidx.paging.RemoteMediatorMock.LoadEvent import androidx.paging.TestPagingSource.Companion.LOAD_ERROR import com.google.common.truth.Truth.assertThat -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith -import kotlin.test.assertFalse -import kotlin.test.assertNotNull -import kotlin.test.assertTrue -import kotlin.test.fail import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineStart @@ -57,6 +51,19 @@ import kotlinx.coroutines.flow.takeWhile import kotlinx.coroutines.flow.toList import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.TestCoroutineScope +import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.withContext +import kotlinx.coroutines.yield +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import kotlin.test.assertEquals +import kotlin.test.assertFailsWith +import kotlin.test.assertFalse +import kotlin.test.assertNotNull +import kotlin.test.assertTrue +import kotlin.test.fail import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.UnconfinedTestDispatcher @@ -64,12 +71,6 @@ import kotlinx.coroutines.test.advanceTimeBy import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runBlockingTest import kotlinx.coroutines.test.runCurrent -import kotlinx.coroutines.test.runTest -import kotlinx.coroutines.withContext -import kotlinx.coroutines.yield -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 @ExperimentalPagingApi @OptIn(ExperimentalCoroutinesApi::class) @@ -1614,8 +1615,9 @@ class PageFetcherSnapshotTest { } } + @Suppress("DEPRECATION") // b/220884819 @Test - fun retry_remotePrepend() = runTest { + fun retry_remotePrepend() = runBlockingTest { @OptIn(ExperimentalPagingApi::class) val remoteMediator = object : RemoteMediatorMock() { override suspend fun load( @@ -1663,8 +1665,9 @@ class PageFetcherSnapshotTest { } } + @Suppress("DEPRECATION") // b/220884819 @Test - fun retry_remoteAppend() = runTest { + fun retry_remoteAppend() = runBlockingTest { @OptIn(ExperimentalPagingApi::class) val remoteMediator = object : RemoteMediatorMock() { override suspend fun load( @@ -2912,8 +2915,9 @@ class PageFetcherSnapshotTest { } } + @Suppress("DEPRECATION") // b/220884819 @Test - fun remoteMediator_immediateInvalidation() = runTest { + fun remoteMediator_immediateInvalidation() = runBlockingTest { @OptIn(ExperimentalPagingApi::class) val remoteMediator = object : RemoteMediatorMock() { override suspend fun initialize(): InitializeAction { @@ -2926,13 +2930,7 @@ class PageFetcherSnapshotTest { state: PagingState<Int, Int> ): MediatorResult { super.load(loadType, state) - // Wait for remote events to get sent and observed by PageFetcher, but don't let - // source REFRESH complete yet until we invalidate. - advanceTimeBy(500) currentPagingSource!!.invalidate() - // Wait for second generation to start before letting remote REFRESH finish, but - // ensure that remote REFRESH finishes before source REFRESH does. - delay(100) return MediatorResult.Success(endOfPaginationReached = false) } } @@ -2952,6 +2950,7 @@ class PageFetcherSnapshotTest { ) val fetcherState = collectFetcherState(pager) advanceUntilIdle() + runCurrent() assertThat(fetcherState.pageEventLists).hasSize(2) assertThat(fetcherState.pageEventLists[0]).containsExactly( remoteLoadStateUpdate<Int>( @@ -2967,10 +2966,7 @@ class PageFetcherSnapshotTest { refreshLocal = Loading, refreshRemote = Loading, ), - remoteLoadStateUpdate<Int>( - refreshLocal = Loading, - refreshRemote = NotLoading.Incomplete, - ), + remoteLoadStateUpdate<Int>(refreshLocal = Loading), remoteRefresh( pages = listOf( TransformablePage( @@ -3739,7 +3735,8 @@ class PageFetcherSnapshotTest { uiReceiver!!.retry() } - suspend fun TestScope.awaitIdle() { + @Suppress("DEPRECATION") // b/220884819 + suspend fun TestCoroutineScope.awaitIdle() { yield() advanceUntilIdle() } diff --git a/playground-common/playground-plugin/build.gradle b/playground-common/playground-plugin/build.gradle index 621d9023396..f5801ec931c 100644 --- a/playground-common/playground-plugin/build.gradle +++ b/playground-common/playground-plugin/build.gradle @@ -26,8 +26,6 @@ repositories { dependencies { implementation "com.gradle:gradle-enterprise-gradle-plugin:3.8.1" implementation "com.gradle:common-custom-user-data-gradle-plugin:1.6.3" - testImplementation "junit:junit:4.13" - testImplementation "com.google.truth:truth:1.1.3" } gradlePlugin { diff --git a/playground-common/playground-plugin/src/main/kotlin/androidx/playground/PlaygroundExtension.kt b/playground-common/playground-plugin/src/main/kotlin/androidx/playground/PlaygroundExtension.kt index 28f2663e13b..ee749ea0615 100644 --- a/playground-common/playground-plugin/src/main/kotlin/androidx/playground/PlaygroundExtension.kt +++ b/playground-common/playground-plugin/src/main/kotlin/androidx/playground/PlaygroundExtension.kt @@ -135,11 +135,26 @@ open class PlaygroundExtension @Inject constructor( if (supportRootDir == null) { throw RuntimeException("Must call setupPlayground() first.") } + + // Multiline matcher for anything of the form: + // includeProject(name, path, ...) + // where '...' is anything except the ')' character. + /* ktlint-disable max-line-length */ + val includeProjectPattern = Regex( + """[\n\r\s]*includeProject\("(?<name>[a-z0-9-:]*)",[\n\r\s]*"(?<path>[a-z0-9-\/]+)[^)]+\)$""", + setOf(RegexOption.MULTILINE, RegexOption.IGNORE_CASE) + ).toPattern() val supportSettingsFile = File(supportRootDir, "settings.gradle") - SettingsParser.findProjects(supportSettingsFile).filter { - filter(it.gradlePath) - }.forEach { (projectGradlePath, projectFilePath) -> - includeProject(projectGradlePath, projectFilePath) + val matcher = includeProjectPattern.matcher(supportSettingsFile.readText()) + + while (matcher.find()) { + // check if is an include project line, if so, extract project gradle path and + // file system path and call the filter + val projectGradlePath = matcher.group("name") + val projectFilePath = matcher.group("path") + if (filter(projectGradlePath)) { + includeProject(projectGradlePath, projectFilePath) + } } } diff --git a/playground-common/playground-plugin/src/main/kotlin/androidx/playground/SettingsParser.kt b/playground-common/playground-plugin/src/main/kotlin/androidx/playground/SettingsParser.kt deleted file mode 100644 index 9fbe43a2d69..00000000000 --- a/playground-common/playground-plugin/src/main/kotlin/androidx/playground/SettingsParser.kt +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2022 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.playground - -import java.io.File - -/** - * Helper class to parse the settings.gradle file from the main build and extract a list of - * projects. - */ -internal object SettingsParser { - /** - * Match lines that start with includeProject, followed by a require argument for project gradle - * path and an optional argument for project file path. - */ - /* ktlint-disable max-line-length */ - private val includeProjectPattern = Regex( - """^[\n\r\s]*includeProject\("(?<name>[a-z0-9-:]*)"(,[\n\r\s]*"(?<path>[a-z0-9-/]+))?.*\).*$""", - setOf(RegexOption.MULTILINE, RegexOption.IGNORE_CASE) - ).toPattern() - - fun findProjects( - settingsFile: File, - ): List<IncludedProject> { - return findProjects( - fileContents = settingsFile.readText(Charsets.UTF_8) - ) - } - - fun findProjects( - fileContents: String, - ): List<IncludedProject> { - val matcher = includeProjectPattern.matcher(fileContents) - val includedProjects = mutableListOf<IncludedProject>() - while (matcher.find()) { - // check if is an include project line, if so, extract project gradle path and - // file system path and call the filter - val projectGradlePath = - matcher.group("name") ?: error("Project gradle path should not be null") - val projectFilePath = - matcher.group("path") ?: createFilePathFromGradlePath(projectGradlePath) - includedProjects.add(IncludedProject(projectGradlePath, projectFilePath)) - } - return includedProjects - } - - /** - * Converts a gradle path (e.g. :a:b:c) to a file path (a/b/c) - */ - private fun createFilePathFromGradlePath(gradlePath: String): String { - return gradlePath.trimStart(':').replace(':', '/') - } - - /** - * Represents an included project from the main settings.gradle file. - */ - internal data class IncludedProject( - /** - * Gradle path of the project (using : as separator) - */ - val gradlePath: String, - /** - * File path for the project, relative to support root folder. - */ - val filePath: String - ) -} diff --git a/playground-common/playground-plugin/src/test/kotlin/androidx/playground/SettingsParserTest.kt b/playground-common/playground-plugin/src/test/kotlin/androidx/playground/SettingsParserTest.kt deleted file mode 100644 index 08a0ee7ba64..00000000000 --- a/playground-common/playground-plugin/src/test/kotlin/androidx/playground/SettingsParserTest.kt +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2022 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.playground - -import com.google.common.truth.Truth.assertThat -import org.junit.Test - -class SettingsParserTest { - @Test - fun parseProjects() { - val projects = SettingsParser.findProjects( - """ - includeProject(":no:filepath", [BuildType.MAIN]) - includeProject(":with:filepath", "some/dir", [BuildType.COMPOSE]) - includeProject(":has:spaces:before:include", "dir2", [BuildType.MAIN]) - includeProject(":has:comments:after", "dir3", [BuildType.MAIN]) // some comment - // includeProject("commented", "should not be there", [BuildType.MAIN]) - includeProject("no:build:type") - includeProject("no:build:type:with:path", "dir4") - """.trimIndent() - ) - assertThat( - projects - ).containsExactly( - SettingsParser.IncludedProject( - gradlePath = ":with:filepath", - filePath = "some/dir" - ), - SettingsParser.IncludedProject( - gradlePath = ":no:filepath", - filePath = "no/filepath" - ), - SettingsParser.IncludedProject( - gradlePath = ":has:spaces:before:include", - filePath = "dir2" - ), - SettingsParser.IncludedProject( - gradlePath = ":has:comments:after", - filePath = "dir3" - ), - SettingsParser.IncludedProject( - gradlePath = "no:build:type", - filePath = "no/build/type" - ), - SettingsParser.IncludedProject( - gradlePath = "no:build:type:with:path", - filePath = "dir4" - ) - ) - } -} diff --git a/room/room-runtime-lint/build.gradle b/room/room-runtime-lint/build.gradle deleted file mode 100644 index 662e8e4367c..00000000000 --- a/room/room-runtime-lint/build.gradle +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2022 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. - */ - -import androidx.build.LibraryType - -plugins { - id("AndroidXPlugin") - id("kotlin") -} - -dependencies { - compileOnly(libs.androidLintMinApi) - compileOnly(libs.androidLintChecks) - compileOnly(libs.kotlinStdlib) - - testImplementation(libs.kotlinStdlib) - testImplementation(libs.androidLint) - testImplementation(libs.androidLintTests) - testImplementation(libs.junit) -} - -androidx { - name = "Android Room-Runtime Lint Checks" - type = LibraryType.LINT - mavenGroup = LibraryGroups.ROOM - inceptionYear = "2022" - description = "Android Room-Runtime Lint Checks" -} diff --git a/room/room-runtime-lint/src/main/java/androidx/room/lint/CursorKotlinUseIssueDetector.kt b/room/room-runtime-lint/src/main/java/androidx/room/lint/CursorKotlinUseIssueDetector.kt deleted file mode 100644 index 97e69b086d7..00000000000 --- a/room/room-runtime-lint/src/main/java/androidx/room/lint/CursorKotlinUseIssueDetector.kt +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2022 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.room.lint - -import com.android.tools.lint.checks.VersionChecks.Companion.isPrecededByVersionCheckExit -import com.android.tools.lint.checks.VersionChecks.Companion.isWithinVersionCheckConditional -import com.android.tools.lint.detector.api.Category -import com.android.tools.lint.detector.api.Detector -import com.android.tools.lint.detector.api.Implementation -import com.android.tools.lint.detector.api.Incident -import com.android.tools.lint.detector.api.Issue -import com.android.tools.lint.detector.api.JavaContext -import com.android.tools.lint.detector.api.Scope -import com.android.tools.lint.detector.api.Severity -import com.android.tools.lint.detector.api.SourceCodeScanner -import com.android.tools.lint.detector.api.minSdkLessThan -import com.intellij.psi.PsiMethod -import org.jetbrains.uast.UCallExpression - -class CursorKotlinUseIssueDetector : Detector(), SourceCodeScanner { - companion object { - private const val DESCRIPTION = "Usage of `kotlin.io.use()` with Cursor requires API 16." - val ISSUE = Issue.create( - id = "CursorKotlinUse", - briefDescription = DESCRIPTION, - explanation = """ - The use of `kotlin.io.use()` with `android.database.Cursor` is not safe when min - API level is less than 16 since Cursor does not implement Closeable. - """, - androidSpecific = true, - category = Category.CORRECTNESS, - severity = Severity.FATAL, - implementation = Implementation( - CursorKotlinUseIssueDetector::class.java, Scope.JAVA_FILE_SCOPE - ) - ) - } - - override fun getApplicableMethodNames(): List<String> = listOf("use") - - override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) { - // Skip if `use` is not Kotlin's - if (!context.evaluator.isMemberInClass(method, "kotlin.io.CloseableKt")) { - return - } - // Skip if the receiver is not Android's Cursor - if (node.receiverType?.canonicalText != "android.database.Cursor") { - return - } - // If the call is within an SDK_INT check, then its OK - if ( - isWithinVersionCheckConditional(context, node, 16) || - isPrecededByVersionCheckExit(context, node, 16) - ) { - return - } - context.report( - incident = Incident(ISSUE, DESCRIPTION, context.getLocation(node)), - constraint = minSdkLessThan(16) - ) - } -}
\ No newline at end of file diff --git a/room/room-runtime-lint/src/main/java/androidx/room/lint/RoomIssueRegistry.kt b/room/room-runtime-lint/src/main/java/androidx/room/lint/RoomIssueRegistry.kt deleted file mode 100644 index 577b8025001..00000000000 --- a/room/room-runtime-lint/src/main/java/androidx/room/lint/RoomIssueRegistry.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2022 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.room.lint - -import com.android.tools.lint.client.api.IssueRegistry -import com.android.tools.lint.client.api.Vendor -import com.android.tools.lint.detector.api.CURRENT_API -import com.android.tools.lint.detector.api.Issue - -class RoomIssueRegistry : IssueRegistry() { - override val minApi = CURRENT_API - override val api = 13 - override val issues: List<Issue> = listOf( - CursorKotlinUseIssueDetector.ISSUE, - ) - override val vendor = Vendor( - feedbackUrl = "https://issuetracker.google.com/issues/new?component=413107", - identifier = "androidx.room", - vendorName = "Android Open Source Project", - ) -}
\ No newline at end of file diff --git a/room/room-runtime-lint/src/main/resources/META-INF/services/com.android.tools.lint.client.api.IssueRegistry b/room/room-runtime-lint/src/main/resources/META-INF/services/com.android.tools.lint.client.api.IssueRegistry deleted file mode 100644 index 687cc5ac627..00000000000 --- a/room/room-runtime-lint/src/main/resources/META-INF/services/com.android.tools.lint.client.api.IssueRegistry +++ /dev/null @@ -1 +0,0 @@ -androidx.room.lint.RoomIssueRegistry
\ No newline at end of file diff --git a/room/room-runtime-lint/src/test/java/androidx/room/lint/CursorKotlinUseIssueDetectorTest.kt b/room/room-runtime-lint/src/test/java/androidx/room/lint/CursorKotlinUseIssueDetectorTest.kt deleted file mode 100644 index c9edd9d17ea..00000000000 --- a/room/room-runtime-lint/src/test/java/androidx/room/lint/CursorKotlinUseIssueDetectorTest.kt +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2022 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.room.lint - -import com.android.tools.lint.checks.infrastructure.LintDetectorTest.kotlin -import com.android.tools.lint.checks.infrastructure.LintDetectorTest.manifest -import com.android.tools.lint.checks.infrastructure.TestLintTask -import org.junit.Test - -class CursorKotlinUseIssueDetectorTest { - @Test - fun cursorUseIssueDetectorTest() { - TestLintTask.lint().files( - kotlin( - "com/example/Foo.kt", - """ - package com.example - import android.database.Cursor - fun foo(c: Cursor) { - c.use { - } - } - """.trimIndent() - ).within("src") - ).issues(CursorKotlinUseIssueDetector.ISSUE) - .run() - /* ktlint-disable max-line-length */ - .expect( - """ - src/com/example/Foo.kt:4: Error: Usage of kotlin.io.use() with Cursor requires API 16. [CursorKotlinUse] - c.use { - ^ - 1 errors, 0 warnings - """.trimIndent() - ) - } - - @Test - fun cursorUseIssueDetectorTest_notKotlinUse() { - TestLintTask.lint().files( - kotlin( - "com/example/Foo.kt", - """ - package com.example - import android.database.Cursor - fun foo(c: Cursor) { - c.use { - } - } - fun <R> Cursor.use(block: (Cursor) -> R): R { - return block(this) - } - """.trimIndent() - ).within("src") - ).issues(CursorKotlinUseIssueDetector.ISSUE) - .run() - .expectClean() - } - - @Test - fun cursorUseIssueDetectorTest_minSdkGreaterThan15() { - TestLintTask.lint().files( - manifest().minSdk(18), - kotlin( - "com/example/Foo.kt", - """ - package com.example - import android.database.Cursor - fun foo(c: Cursor) { - c.use { - } - } - """.trimIndent() - ).within("src"), - ).issues(CursorKotlinUseIssueDetector.ISSUE) - .run() - .expectClean() - } - - @Test - fun cursorUseIssueDetectorTest_versionChecked() { - TestLintTask.lint().files( - kotlin( - "com/example/Foo.kt", - """ - package com.example - import android.database.Cursor - import android.os.Build - fun foo(c: Cursor) { - if (Build.VERSION.SDK_INT > 15) { - c.use { } - } - } - """.trimIndent() - ).within("src"), - ).issues(CursorKotlinUseIssueDetector.ISSUE) - .run() - .expectClean() - } -}
\ No newline at end of file diff --git a/room/room-runtime/build.gradle b/room/room-runtime/build.gradle index a7a8db363fd..0cdeecd569b 100644 --- a/room/room-runtime/build.gradle +++ b/room/room-runtime/build.gradle @@ -40,7 +40,6 @@ dependencies { compileOnly("androidx.lifecycle:lifecycle-livedata-core:2.0.0") implementation("androidx.annotation:annotation-experimental:1.1.0-rc01") compileOnly libs.kotlinStdlib // Due to :annotation-experimental - lintChecks(project(":room:room-runtime-lint")) testImplementation("androidx.arch.core:core-testing:2.0.1") testImplementation(libs.junit) diff --git a/room/room-runtime/src/main/java/androidx/room/util/CursorUtil.kt b/room/room-runtime/src/main/java/androidx/room/util/CursorUtil.kt index 1969ad0e13e..accf308e881 100644 --- a/room/room-runtime/src/main/java/androidx/room/util/CursorUtil.kt +++ b/room/room-runtime/src/main/java/androidx/room/util/CursorUtil.kt @@ -24,6 +24,9 @@ import android.os.Build import android.util.Log import androidx.annotation.RestrictTo import androidx.annotation.VisibleForTesting +import java.lang.Exception +import java.lang.IllegalArgumentException +import java.lang.IllegalStateException /** * Copies the given cursor into a in-memory cursor and then closes it. @@ -35,7 +38,7 @@ import androidx.annotation.VisibleForTesting * @param c the cursor to copy. * @return a new cursor containing the same data as the given cursor. */ -fun copyAndClose(c: Cursor): Cursor = c.useCursor { cursor -> +fun copyAndClose(c: Cursor): Cursor = c.use { cursor -> val matrixCursor = MatrixCursor(cursor.columnNames, cursor.count) while (cursor.moveToNext()) { val row = arrayOfNulls<Any>(cursor.columnCount) @@ -134,20 +137,4 @@ fun findColumnIndexBySuffix(columnNames: Array<String>, name: String): Int { } } return -1 -} - -/** - * Backwards compatible function that executes the given block function on this Cursor and then - * closes the Cursor. - */ -internal inline fun <R> Cursor.useCursor(block: (Cursor) -> R): R { - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { - return this.use(block) - } else { - try { - return block(this) - } finally { - this.close() - } - } }
\ No newline at end of file diff --git a/room/room-runtime/src/main/java/androidx/room/util/DBUtil.kt b/room/room-runtime/src/main/java/androidx/room/util/DBUtil.kt index b4768fc0a65..626b0edf7ef 100644 --- a/room/room-runtime/src/main/java/androidx/room/util/DBUtil.kt +++ b/room/room-runtime/src/main/java/androidx/room/util/DBUtil.kt @@ -97,7 +97,7 @@ fun query( */ fun dropFtsSyncTriggers(db: SupportSQLiteDatabase) { val existingTriggers = buildList { - db.query("SELECT name FROM sqlite_master WHERE type = 'trigger'").useCursor { cursor -> + db.query("SELECT name FROM sqlite_master WHERE type = 'trigger'").use { cursor -> while (cursor.moveToNext()) { add(cursor.getString(0)) } @@ -118,7 +118,7 @@ fun foreignKeyCheck( db: SupportSQLiteDatabase, tableName: String ) { - db.query("PRAGMA foreign_key_check(`$tableName`)").useCursor { cursor -> + db.query("PRAGMA foreign_key_check(`$tableName`)").use { cursor -> if (cursor.count > 0) { val errorMsg = processForeignKeyCheckFailure(cursor) throw IllegalStateException(errorMsg) diff --git a/room/room-runtime/src/main/java/androidx/room/util/FtsTableInfo.kt b/room/room-runtime/src/main/java/androidx/room/util/FtsTableInfo.kt index f6fa32d5c6c..87ecec3788f 100644 --- a/room/room-runtime/src/main/java/androidx/room/util/FtsTableInfo.kt +++ b/room/room-runtime/src/main/java/androidx/room/util/FtsTableInfo.kt @@ -94,7 +94,7 @@ class FtsTableInfo( private fun readColumns(database: SupportSQLiteDatabase, tableName: String): Set<String> { return buildSet { - database.query("PRAGMA table_info(`$tableName`)").useCursor { cursor -> + database.query("PRAGMA table_info(`$tableName`)").use { cursor -> if (cursor.columnCount > 0) { val nameIndex = cursor.getColumnIndex("name") while (cursor.moveToNext()) { @@ -108,7 +108,7 @@ class FtsTableInfo( private fun readOptions(database: SupportSQLiteDatabase, tableName: String): Set<String> { val sql = database.query( "SELECT * FROM sqlite_master WHERE `name` = '$tableName'" - ).useCursor { cursor -> + ).use { cursor -> if (cursor.moveToFirst()) { cursor.getString(cursor.getColumnIndexOrThrow("sql")) } else { diff --git a/room/room-runtime/src/main/java/androidx/room/util/TableInfo.kt b/room/room-runtime/src/main/java/androidx/room/util/TableInfo.kt index aa9d4ef0f07..6b0a2837cd9 100644 --- a/room/room-runtime/src/main/java/androidx/room/util/TableInfo.kt +++ b/room/room-runtime/src/main/java/androidx/room/util/TableInfo.kt @@ -479,7 +479,7 @@ private fun readForeignKeys( tableName: String ): Set<TableInfo.ForeignKey> { // this seems to return everything in order but it is not documented so better be safe - database.query("PRAGMA foreign_key_list(`$tableName`)").useCursor { cursor -> + database.query("PRAGMA foreign_key_list(`$tableName`)").use { cursor -> val idColumnIndex = cursor.getColumnIndex("id") val seqColumnIndex = cursor.getColumnIndex("seq") val tableColumnIndex = cursor.getColumnIndex("table") @@ -544,7 +544,7 @@ private fun readColumns( database: SupportSQLiteDatabase, tableName: String ): Map<String, TableInfo.Column> { - database.query("PRAGMA table_info(`$tableName`)").useCursor { cursor -> + database.query("PRAGMA table_info(`$tableName`)").use { cursor -> if (cursor.columnCount <= 0) { return emptyMap() } @@ -582,7 +582,7 @@ private fun readColumns( * @return null if we cannot read the indices due to older sqlite implementations. */ private fun readIndices(database: SupportSQLiteDatabase, tableName: String): Set<TableInfo.Index>? { - database.query("PRAGMA index_list(`$tableName`)").useCursor { cursor -> + database.query("PRAGMA index_list(`$tableName`)").use { cursor -> val nameColumnIndex = cursor.getColumnIndex("name") val originColumnIndex = cursor.getColumnIndex("origin") val uniqueIndex = cursor.getColumnIndex("unique") @@ -615,7 +615,7 @@ private fun readIndex( name: String, unique: Boolean ): TableInfo.Index? { - return database.query("PRAGMA index_xinfo(`$name`)").useCursor { cursor -> + return database.query("PRAGMA index_xinfo(`$name`)").use { cursor -> val seqnoColumnIndex = cursor.getColumnIndex("seqno") val cidColumnIndex = cursor.getColumnIndex("cid") val nameColumnIndex = cursor.getColumnIndex("name") diff --git a/room/room-runtime/src/main/java/androidx/room/util/ViewInfo.kt b/room/room-runtime/src/main/java/androidx/room/util/ViewInfo.kt index 83e7e80c345..f922b031ff2 100644 --- a/room/room-runtime/src/main/java/androidx/room/util/ViewInfo.kt +++ b/room/room-runtime/src/main/java/androidx/room/util/ViewInfo.kt @@ -71,7 +71,7 @@ class ViewInfo( return database.query( "SELECT name, sql FROM sqlite_master " + "WHERE type = 'view' AND name = '$viewName'" - ).useCursor { cursor -> + ).use { cursor -> if (cursor.moveToFirst()) { ViewInfo(cursor.getString(0), cursor.getString(1)) } else { diff --git a/settings.gradle b/settings.gradle index c0ec98f458c..8ae607a4045 100644 --- a/settings.gradle +++ b/settings.gradle @@ -196,10 +196,6 @@ boolean shouldIncludeForFilter(List<BuildType> includeList) { return false } -def includeProject(name, List<BuildType> filter = []) { - includeProject(name, null, filter) -} - // Calling includeProject(name, filePath) is shorthand for: // // include(name) @@ -216,9 +212,6 @@ def includeProject(name, filePath, List<BuildType> filter = []) { def file if (filePath != null) { if (filePath instanceof String) { - if ((":" + filePath.replace("/",":")).equals(name)) { - throw new IllegalArgumentException("Redundant filepath for $name, please remove it") - } file = new File(rootDir, filePath) } else { file = filePath @@ -242,81 +235,82 @@ def includeProject(name, filePath, List<BuildType> filter = []) { // ///////////////////////////// -includeProject(":activity:activity", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE, BuildType.WEAR]) -includeProject(":activity:activity-compose", [BuildType.COMPOSE]) +includeProject(":activity:activity", "activity/activity", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE, BuildType.WEAR]) +includeProject(":activity:activity-compose", "activity/activity-compose", [BuildType.COMPOSE]) includeProject(":activity:activity-compose:activity-compose-samples", "activity/activity-compose/samples", [BuildType.COMPOSE]) -includeProject(":activity:activity-compose:integration-tests:activity-demos", [BuildType.COMPOSE]) -includeProject(":activity:activity-compose-lint", [BuildType.COMPOSE]) -includeProject(":activity:activity-ktx", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE]) -includeProject(":activity:activity-lint", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE, BuildType.WEAR]) -includeProject(":activity:integration-tests:testapp", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":ads:ads-identifier", [BuildType.MAIN]) -includeProject(":ads:ads-identifier-benchmark", [BuildType.MAIN]) -includeProject(":ads:ads-identifier-common", [BuildType.MAIN]) -includeProject(":ads:ads-identifier-provider", [BuildType.MAIN]) -includeProject(":ads:ads-identifier-provider:integration-tests:testapp", [BuildType.MAIN]) -includeProject(":ads:ads-identifier-testing", [BuildType.MAIN]) -includeProject(":ads:ads-identifier:integration-tests:testapp", [BuildType.MAIN]) -includeProject(":annotation:annotation") -includeProject(":annotation:annotation-experimental") -includeProject(":annotation:annotation-experimental-lint") +includeProject(":activity:activity-compose:integration-tests:activity-demos", "activity/activity-compose/integration-tests/activity-demos", [BuildType.COMPOSE]) +includeProject(":activity:activity-compose-lint", "activity/activity-compose-lint", [BuildType.COMPOSE]) +includeProject(":activity:activity-ktx", "activity/activity-ktx", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE]) +includeProject(":activity:activity-lint", "activity/activity-lint", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE, BuildType.WEAR]) +includeProject(":activity:integration-tests:testapp", "activity/integration-tests/testapp", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":ads:ads-identifier", "ads/ads-identifier", [BuildType.MAIN]) +includeProject(":ads:ads-identifier-benchmark", "ads/ads-identifier-benchmark", [BuildType.MAIN]) +includeProject(":ads:ads-identifier-common", "ads/ads-identifier-common", [BuildType.MAIN]) +includeProject(":ads:ads-identifier-provider", "ads/ads-identifier-provider", [BuildType.MAIN]) +includeProject(":ads:ads-identifier-provider:integration-tests:testapp", "ads/ads-identifier-provider/integration-tests/testapp", [BuildType.MAIN]) +includeProject(":ads:ads-identifier-testing", "ads/ads-identifier-testing", [BuildType.MAIN]) +includeProject(":ads:ads-identifier:integration-tests:testapp", "ads/ads-identifier/integration-tests/testapp", [BuildType.MAIN]) +includeProject(":annotation:annotation", "annotation/annotation") +includeProject(":annotation:annotation-experimental", "annotation/annotation-experimental") +includeProject(":annotation:annotation-experimental-lint", "annotation/annotation-experimental-lint") includeProject(":annotation:annotation-experimental-lint-integration-tests", "annotation/annotation-experimental-lint/integration-tests") -includeProject(":annotation:annotation-sampled") -includeProject(":appcompat:appcompat", [BuildType.MAIN]) -includeProject(":appcompat:appcompat-benchmark", [BuildType.MAIN]) -includeProject(":appcompat:appcompat-lint", [BuildType.MAIN]) -includeProject(":appcompat:appcompat-resources", [BuildType.MAIN]) -includeProject(":appcompat:integration-tests:receive-content-testapp", [BuildType.MAIN]) -includeProject(":appsearch:appsearch", [BuildType.MAIN]) -includeProject(":appsearch:appsearch-builtin-types", [BuildType.MAIN]) +includeProject(":annotation:annotation-sampled", "annotation/annotation-sampled") +includeProject(":appcompat:appcompat", "appcompat/appcompat", [BuildType.MAIN]) +includeProject(":appcompat:appcompat-benchmark", "appcompat/appcompat-benchmark", [BuildType.MAIN]) +includeProject(":appcompat:appcompat-lint", "appcompat/appcompat-lint", [BuildType.MAIN]) +includeProject(":appcompat:appcompat-resources", "appcompat/appcompat-resources", [BuildType.MAIN]) +includeProject(":appcompat:integration-tests:receive-content-testapp", "appcompat/integration-tests/receive-content-testapp", [BuildType.MAIN]) +includeProject(":appsearch:appsearch", "appsearch/appsearch", [BuildType.MAIN]) +includeProject(":appsearch:appsearch-builtin-types", "appsearch/appsearch-builtin-types", [BuildType.MAIN]) includeProject(":appsearch:appsearch-compiler", "appsearch/compiler", [BuildType.MAIN]) -includeProject(":appsearch:appsearch-debug-view", [BuildType.MAIN]) -includeProject(":appsearch:appsearch-debug-view:samples", [BuildType.MAIN]) -includeProject(":appsearch:appsearch-ktx", [BuildType.MAIN]) -includeProject(":appsearch:appsearch-local-storage", [BuildType.MAIN]) -includeProject(":appsearch:appsearch-platform-storage", [BuildType.MAIN]) -includeProject(":appsearch:appsearch-test-util", [BuildType.MAIN]) -includeProject(":arch:core:core-common", [BuildType.MAIN]) -includeProject(":arch:core:core-runtime", [BuildType.MAIN]) -includeProject(":arch:core:core-testing", [BuildType.MAIN]) -includeProject(":asynclayoutinflater:asynclayoutinflater", [BuildType.MAIN]) -includeProject(":autofill:autofill", [BuildType.MAIN]) +includeProject(":appsearch:appsearch-debug-view", "appsearch/appsearch-debug-view", [BuildType.MAIN]) +includeProject(":appsearch:appsearch-debug-view:samples", "appsearch/appsearch-debug-view/samples", + [BuildType.MAIN]) +includeProject(":appsearch:appsearch-ktx", "appsearch/appsearch-ktx", [BuildType.MAIN]) +includeProject(":appsearch:appsearch-local-storage", "appsearch/appsearch-local-storage", [BuildType.MAIN]) +includeProject(":appsearch:appsearch-platform-storage", "appsearch/appsearch-platform-storage", [BuildType.MAIN]) +includeProject(":appsearch:appsearch-test-util", "appsearch/appsearch-test-util", [BuildType.MAIN]) +includeProject(":arch:core:core-common", "arch/core/core-common", [BuildType.MAIN]) +includeProject(":arch:core:core-runtime", "arch/core/core-runtime", [BuildType.MAIN]) +includeProject(":arch:core:core-testing", "arch/core/core-testing", [BuildType.MAIN]) +includeProject(":asynclayoutinflater:asynclayoutinflater", "asynclayoutinflater/asynclayoutinflater", [BuildType.MAIN]) +includeProject(":autofill:autofill", "autofill/autofill", [BuildType.MAIN]) includeProject(":benchmark:benchmark-benchmark", "benchmark/benchmark", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":benchmark:benchmark-common") +includeProject(":benchmark:benchmark-common", "benchmark/benchmark-common") includeProject(":benchmark:benchmark-gradle-plugin", "benchmark/gradle-plugin", [BuildType.MAIN]) -includeProject(":benchmark:benchmark-junit4") -includeProject(":benchmark:benchmark-macro", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":benchmark:benchmark-macro-junit4", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":benchmark:integration-tests:dry-run-benchmark", [BuildType.MAIN]) -includeProject(":benchmark:integration-tests:macrobenchmark", [BuildType.MAIN]) -includeProject(":benchmark:integration-tests:macrobenchmark-target", [BuildType.MAIN]) -includeProject(":benchmark:integration-tests:test-module-sample", [BuildType.MAIN]) -includeProject(":benchmark:integration-tests:startup-benchmark", [BuildType.MAIN]) -includeProject(":biometric:biometric", [BuildType.MAIN]) -includeProject(":biometric:biometric-ktx", [BuildType.MAIN]) +includeProject(":benchmark:benchmark-junit4", "benchmark/benchmark-junit4") +includeProject(":benchmark:benchmark-macro", "benchmark/benchmark-macro", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":benchmark:benchmark-macro-junit4", "benchmark/benchmark-macro-junit4", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":benchmark:integration-tests:dry-run-benchmark", "benchmark/integration-tests/dry-run-benchmark", [BuildType.MAIN]) +includeProject(":benchmark:integration-tests:macrobenchmark", "benchmark/integration-tests/macrobenchmark", [BuildType.MAIN]) +includeProject(":benchmark:integration-tests:macrobenchmark-target", "benchmark/integration-tests/macrobenchmark-target", [BuildType.MAIN]) +includeProject(":benchmark:integration-tests:test-module-sample", "benchmark/integration-tests/test-module-sample", [BuildType.MAIN]) +includeProject(":benchmark:integration-tests:startup-benchmark", "benchmark/integration-tests/startup-benchmark", [BuildType.MAIN]) +includeProject(":biometric:biometric", "biometric/biometric", [BuildType.MAIN]) +includeProject(":biometric:biometric-ktx", "biometric/biometric-ktx", [BuildType.MAIN]) includeProject(":biometric:biometric-ktx-samples", "biometric/biometric-ktx/samples", [BuildType.MAIN]) -includeProject(":biometric:integration-tests:testapp", [BuildType.MAIN]) -includeProject(":browser:browser", [BuildType.MAIN]) -includeProject(":buildSrc-tests", [BuildType.MAIN]) +includeProject(":biometric:integration-tests:testapp", "biometric/integration-tests/testapp", [BuildType.MAIN]) +includeProject(":browser:browser", "browser/browser", [BuildType.MAIN]) +includeProject(":buildSrc-tests", "buildSrc-tests", [BuildType.MAIN]) // these projects intentionally fail to compile unless androidx.useMaxDepVersions is enabled if (startParameter.projectProperties.containsKey("androidx.useMaxDepVersions")) { - includeProject(":buildSrc-tests:max-dep-versions:buildSrc-tests-max-dep-versions-dep", [BuildType.MAIN]) - includeProject(":buildSrc-tests:max-dep-versions:buildSrc-tests-max-dep-versions-main", [BuildType.MAIN]) + includeProject(":buildSrc-tests:max-dep-versions:buildSrc-tests-max-dep-versions-dep", "buildSrc-tests/max-dep-versions/buildSrc-tests-max-dep-versions-dep", [BuildType.MAIN]) + includeProject(":buildSrc-tests:max-dep-versions:buildSrc-tests-max-dep-versions-main", "buildSrc-tests/max-dep-versions/buildSrc-tests-max-dep-versions-main", [BuildType.MAIN]) } -includeProject(":buildSrc-tests:project-subsets", [BuildType.MAIN]) -includeProject(":camera:camera-camera2", [BuildType.MAIN]) -includeProject(":camera:camera-camera2-pipe", [BuildType.MAIN]) -includeProject(":camera:camera-camera2-pipe-integration", [BuildType.MAIN]) -includeProject(":camera:camera-camera2-pipe-testing", [BuildType.MAIN]) -includeProject(":camera:camera-core", [BuildType.MAIN]) -includeProject(":camera:camera-extensions", [BuildType.MAIN]) -includeProject(":camera:camera-extensions-stub", [BuildType.MAIN]) -includeProject(":camera:camera-lifecycle", [BuildType.MAIN]) -includeProject(":camera:camera-mlkit-vision", [BuildType.MAIN]) -includeProject(":camera:camera-viewfinder", [BuildType.MAIN]) -includeProject(":camera:camera-testing", [BuildType.MAIN]) -includeProject(":camera:camera-video", [BuildType.MAIN]) -includeProject(":camera:camera-view", [BuildType.MAIN]) +includeProject(":buildSrc-tests:project-subsets", "buildSrc-tests/project-subsets", [BuildType.MAIN]) +includeProject(":camera:camera-camera2", "camera/camera-camera2", [BuildType.MAIN]) +includeProject(":camera:camera-camera2-pipe", "camera/camera-camera2-pipe", [BuildType.MAIN]) +includeProject(":camera:camera-camera2-pipe-integration", "camera/camera-camera2-pipe-integration", [BuildType.MAIN]) +includeProject(":camera:camera-camera2-pipe-testing", "camera/camera-camera2-pipe-testing", [BuildType.MAIN]) +includeProject(":camera:camera-core", "camera/camera-core", [BuildType.MAIN]) +includeProject(":camera:camera-extensions", "camera/camera-extensions", [BuildType.MAIN]) +includeProject(":camera:camera-extensions-stub", "camera/camera-extensions-stub", [BuildType.MAIN]) +includeProject(":camera:camera-lifecycle", "camera/camera-lifecycle", [BuildType.MAIN]) +includeProject(":camera:camera-mlkit-vision", "camera/camera-mlkit-vision", [BuildType.MAIN]) +includeProject(":camera:camera-viewfinder", "camera/camera-viewfinder", [BuildType.MAIN]) +includeProject(":camera:camera-testing", "camera/camera-testing", [BuildType.MAIN]) +includeProject(":camera:camera-video", "camera/camera-video", [BuildType.MAIN]) +includeProject(":camera:camera-view", "camera/camera-view", [BuildType.MAIN]) includeProject(":camera:integration-tests:camera-testapp-camera2-pipe", "camera/integration-tests/camerapipetestapp", [BuildType.MAIN]) includeProject(":camera:integration-tests:camera-testapp-core", "camera/integration-tests/coretestapp", [BuildType.MAIN]) includeProject(":camera:integration-tests:camera-testapp-extensions", "camera/integration-tests/extensionstestapp", [BuildType.MAIN]) @@ -324,10 +318,10 @@ includeProject(":camera:integration-tests:camera-testapp-viewfinder", "camera/in includeProject(":camera:integration-tests:camera-testapp-timing", "camera/integration-tests/timingtestapp", [BuildType.MAIN]) includeProject(":camera:integration-tests:camera-testapp-uiwidgets", "camera/integration-tests/uiwidgetstestapp", [BuildType.MAIN]) includeProject(":camera:integration-tests:camera-testapp-view", "camera/integration-tests/viewtestapp", [BuildType.MAIN]) -includeProject(":camera:camera-testlib-extensions", [BuildType.MAIN]) -includeProject(":car:app:app", [BuildType.MAIN]) -includeProject(":car:app:app-automotive", [BuildType.MAIN]) -includeProject(":car:app:app-projected", [BuildType.MAIN]) +includeProject(":camera:camera-testlib-extensions", "camera/camera-testlib-extensions", [BuildType.MAIN]) +includeProject(":car:app:app", "car/app/app", [BuildType.MAIN]) +includeProject(":car:app:app-automotive", "car/app/app-automotive", [BuildType.MAIN]) +includeProject(":car:app:app-projected", "car/app/app-projected", [BuildType.MAIN]) includeProject(":car:app:app-samples:helloworld-automotive", "car/app/app-samples/helloworld/automotive", [BuildType.MAIN]) includeProject(":car:app:app-samples:helloworld-common", "car/app/app-samples/helloworld/common", [BuildType.MAIN]) includeProject(":car:app:app-samples:helloworld-mobile", "car/app/app-samples/helloworld/mobile", [BuildType.MAIN]) @@ -340,470 +334,474 @@ includeProject(":car:app:app-samples:places-mobile", "car/app/app-samples/places includeProject(":car:app:app-samples:showcase-automotive", "car/app/app-samples/showcase/automotive", [BuildType.MAIN]) includeProject(":car:app:app-samples:showcase-common", "car/app/app-samples/showcase/common", [BuildType.MAIN]) includeProject(":car:app:app-samples:showcase-mobile", "car/app/app-samples/showcase/mobile", [BuildType.MAIN]) -includeProject(":car:app:app-testing", [BuildType.MAIN]) -includeProject(":cardview:cardview", [BuildType.MAIN]) -includeProject(":collection:collection", [BuildType.MAIN]) -includeProject(":collection:collection-benchmark", [BuildType.MAIN]) -includeProject(":collection:collection-benchmark-js", [BuildType.MAIN]) -includeProject(":collection:collection-benchmark-native", [BuildType.MAIN]) -includeProject(":collection:collection-ktx", [BuildType.MAIN]) -includeProject(":collection:integration-tests:testapp", [BuildType.MAIN]) -includeProject(":collection2:collection2", [BuildType.MAIN]) -includeProject(":collection2:collection2:integration-tests:publishing", [BuildType.MAIN]) -includeProject(":compose:animation", [BuildType.COMPOSE]) -includeProject(":compose:animation:animation", [BuildType.COMPOSE]) -includeProject(":compose:animation:animation-lint", [BuildType.COMPOSE]) -includeProject(":compose:animation:animation-core", [BuildType.COMPOSE]) -includeProject(":compose:animation:animation-core-lint", [BuildType.COMPOSE]) +includeProject(":car:app:app-testing", "car/app/app-testing", [BuildType.MAIN]) +includeProject(":cardview:cardview", "cardview/cardview", [BuildType.MAIN]) +includeProject(":collection:collection", "collection/collection", [BuildType.MAIN]) +includeProject(":collection:collection-benchmark", "collection/collection-benchmark", [BuildType.MAIN]) +includeProject(":collection:collection-benchmark-js", "collection/collection-benchmark-js", [BuildType.MAIN]) +includeProject(":collection:collection-benchmark-native", "collection/collection-benchmark-native", [BuildType.MAIN]) +includeProject(":collection:collection-ktx", "collection/collection-ktx", [BuildType.MAIN]) +includeProject(":collection:integration-tests:testapp", "collection/integration-tests/testapp", [BuildType.MAIN]) +includeProject(":collection2:collection2", "collection2/collection2", [BuildType.MAIN]) +includeProject(":collection2:collection2:integration-tests:publishing", "collection2/collection2/integration-tests/publishing", [BuildType.MAIN]) +includeProject(":compose:animation", "compose/animation", [BuildType.COMPOSE]) +includeProject(":compose:animation:animation", "compose/animation/animation", [BuildType.COMPOSE]) +includeProject(":compose:animation:animation-lint", "compose/animation/animation-lint", [BuildType.COMPOSE]) +includeProject(":compose:animation:animation-core", "compose/animation/animation-core", [BuildType.COMPOSE]) +includeProject(":compose:animation:animation-core-lint", "compose/animation/animation-core-lint", [BuildType.COMPOSE]) includeProject(":compose:animation:animation-core:animation-core-benchmark", "compose/animation/animation-core/benchmark", [BuildType.COMPOSE]) includeProject(":compose:animation:animation-core:animation-core-samples", "compose/animation/animation-core/samples", [BuildType.COMPOSE]) -includeProject(":compose:animation:animation-tooling-internal", [BuildType.COMPOSE]) -includeProject(":compose:animation:animation:integration-tests:animation-demos", [BuildType.COMPOSE]) +includeProject(":compose:animation:animation-tooling-internal", "compose/animation/animation-tooling-internal", [BuildType.COMPOSE]) +includeProject(":compose:animation:animation:integration-tests:animation-demos", "compose/animation/animation/integration-tests/animation-demos", [BuildType.COMPOSE]) includeProject(":compose:animation:animation:animation-samples", "compose/animation/animation/samples", [BuildType.COMPOSE]) -includeProject(":compose:animation:animation-graphics", [BuildType.COMPOSE]) +includeProject(":compose:animation:animation-graphics", "compose/animation/animation-graphics", [BuildType.COMPOSE]) includeProject(":compose:animation:animation-graphics:animation-graphics-samples", "compose/animation/animation-graphics/samples", [BuildType.COMPOSE]) -includeProject(":compose:benchmark-utils", [BuildType.COMPOSE]) +includeProject(":compose:benchmark-utils", "compose/benchmark-utils", [BuildType.COMPOSE]) includeProject(":compose:benchmark-utils:benchmark-utils-benchmark", "compose/benchmark-utils/benchmark", [BuildType.COMPOSE]) -includeProject(":compose:compiler:compiler", [BuildType.COMPOSE, BuildType.MAIN]) -includeProject(":compose:compiler:compiler:integration-tests", [BuildType.COMPOSE]) -includeProject(":compose:compiler:compiler-hosted", [BuildType.COMPOSE, BuildType.MAIN]) -includeProject(":compose:compiler:compiler-hosted:integration-tests", [BuildType.COMPOSE]) -includeProject(":compose:compiler:compiler-hosted:integration-tests:kotlin-compiler-repackaged", [BuildType.COMPOSE]) -includeProject(":compose:compiler:compiler-daemon", [BuildType.COMPOSE]) -includeProject(":compose:compiler:compiler-daemon:integration-tests", [BuildType.COMPOSE]) +includeProject(":compose:compiler:compiler", "compose/compiler/compiler", [BuildType.COMPOSE, BuildType.MAIN]) +includeProject(":compose:compiler:compiler:integration-tests", "compose/compiler/compiler/integration-tests", [BuildType.COMPOSE]) +includeProject(":compose:compiler:compiler-hosted", "compose/compiler/compiler-hosted", [BuildType.COMPOSE, BuildType.MAIN]) +includeProject(":compose:compiler:compiler-hosted:integration-tests", "compose/compiler/compiler-hosted/integration-tests", [BuildType.COMPOSE]) +includeProject(":compose:compiler:compiler-hosted:integration-tests:kotlin-compiler-repackaged", "compose/compiler/compiler-hosted/integration-tests/kotlin-compiler-repackaged", [BuildType.COMPOSE]) +includeProject(":compose:compiler:compiler-daemon", "compose/compiler/compiler-daemon", [BuildType.COMPOSE]) +includeProject(":compose:compiler:compiler-daemon:integration-tests", "compose/compiler/compiler-daemon/integration-tests", [BuildType.COMPOSE]) if (isMultiplatformEnabled()) { - includeProject(":compose:desktop", [BuildType.COMPOSE]) - includeProject(":compose:desktop:desktop", [BuildType.COMPOSE]) + includeProject(":compose:desktop", "compose/desktop", [BuildType.COMPOSE]) + includeProject(":compose:desktop:desktop", "compose/desktop/desktop", [BuildType.COMPOSE]) includeProject(":compose:desktop:desktop:desktop-samples", "compose/desktop/desktop/samples", [BuildType.COMPOSE]) } -includeProject(":compose:foundation", [BuildType.COMPOSE]) -includeProject(":compose:foundation:foundation", [BuildType.COMPOSE]) +includeProject(":compose:foundation", "compose/foundation", [BuildType.COMPOSE]) +includeProject(":compose:foundation:foundation", "compose/foundation/foundation", [BuildType.COMPOSE]) includeProject(":compose:foundation:foundation-benchmark", "compose/foundation/foundation/benchmark", [BuildType.COMPOSE]) -includeProject(":compose:foundation:foundation-layout", [BuildType.COMPOSE]) +includeProject(":compose:foundation:foundation-layout", "compose/foundation/foundation-layout", [BuildType.COMPOSE]) includeProject(":compose:foundation:foundation-layout:foundation-layout-benchmark", "compose/foundation/foundation-layout/benchmark", [BuildType.COMPOSE]) includeProject(":compose:foundation:foundation-layout:integration-tests:foundation-layout-demos", "compose/foundation/foundation-layout/integration-tests/layout-demos", [BuildType.COMPOSE]) includeProject(":compose:foundation:foundation-layout:foundation-layout-samples", "compose/foundation/foundation-layout/samples", [BuildType.COMPOSE]) -includeProject(":compose:foundation:foundation:integration-tests:foundation-demos", [BuildType.COMPOSE]) +includeProject(":compose:foundation:foundation:integration-tests:foundation-demos", "compose/foundation/foundation/integration-tests/foundation-demos", [BuildType.COMPOSE]) includeProject(":compose:foundation:foundation:foundation-samples", "compose/foundation/foundation/samples", [BuildType.COMPOSE]) -includeProject(":compose:integration-tests", [BuildType.COMPOSE]) -includeProject(":compose:integration-tests:demos", [BuildType.COMPOSE]) -includeProject(":compose:integration-tests:demos:common", [BuildType.COMPOSE]) -includeProject(":compose:integration-tests:docs-snippets", [BuildType.COMPOSE]) -includeProject(":compose:integration-tests:macrobenchmark", [BuildType.COMPOSE]) -includeProject(":compose:integration-tests:macrobenchmark-target", [BuildType.COMPOSE]) -includeProject(":compose:integration-tests:material-catalog", [BuildType.COMPOSE]) -includeProject(":compose:lint", [BuildType.COMPOSE]) -includeProject(":compose:lint:internal-lint-checks", [BuildType.COMPOSE, BuildType.MAIN]) -includeProject(":compose:lint:common", [BuildType.COMPOSE, BuildType.MAIN]) -includeProject(":compose:lint:common-test", [BuildType.COMPOSE, BuildType.MAIN]) -includeProject(":compose:material", [BuildType.COMPOSE]) -includeProject(":compose:material3:material3", [BuildType.COMPOSE]) -includeProject(":compose:material:material", [BuildType.COMPOSE]) +includeProject(":compose:integration-tests", "compose/integration-tests", [BuildType.COMPOSE]) +includeProject(":compose:integration-tests:demos", "compose/integration-tests/demos", [BuildType.COMPOSE]) +includeProject(":compose:integration-tests:demos:common", "compose/integration-tests/demos/common", [BuildType.COMPOSE]) +includeProject(":compose:integration-tests:docs-snippets", "compose/integration-tests/docs-snippets", [BuildType.COMPOSE]) +includeProject(":compose:integration-tests:macrobenchmark", "compose/integration-tests/macrobenchmark", [BuildType.COMPOSE]) +includeProject(":compose:integration-tests:macrobenchmark-target", "compose/integration-tests/macrobenchmark-target", [BuildType.COMPOSE]) +includeProject(":compose:integration-tests:material-catalog", "compose/integration-tests/material-catalog", [BuildType.COMPOSE]) +includeProject(":compose:lint", "compose/lint", [BuildType.COMPOSE]) +includeProject(":compose:lint:internal-lint-checks", "compose/lint/internal-lint-checks", [BuildType.COMPOSE, BuildType.MAIN]) +includeProject(":compose:lint:common", "compose/lint/common", [BuildType.COMPOSE, BuildType.MAIN]) +includeProject(":compose:lint:common-test", "compose/lint/common-test", [BuildType.COMPOSE, BuildType.MAIN]) +includeProject(":compose:material", "compose/material", [BuildType.COMPOSE]) +includeProject(":compose:material3:material3", "compose/material3/material3", [BuildType.COMPOSE]) +includeProject(":compose:material:material", "compose/material/material", [BuildType.COMPOSE]) includeProject(":compose:material:material-benchmark", "compose/material/material/benchmark", [BuildType.COMPOSE]) -includeProject(":compose:material:material-lint", [BuildType.COMPOSE]) -includeProject(":compose:material:material-icons-core", [BuildType.COMPOSE]) +includeProject(":compose:material:material-lint", "compose/material/material-lint", [BuildType.COMPOSE]) +includeProject(":compose:material:material-icons-core", "compose/material/material-icons-core", [BuildType.COMPOSE]) includeProject(":compose:material:material-icons-core:material-icons-core-samples", "compose/material/material-icons-core/samples", [BuildType.COMPOSE]) -includeProject(":compose:material:material-icons-extended", [BuildType.COMPOSE]) -includeProject(":compose:material:material-icons-extended-filled", [BuildType.COMPOSE]) -includeProject(":compose:material:material-icons-extended-outlined", [BuildType.COMPOSE]) -includeProject(":compose:material:material-icons-extended-rounded", [BuildType.COMPOSE]) -includeProject(":compose:material:material-icons-extended-sharp", [BuildType.COMPOSE]) -includeProject(":compose:material:material-icons-extended-twotone", [BuildType.COMPOSE]) -includeProject(":compose:material:material-ripple", [BuildType.COMPOSE]) -includeProject(":compose:material:material-window", [BuildType.COMPOSE]) -includeProject(":compose:material:material:icons:generator", [BuildType.COMPOSE]) -includeProject(":compose:material:material:integration-tests:material-demos", [BuildType.COMPOSE]) -includeProject(":compose:material:material:integration-tests:material-catalog", [BuildType.COMPOSE]) -includeProject(":compose:material3:material3:integration-tests:material3-catalog", [BuildType.COMPOSE]) +includeProject(":compose:material:material-icons-extended", "compose/material/material-icons-extended", [BuildType.COMPOSE]) +includeProject(":compose:material:material-icons-extended-filled", "compose/material/material-icons-extended-filled", [BuildType.COMPOSE]) +includeProject(":compose:material:material-icons-extended-outlined", "compose/material/material-icons-extended-outlined", [BuildType.COMPOSE]) +includeProject(":compose:material:material-icons-extended-rounded", "compose/material/material-icons-extended-rounded", [BuildType.COMPOSE]) +includeProject(":compose:material:material-icons-extended-sharp", "compose/material/material-icons-extended-sharp", [BuildType.COMPOSE]) +includeProject(":compose:material:material-icons-extended-twotone", "compose/material/material-icons-extended-twotone", [BuildType.COMPOSE]) +includeProject(":compose:material:material-ripple", "compose/material/material-ripple", [BuildType.COMPOSE]) +includeProject(":compose:material:material-window", "compose/material/material-window", [BuildType.COMPOSE]) +includeProject(":compose:material:material:icons:generator", "compose/material/material/icons/generator", [BuildType.COMPOSE]) +includeProject(":compose:material:material:integration-tests:material-demos", "compose/material/material/integration-tests/material-demos", [BuildType.COMPOSE]) +includeProject(":compose:material:material:integration-tests:material-catalog", "compose/material/material/integration-tests/material-catalog", [BuildType.COMPOSE]) +includeProject(":compose:material3:material3:integration-tests:material3-catalog", "compose/material3/material3/integration-tests/material3-catalog", [BuildType.COMPOSE]) includeProject(":compose:material:material:material-samples", "compose/material/material/samples", [BuildType.COMPOSE]) includeProject(":compose:material3:material3:material3-samples", "compose/material3/material3/samples", [BuildType.COMPOSE]) -includeProject(":compose:runtime", [BuildType.COMPOSE, BuildType.MAIN]) -includeProject(":compose:runtime:runtime", [BuildType.COMPOSE, BuildType.MAIN]) -includeProject(":compose:runtime:runtime-lint", [BuildType.COMPOSE, BuildType.MAIN]) -includeProject(":compose:runtime:runtime-livedata", [BuildType.COMPOSE]) +includeProject(":compose:runtime", "compose/runtime", [BuildType.COMPOSE, BuildType.MAIN]) +includeProject(":compose:runtime:runtime", "compose/runtime/runtime", [BuildType.COMPOSE, BuildType.MAIN]) +includeProject(":compose:runtime:runtime-lint", "compose/runtime/runtime-lint", [BuildType.COMPOSE, BuildType.MAIN]) +includeProject(":compose:runtime:runtime-livedata", "compose/runtime/runtime-livedata", [BuildType.COMPOSE]) includeProject(":compose:runtime:runtime-livedata:runtime-livedata-samples", "compose/runtime/runtime-livedata/samples", [BuildType.COMPOSE]) -includeProject(":compose:runtime:runtime-rxjava2", [BuildType.COMPOSE]) +includeProject(":compose:runtime:runtime-rxjava2", "compose/runtime/runtime-rxjava2", [BuildType.COMPOSE]) includeProject(":compose:runtime:runtime-rxjava2:runtime-rxjava2-samples", "compose/runtime/runtime-rxjava2/samples", [BuildType.COMPOSE]) -includeProject(":compose:runtime:runtime-rxjava3", [BuildType.COMPOSE]) +includeProject(":compose:runtime:runtime-rxjava3", "compose/runtime/runtime-rxjava3", [BuildType.COMPOSE]) includeProject(":compose:runtime:runtime-rxjava3:runtime-rxjava3-samples", "compose/runtime/runtime-rxjava3/samples", [BuildType.COMPOSE]) -includeProject(":compose:runtime:runtime-saveable", [BuildType.COMPOSE]) -includeProject(":compose:runtime:runtime-saveable-lint", [BuildType.COMPOSE]) +includeProject(":compose:runtime:runtime-saveable", "compose/runtime/runtime-saveable", [BuildType.COMPOSE]) +includeProject(":compose:runtime:runtime-saveable-lint", "compose/runtime/runtime-saveable-lint", [BuildType.COMPOSE]) includeProject(":compose:runtime:runtime-saveable:runtime-saveable-samples", "compose/runtime/runtime-saveable/samples", [BuildType.COMPOSE]) includeProject(":compose:runtime:runtime:benchmark", "compose/runtime/runtime/compose-runtime-benchmark", [BuildType.COMPOSE]) -includeProject(":compose:runtime:runtime:integration-tests", [BuildType.COMPOSE]) +includeProject(":compose:runtime:runtime:integration-tests", "compose/runtime/runtime/integration-tests", [BuildType.COMPOSE]) includeProject(":compose:runtime:runtime:runtime-samples", "compose/runtime/runtime/samples", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":compose:test-utils", [BuildType.COMPOSE]) -includeProject(":compose:ui", [BuildType.COMPOSE]) -includeProject(":compose:ui:ui", [BuildType.COMPOSE]) +includeProject(":compose:test-utils", "compose/test-utils", [BuildType.COMPOSE]) +includeProject(":compose:ui", "compose/ui", [BuildType.COMPOSE]) +includeProject(":compose:ui:ui", "compose/ui/ui", [BuildType.COMPOSE]) includeProject(":compose:ui:ui-benchmark", "compose/ui/ui/benchmark", [BuildType.COMPOSE]) -includeProject(":compose:ui:ui-android-stubs", [BuildType.COMPOSE]) -includeProject(":compose:ui:ui-geometry", [BuildType.COMPOSE]) -includeProject(":compose:ui:ui-graphics", [BuildType.COMPOSE]) -includeProject(":compose:ui:ui-graphics-lint", [BuildType.COMPOSE]) +includeProject(":compose:ui:ui-android-stubs", "compose/ui/ui-android-stubs", [BuildType.COMPOSE]) +includeProject(":compose:ui:ui-geometry", "compose/ui/ui-geometry", [BuildType.COMPOSE]) +includeProject(":compose:ui:ui-graphics", "compose/ui/ui-graphics", [BuildType.COMPOSE]) +includeProject(":compose:ui:ui-graphics-lint", "compose/ui/ui-graphics-lint", [BuildType.COMPOSE]) includeProject(":compose:ui:ui-graphics:ui-graphics-benchmark", "compose/ui/ui-graphics/benchmark", [BuildType.COMPOSE]) -includeProject(":compose:ui:ui-graphics:ui-graphics-benchmark:test", [BuildType.COMPOSE]) +includeProject(":compose:ui:ui-graphics:ui-graphics-benchmark:test", "compose/ui/ui-graphics/benchmark/test", [BuildType.COMPOSE]) includeProject(":compose:ui:ui-graphics:ui-graphics-samples", "compose/ui/ui-graphics/samples", [BuildType.COMPOSE]) -includeProject(":compose:ui:ui-inspection", [BuildType.COMPOSE]) -includeProject(":compose:ui:ui-lint", [BuildType.COMPOSE]) -includeProject(":compose:ui:ui-test", [BuildType.COMPOSE]) +includeProject(":compose:ui:ui-inspection", "compose/ui/ui-inspection", [BuildType.COMPOSE]) +includeProject(":compose:ui:ui-lint", "compose/ui/ui-lint", [BuildType.COMPOSE]) +includeProject(":compose:ui:ui-test", "compose/ui/ui-test", [BuildType.COMPOSE]) includeProject(":compose:ui:ui-test:ui-test-samples", "compose/ui/ui-test/samples", [BuildType.COMPOSE]) -includeProject(":compose:ui:ui-test-font", [BuildType.COMPOSE]) -includeProject(":compose:ui:ui-test-junit4", [BuildType.COMPOSE]) -includeProject(":compose:ui:ui-test-manifest", [BuildType.COMPOSE]) -includeProject(":compose:ui:ui-test-manifest:integration-tests:testapp", [BuildType.COMPOSE]) -includeProject(":compose:ui:ui-text", [BuildType.COMPOSE]) -includeProject(":compose:ui:ui-text-google-fonts", [BuildType.COMPOSE]) +includeProject(":compose:ui:ui-test-font", "compose/ui/ui-test-font", [BuildType.COMPOSE]) +includeProject(":compose:ui:ui-test-junit4", "compose/ui/ui-test-junit4", [BuildType.COMPOSE]) +includeProject(":compose:ui:ui-test-manifest", "compose/ui/ui-test-manifest", [BuildType.COMPOSE]) +includeProject(":compose:ui:ui-test-manifest:integration-tests:testapp", "compose/ui/ui-test-manifest/integration-tests/testapp", [BuildType.COMPOSE]) +includeProject(":compose:ui:ui-text", "compose/ui/ui-text", [BuildType.COMPOSE]) +includeProject(":compose:ui:ui-text-google-fonts", "compose/ui/ui-text-google-fonts", [BuildType.COMPOSE]) includeProject(":compose:ui:ui-text:ui-text-benchmark", "compose/ui/ui-text/benchmark", [BuildType.COMPOSE]) includeProject(":compose:ui:ui-text:ui-text-samples", "compose/ui/ui-text/samples", [BuildType.COMPOSE]) -includeProject(":compose:ui:ui-tooling", [BuildType.COMPOSE]) -includeProject(":compose:ui:ui-tooling-data", [BuildType.COMPOSE]) -includeProject(":compose:ui:ui-tooling-preview", [BuildType.COMPOSE]) -includeProject(":compose:ui:ui-unit", [BuildType.COMPOSE]) +includeProject(":compose:ui:ui-tooling", "compose/ui/ui-tooling", [BuildType.COMPOSE]) +includeProject(":compose:ui:ui-tooling-data", "compose/ui/ui-tooling-data", [BuildType.COMPOSE]) +includeProject(":compose:ui:ui-tooling-preview", "compose/ui/ui-tooling-preview", [BuildType.COMPOSE]) +includeProject(":compose:ui:ui-unit", "compose/ui/ui-unit", [BuildType.COMPOSE]) includeProject(":compose:ui:ui-unit:ui-unit-samples", "compose/ui/ui-unit/samples", [BuildType.COMPOSE]) -includeProject(":compose:ui:ui-util", [BuildType.COMPOSE]) -includeProject(":compose:ui:ui-viewbinding", [BuildType.COMPOSE]) +includeProject(":compose:ui:ui-util", "compose/ui/ui-util", [BuildType.COMPOSE]) +includeProject(":compose:ui:ui-viewbinding", "compose/ui/ui-viewbinding", [BuildType.COMPOSE]) includeProject(":compose:ui:ui-viewbinding:ui-viewbinding-samples", "compose/ui/ui-viewbinding/samples", [BuildType.COMPOSE]) -includeProject(":compose:ui:ui:integration-tests:ui-demos", [BuildType.COMPOSE]) +includeProject(":compose:ui:ui:integration-tests:ui-demos", "compose/ui/ui/integration-tests/ui-demos", [BuildType.COMPOSE]) includeProject(":compose:ui:ui:ui-samples", "compose/ui/ui/samples", [BuildType.COMPOSE]) -includeProject(":concurrent:concurrent-futures", [BuildType.MAIN]) -includeProject(":concurrent:concurrent-futures-ktx", [BuildType.MAIN]) -includeProject(":contentpager:contentpager", [BuildType.MAIN]) -includeProject(":coordinatorlayout:coordinatorlayout", [BuildType.MAIN]) -includeProject(":core:core", [BuildType.MAIN, BuildType.MEDIA, BuildType.FLAN, BuildType.COMPOSE, BuildType.WEAR]) -includeProject(":core:core-animation", [BuildType.MAIN]) -includeProject(":core:core-animation-integration-tests:testapp", [BuildType.MAIN]) -includeProject(":core:core-animation-testing", [BuildType.MAIN]) -includeProject(":core:core-appdigest", [BuildType.MAIN]) -includeProject(":core:core-google-shortcuts", [BuildType.MAIN]) -includeProject(":core:core-i18n", [BuildType.MAIN]) -includeProject(":core:core-ktx", [BuildType.MAIN, BuildType.GLANCE]) -includeProject(":core:core-performance", [BuildType.MAIN]) +includeProject(":concurrent:concurrent-futures", "concurrent/concurrent-futures", [BuildType.MAIN]) +includeProject(":concurrent:concurrent-futures-ktx", "concurrent/concurrent-futures-ktx", [BuildType.MAIN]) +includeProject(":contentpager:contentpager", "contentpager/contentpager", [BuildType.MAIN]) +includeProject(":coordinatorlayout:coordinatorlayout", "coordinatorlayout/coordinatorlayout", [BuildType.MAIN]) +includeProject(":core:core", "core/core", [BuildType.MAIN, BuildType.MEDIA, BuildType.FLAN, BuildType.COMPOSE, BuildType.WEAR]) +includeProject(":core:core-animation", "core/core-animation", [BuildType.MAIN]) +includeProject(":core:core-animation-integration-tests:testapp", "core/core-animation-integration-tests/testapp", [BuildType.MAIN]) +includeProject(":core:core-animation-testing", "core/core-animation-testing", [BuildType.MAIN]) +includeProject(":core:core-appdigest", "core/core-appdigest", [BuildType.MAIN]) +includeProject(":core:core-google-shortcuts", "core/core-google-shortcuts", [BuildType.MAIN]) +includeProject(":core:core-i18n", "core/core-i18n", [BuildType.MAIN]) +includeProject(":core:core-ktx", "core/core-ktx", [BuildType.MAIN, BuildType.GLANCE]) +includeProject(":core:core-performance", "core/core-performance", [BuildType.MAIN]) includeProject(":core:core-performance:core-performance-samples", "core/core-performance/samples", [BuildType.MAIN]) -includeProject(":core:core-remoteviews", [BuildType.MAIN, BuildType.GLANCE]) -includeProject(":core:core-remoteviews:integration-tests:demos", [BuildType.MAIN, BuildType.GLANCE]) -includeProject(":core:core-splashscreen", [BuildType.MAIN]) +includeProject(":core:core-remoteviews", "core/core-remoteviews", [BuildType.MAIN, BuildType.GLANCE]) +includeProject(":core:core-remoteviews:integration-tests:demos", "core/core-remoteviews/integration-tests/demos", [BuildType.MAIN, BuildType.GLANCE]) +includeProject(":core:core-splashscreen", "core/core-splashscreen", [BuildType.MAIN]) includeProject(":core:core-splashscreen:core-splashscreen-samples", "core/core-splashscreen/samples", [BuildType.MAIN]) includeProject(":core:core-graphics-integration-tests:core-graphics-integration-tests", "core/core-graphics-integration-tests/testapp", [BuildType.MAIN]) -includeProject(":core:core-role", [BuildType.MAIN]) -includeProject(":core:uwb:uwb", [BuildType.MAIN]) -includeProject(":cursoradapter:cursoradapter", [BuildType.MAIN]) -includeProject(":customview:customview", [BuildType.MAIN]) -includeProject(":customview:customview-poolingcontainer", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":datastore:datastore", [BuildType.MAIN]) -includeProject(":datastore:datastore-core", [BuildType.MAIN]) -includeProject(":datastore:datastore-preferences", [BuildType.MAIN]) -includeProject(":datastore:datastore-preferences-core", [BuildType.MAIN]) -includeProject(":datastore:datastore-preferences-proto", [BuildType.MAIN]) -includeProject(":datastore:datastore-preferences-rxjava2", [BuildType.MAIN]) -includeProject(":datastore:datastore-preferences-rxjava3", [BuildType.MAIN]) -includeProject(":datastore:datastore-proto", [BuildType.MAIN]) -includeProject(":datastore:datastore-rxjava2", [BuildType.MAIN]) -includeProject(":datastore:datastore-rxjava3", [BuildType.MAIN]) -includeProject(":datastore:datastore-sampleapp", [BuildType.MAIN]) -includeProject(":documentfile:documentfile", [BuildType.MAIN]) -includeProject(":draganddrop:draganddrop", [BuildType.MAIN]) -includeProject(":draganddrop:integration-tests:sampleapp", [BuildType.MAIN]) -includeProject(":drawerlayout:drawerlayout", [BuildType.MAIN]) -includeProject(":dynamicanimation", [BuildType.MAIN]) -includeProject(":dynamicanimation:dynamicanimation", [BuildType.MAIN]) -includeProject(":dynamicanimation:dynamicanimation-ktx", [BuildType.MAIN]) -includeProject(":emoji:emoji", [BuildType.MAIN]) -includeProject(":emoji:emoji-appcompat", [BuildType.MAIN]) -includeProject(":emoji:emoji-bundled", [BuildType.MAIN]) -includeProject(":emoji2:emoji2", [BuildType.MAIN]) -includeProject(":emoji2:emoji2-bundled", [BuildType.MAIN]) -includeProject(":emoji2:emoji2-views", [BuildType.MAIN]) -includeProject(":emoji2:emoji2-views-helper", [BuildType.MAIN]) -includeProject(":emoji2:emoji2-benchmark", [BuildType.MAIN]) -includeProject(":emoji2:integration-tests:init-disabled-macrobenchmark", [BuildType.MAIN]) -includeProject(":emoji2:integration-tests:init-disabled-macrobenchmark-target", [BuildType.MAIN]) -includeProject(":emoji2:integration-tests:init-enabled-macrobenchmark", [BuildType.MAIN]) -includeProject(":emoji2:integration-tests:init-enabled-macrobenchmark-target", [BuildType.MAIN]) -includeProject(":enterprise:enterprise-feedback", [BuildType.MAIN]) -includeProject(":enterprise:enterprise-feedback-testing", [BuildType.MAIN]) -includeProject(":exifinterface:exifinterface", [BuildType.MAIN]) -includeProject(":fakeannotations", [BuildType.MAIN]) -includeProject(":fragment:fragment", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR]) -includeProject(":fragment:fragment-ktx", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":fragment:fragment-lint", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR]) -includeProject(":fragment:fragment-testing", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":fragment:fragment-testing-lint", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":fragment:fragment-truth", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":fragment:integration-tests:testapp", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":glance:glance", [BuildType.MAIN, BuildType.GLANCE]) -includeProject(":glance:glance-appwidget", [BuildType.MAIN, BuildType.GLANCE]) -includeProject(":glance:glance-appwidget-proto", [BuildType.MAIN, BuildType.GLANCE]) -includeProject(":glance:glance-appwidget:integration-tests:demos", [BuildType.MAIN, BuildType.GLANCE]) -includeProject(":glance:glance-appwidget:glance-layout-generator", [BuildType.MAIN, BuildType.GLANCE]) -includeProject(":glance:glance-wear-tiles:integration-tests:demos", [BuildType.MAIN, BuildType.GLANCE]) -includeProject(":glance:glance-wear-tiles", [BuildType.MAIN, BuildType.GLANCE]) -includeProject(":gridlayout:gridlayout", [BuildType.MAIN]) -includeProject(":health:health-data-client", [BuildType.MAIN]) -includeProject(":health:health-services-client", [BuildType.MAIN]) -includeProject(":heifwriter:heifwriter", [BuildType.MAIN]) -includeProject(":hilt:hilt-common", [BuildType.MAIN]) -includeProject(":hilt:hilt-compiler", [BuildType.MAIN]) -includeProject(":hilt:hilt-navigation", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":hilt:hilt-navigation-compose", [BuildType.COMPOSE]) +includeProject(":core:core-role", "core/core-role", [BuildType.MAIN]) +includeProject(":core:uwb:uwb", "core/uwb/uwb", [BuildType.MAIN]) +includeProject(":cursoradapter:cursoradapter", "cursoradapter/cursoradapter", [BuildType.MAIN]) +includeProject(":customview:customview", "customview/customview", [BuildType.MAIN]) +includeProject(":customview:customview-poolingcontainer", "customview/customview-poolingcontainer", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":datastore:datastore", "datastore/datastore", [BuildType.MAIN]) +includeProject(":datastore:datastore-core", "datastore/datastore-core", [BuildType.MAIN]) +includeProject(":datastore:datastore-preferences", "datastore/datastore-preferences", [BuildType.MAIN]) +includeProject(":datastore:datastore-preferences-core", "datastore/datastore-preferences-core", + [BuildType.MAIN]) +includeProject(":datastore:datastore-preferences-proto", + "datastore/datastore-preferences-proto", [BuildType.MAIN]) +includeProject(":datastore:datastore-preferences-rxjava2", + "datastore/datastore-preferences-rxjava2", [BuildType.MAIN]) +includeProject(":datastore:datastore-preferences-rxjava3", + "datastore/datastore-preferences-rxjava3", [BuildType.MAIN]) +includeProject(":datastore:datastore-proto", "datastore/datastore-proto", [BuildType.MAIN]) +includeProject(":datastore:datastore-rxjava2", "datastore/datastore-rxjava2", [BuildType.MAIN]) +includeProject(":datastore:datastore-rxjava3", "datastore/datastore-rxjava3", [BuildType.MAIN]) +includeProject(":datastore:datastore-sampleapp", "datastore/datastore-sampleapp", [BuildType.MAIN]) +includeProject(":documentfile:documentfile", "documentfile/documentfile", [BuildType.MAIN]) +includeProject(":draganddrop:draganddrop", "draganddrop/draganddrop", [BuildType.MAIN]) +includeProject(":draganddrop:integration-tests:sampleapp", "draganddrop/integration-tests/sampleapp", [BuildType.MAIN]) +includeProject(":drawerlayout:drawerlayout", "drawerlayout/drawerlayout", [BuildType.MAIN]) +includeProject(":dynamicanimation", "dynamicanimation", [BuildType.MAIN]) +includeProject(":dynamicanimation:dynamicanimation", "dynamicanimation/dynamicanimation", [BuildType.MAIN]) +includeProject(":dynamicanimation:dynamicanimation-ktx", "dynamicanimation/dynamicanimation-ktx", [BuildType.MAIN]) +includeProject(":emoji:emoji", "emoji/emoji", [BuildType.MAIN]) +includeProject(":emoji:emoji-appcompat", "emoji/emoji-appcompat", [BuildType.MAIN]) +includeProject(":emoji:emoji-bundled", "emoji/emoji-bundled", [BuildType.MAIN]) +includeProject(":emoji2:emoji2", "emoji2/emoji2", [BuildType.MAIN]) +includeProject(":emoji2:emoji2-bundled", "emoji2/emoji2-bundled", [BuildType.MAIN]) +includeProject(":emoji2:emoji2-views", "emoji2/emoji2-views", [BuildType.MAIN]) +includeProject(":emoji2:emoji2-views-helper", "emoji2/emoji2-views-helper", [BuildType.MAIN]) +includeProject(":emoji2:emoji2-benchmark", "emoji2/emoji2-benchmark", [BuildType.MAIN]) +includeProject(":emoji2:integration-tests:init-disabled-macrobenchmark", "emoji2/integration-tests/init-disabled-macrobenchmark", [BuildType.MAIN]) +includeProject(":emoji2:integration-tests:init-disabled-macrobenchmark-target", "emoji2/integration-tests/init-disabled-macrobenchmark-target", [BuildType.MAIN]) +includeProject(":emoji2:integration-tests:init-enabled-macrobenchmark", "emoji2/integration-tests/init-enabled-macrobenchmark", [BuildType.MAIN]) +includeProject(":emoji2:integration-tests:init-enabled-macrobenchmark-target", "emoji2/integration-tests/init-enabled-macrobenchmark-target", [BuildType.MAIN]) +includeProject(":enterprise:enterprise-feedback", "enterprise/enterprise-feedback", [BuildType.MAIN]) +includeProject(":enterprise:enterprise-feedback-testing", "enterprise/enterprise-feedback-testing", [BuildType.MAIN]) +includeProject(":exifinterface:exifinterface", "exifinterface/exifinterface", [BuildType.MAIN]) +includeProject(":fakeannotations", "fakeannotations", [BuildType.MAIN]) +includeProject(":fragment:fragment", "fragment/fragment", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR]) +includeProject(":fragment:fragment-ktx", "fragment/fragment-ktx", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":fragment:fragment-lint", "fragment/fragment-lint", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR]) +includeProject(":fragment:fragment-testing", "fragment/fragment-testing", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":fragment:fragment-testing-lint", "fragment/fragment-testing-lint", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":fragment:fragment-truth", "fragment/fragment-truth", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":fragment:integration-tests:testapp", "fragment/integration-tests/testapp", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":glance:glance", "glance/glance", [BuildType.MAIN, BuildType.GLANCE]) +includeProject(":glance:glance-appwidget", "glance/glance-appwidget", [BuildType.MAIN, BuildType.GLANCE]) +includeProject(":glance:glance-appwidget-proto", "glance/glance-appwidget-proto", [BuildType.MAIN, BuildType.GLANCE]) +includeProject(":glance:glance-appwidget:integration-tests:demos", "glance/glance-appwidget/integration-tests/demos", [BuildType.MAIN, BuildType.GLANCE]) +includeProject(":glance:glance-appwidget:glance-layout-generator", "glance/glance-appwidget/glance-layout-generator", [BuildType.MAIN, BuildType.GLANCE]) +includeProject(":glance:glance-wear-tiles:integration-tests:demos", "glance/glance-wear-tiles/integration-tests/demos", [BuildType.MAIN, BuildType.GLANCE]) +includeProject(":glance:glance-wear-tiles", "glance/glance-wear-tiles", [BuildType.MAIN, BuildType.GLANCE]) +includeProject(":gridlayout:gridlayout", "gridlayout/gridlayout", [BuildType.MAIN]) +includeProject(":health:health-data-client", "health/health-data-client", [BuildType.MAIN]) +includeProject(":health:health-services-client", "health/health-services-client", [BuildType.MAIN]) +includeProject(":heifwriter:heifwriter", "heifwriter/heifwriter", [BuildType.MAIN]) +includeProject(":hilt:hilt-common", "hilt/hilt-common", [BuildType.MAIN]) +includeProject(":hilt:hilt-compiler", "hilt/hilt-compiler", [BuildType.MAIN]) +includeProject(":hilt:hilt-navigation", "hilt/hilt-navigation", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":hilt:hilt-navigation-compose", "hilt/hilt-navigation-compose", [BuildType.COMPOSE]) includeProject(":hilt:hilt-navigation-compose-samples", "hilt/hilt-navigation-compose/samples", [BuildType.COMPOSE]) -includeProject(":hilt:hilt-navigation-fragment", [BuildType.MAIN]) -includeProject(":hilt:hilt-work", [BuildType.MAIN]) +includeProject(":hilt:hilt-navigation-fragment", "hilt/hilt-navigation-fragment", [BuildType.MAIN]) +includeProject(":hilt:hilt-work", "hilt/hilt-work", [BuildType.MAIN]) includeProject(":hilt:integration-tests:hilt-testapp-viewmodel", "hilt/integration-tests/viewmodelapp", [BuildType.MAIN]) includeProject(":hilt:integration-tests:hilt-testapp-worker", "hilt/integration-tests/workerapp", [BuildType.MAIN]) -includeProject(":inspection:inspection", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":inspection:inspection-gradle-plugin", [BuildType.MAIN]) -includeProject(":inspection:inspection-testing", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":interpolator:interpolator", [BuildType.MAIN]) +includeProject(":inspection:inspection", "inspection/inspection", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":inspection:inspection-gradle-plugin", "inspection/inspection-gradle-plugin", [BuildType.MAIN]) +includeProject(":inspection:inspection-testing", "inspection/inspection-testing", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":interpolator:interpolator", "interpolator/interpolator", [BuildType.MAIN]) includeProject(":jetifier:jetifier-core", "jetifier/jetifier/core", [BuildType.MAIN]) includeProject(":jetifier:jetifier-preprocessor", "jetifier/jetifier/preprocessor", [BuildType.MAIN]) includeProject(":jetifier:jetifier-processor", "jetifier/jetifier/processor", [BuildType.MAIN]) includeProject(":jetifier:jetifier-standalone", "jetifier/jetifier/standalone", [BuildType.MAIN]) -includeProject(":leanback:leanback", [BuildType.MAIN]) -includeProject(":leanback:leanback-grid", [BuildType.MAIN]) -includeProject(":leanback:leanback-paging", [BuildType.MAIN]) -includeProject(":leanback:leanback-preference", [BuildType.MAIN]) -includeProject(":leanback:leanback-tab", [BuildType.MAIN]) -includeProject(":lifecycle:integration-tests:incrementality", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":leanback:leanback", "leanback/leanback", [BuildType.MAIN]) +includeProject(":leanback:leanback-grid", "leanback/leanback-grid", [BuildType.MAIN]) +includeProject(":leanback:leanback-paging", "leanback/leanback-paging", [BuildType.MAIN]) +includeProject(":leanback:leanback-preference", "leanback/leanback-preference", [BuildType.MAIN]) +includeProject(":leanback:leanback-tab", "leanback/leanback-tab", [BuildType.MAIN]) +includeProject(":lifecycle:integration-tests:incrementality", "lifecycle/integration-tests/incrementality", [BuildType.MAIN, BuildType.FLAN]) includeProject(":lifecycle:integration-tests:lifecycle-testapp", "lifecycle/integration-tests/testapp", [BuildType.MAIN, BuildType.FLAN]) includeProject(":lifecycle:integration-tests:lifecycle-testapp-kotlin", "lifecycle/integration-tests/kotlintestapp", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":lifecycle:lifecycle-common", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR, BuildType.COMPOSE]) -includeProject(":lifecycle:lifecycle-common-java8", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR, BuildType.COMPOSE]) -includeProject(":lifecycle:lifecycle-compiler", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":lifecycle:lifecycle-extensions", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":lifecycle:lifecycle-livedata", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":lifecycle:lifecycle-livedata-core", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR, BuildType.COMPOSE]) -includeProject(":lifecycle:lifecycle-livedata-core-ktx", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":lifecycle:lifecycle-livedata-core-ktx-lint", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":lifecycle:lifecycle-livedata-core-truth", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":lifecycle:lifecycle-livedata-ktx", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":lifecycle:lifecycle-process", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":lifecycle:lifecycle-reactivestreams", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":lifecycle:lifecycle-reactivestreams-ktx", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":lifecycle:lifecycle-runtime", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR, BuildType.COMPOSE]) -includeProject(":lifecycle:lifecycle-runtime-ktx", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR, BuildType.COMPOSE]) -includeProject(":lifecycle:lifecycle-runtime-ktx-lint", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR, BuildType.COMPOSE]) -includeProject(":lifecycle:lifecycle-runtime-testing", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR, BuildType.COMPOSE]) -includeProject(":lifecycle:lifecycle-service", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":lifecycle:lifecycle-viewmodel", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR, BuildType.COMPOSE]) -includeProject(":lifecycle:lifecycle-viewmodel-compose", [BuildType.COMPOSE]) +includeProject(":lifecycle:lifecycle-common", "lifecycle/lifecycle-common", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR, BuildType.COMPOSE]) +includeProject(":lifecycle:lifecycle-common-java8", "lifecycle/lifecycle-common-java8", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR, BuildType.COMPOSE]) +includeProject(":lifecycle:lifecycle-compiler", "lifecycle/lifecycle-compiler", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":lifecycle:lifecycle-extensions", "lifecycle/lifecycle-extensions", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":lifecycle:lifecycle-livedata", "lifecycle/lifecycle-livedata", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":lifecycle:lifecycle-livedata-core", "lifecycle/lifecycle-livedata-core", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR, BuildType.COMPOSE]) +includeProject(":lifecycle:lifecycle-livedata-core-ktx", "lifecycle/lifecycle-livedata-core-ktx", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":lifecycle:lifecycle-livedata-core-ktx-lint", "lifecycle/lifecycle-livedata-core-ktx-lint", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":lifecycle:lifecycle-livedata-core-truth", "lifecycle/lifecycle-livedata-core-truth", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":lifecycle:lifecycle-livedata-ktx", "lifecycle/lifecycle-livedata-ktx", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":lifecycle:lifecycle-process", "lifecycle/lifecycle-process", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":lifecycle:lifecycle-reactivestreams", "lifecycle/lifecycle-reactivestreams", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":lifecycle:lifecycle-reactivestreams-ktx", "lifecycle/lifecycle-reactivestreams-ktx", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":lifecycle:lifecycle-runtime", "lifecycle/lifecycle-runtime", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR, BuildType.COMPOSE]) +includeProject(":lifecycle:lifecycle-runtime-ktx", "lifecycle/lifecycle-runtime-ktx", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR, BuildType.COMPOSE]) +includeProject(":lifecycle:lifecycle-runtime-ktx-lint", "lifecycle/lifecycle-runtime-ktx-lint", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR, BuildType.COMPOSE]) +includeProject(":lifecycle:lifecycle-runtime-testing", "lifecycle/lifecycle-runtime-testing", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR, BuildType.COMPOSE]) +includeProject(":lifecycle:lifecycle-service", "lifecycle/lifecycle-service", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":lifecycle:lifecycle-viewmodel", "lifecycle/lifecycle-viewmodel", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR, BuildType.COMPOSE]) +includeProject(":lifecycle:lifecycle-viewmodel-compose", "lifecycle/lifecycle-viewmodel-compose", [BuildType.COMPOSE]) includeProject(":lifecycle:lifecycle-viewmodel-compose:lifecycle-viewmodel-compose-samples", "lifecycle/lifecycle-viewmodel-compose/samples", [BuildType.COMPOSE]) -includeProject(":lifecycle:lifecycle-viewmodel-compose:integration-tests:lifecycle-viewmodel-demos", [BuildType.COMPOSE]) -includeProject(":lifecycle:lifecycle-viewmodel-ktx", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE]) -includeProject(":lifecycle:lifecycle-viewmodel-savedstate", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR, BuildType.COMPOSE]) -includeProject(":lint-checks") -includeProject(":lint-checks:integration-tests") -includeProject(":lint-demos:lint-demo-appcompat", [BuildType.MAIN]) -includeProject(":loader:loader", [BuildType.MAIN]) -includeProject(":loader:loader-ktx", [BuildType.MAIN]) -includeProject(":media2:integration-tests:testapp", [BuildType.MAIN, BuildType.MEDIA]) -includeProject(":media2:media2-common", [BuildType.MAIN, BuildType.MEDIA]) -includeProject(":media2:media2-exoplayer", [BuildType.MAIN, BuildType.MEDIA]) -includeProject(":media2:media2-player", [BuildType.MAIN, BuildType.MEDIA]) -includeProject(":media2:media2-session", [BuildType.MAIN, BuildType.MEDIA]) -includeProject(":media2:media2-widget", [BuildType.MAIN, BuildType.MEDIA]) -includeProject(":media:media", [BuildType.MAIN, BuildType.MEDIA]) -includeProject(":mediarouter:mediarouter", [BuildType.MAIN, BuildType.MEDIA]) -includeProject(":mediarouter:mediarouter-testing", [BuildType.MAIN, BuildType.MEDIA]) -includeProject(":metrics:metrics-performance", [BuildType.MAIN]) +includeProject(":lifecycle:lifecycle-viewmodel-compose:integration-tests:lifecycle-viewmodel-demos", "lifecycle/lifecycle-viewmodel-compose/integration-tests/lifecycle-viewmodel-demos", [BuildType.COMPOSE]) +includeProject(":lifecycle:lifecycle-viewmodel-ktx", "lifecycle/lifecycle-viewmodel-ktx", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE]) +includeProject(":lifecycle:lifecycle-viewmodel-savedstate", "lifecycle/lifecycle-viewmodel-savedstate", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR, BuildType.COMPOSE]) +includeProject(":lint-checks", "lint-checks") +includeProject(":lint-checks:integration-tests", "lint-checks/integration-tests") +includeProject(":lint-demos:lint-demo-appcompat", "lint-demos/lint-demo-appcompat", [BuildType.MAIN]) +includeProject(":loader:loader", "loader/loader", [BuildType.MAIN]) +includeProject(":loader:loader-ktx", "loader/loader-ktx", [BuildType.MAIN]) +includeProject(":media2:integration-tests:testapp", "media2/integration-tests/testapp", [BuildType.MAIN, BuildType.MEDIA]) +includeProject(":media2:media2-common", "media2/media2-common", [BuildType.MAIN, BuildType.MEDIA]) +includeProject(":media2:media2-exoplayer", "media2/media2-exoplayer", [BuildType.MAIN, BuildType.MEDIA]) +includeProject(":media2:media2-player", "media2/media2-player", [BuildType.MAIN, BuildType.MEDIA]) +includeProject(":media2:media2-session", "media2/media2-session", [BuildType.MAIN, BuildType.MEDIA]) +includeProject(":media2:media2-widget", "media2/media2-widget", [BuildType.MAIN, BuildType.MEDIA]) +includeProject(":media:media", "media/media", [BuildType.MAIN, BuildType.MEDIA]) +includeProject(":mediarouter:mediarouter", "mediarouter/mediarouter", [BuildType.MAIN, BuildType.MEDIA]) +includeProject(":mediarouter:mediarouter-testing", "mediarouter/mediarouter-testing", [BuildType.MAIN, BuildType.MEDIA]) +includeProject(":metrics:metrics-performance", "metrics/metrics-performance", [BuildType.MAIN]) includeProject(":metrics:metrics-integration-tests", "metrics/integration-tests", [BuildType.MAIN]) includeProject(":metrics:metrics-integration-tests:janktest", "metrics/integration-tests/janktest", [BuildType.MAIN]) -includeProject(":navigation:navigation-benchmark", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":navigation:navigation-common", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE]) -includeProject(":navigation:navigation-common-ktx", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE]) -includeProject(":navigation:navigation-compose", [BuildType.COMPOSE]) +includeProject(":navigation:navigation-benchmark", "navigation/navigation-benchmark", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":navigation:navigation-common", "navigation/navigation-common", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE]) +includeProject(":navigation:navigation-common-ktx", "navigation/navigation-common-ktx", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE]) +includeProject(":navigation:navigation-compose", "navigation/navigation-compose", [BuildType.COMPOSE]) includeProject(":navigation:navigation-compose:navigation-compose-samples", "navigation/navigation-compose/samples", [BuildType.COMPOSE]) -includeProject(":navigation:navigation-compose:integration-tests:navigation-demos", [BuildType.COMPOSE]) -includeProject(":navigation:navigation-compose-lint", [BuildType.COMPOSE]) -includeProject(":navigation:navigation-dynamic-features-fragment", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":navigation:navigation-dynamic-features-runtime", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":navigation:navigation-fragment", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":navigation:navigation-fragment-ktx", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":navigation:navigation-compose:integration-tests:navigation-demos", "navigation/navigation-compose/integration-tests/navigation-demos", [BuildType.COMPOSE]) +includeProject(":navigation:navigation-compose-lint", "navigation/navigation-compose-lint", [BuildType.COMPOSE]) +includeProject(":navigation:navigation-dynamic-features-fragment", "navigation/navigation-dynamic-features-fragment", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":navigation:navigation-dynamic-features-runtime", "navigation/navigation-dynamic-features-runtime", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":navigation:navigation-fragment", "navigation/navigation-fragment", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":navigation:navigation-fragment-ktx", "navigation/navigation-fragment-ktx", [BuildType.MAIN, BuildType.FLAN]) includeProject(":navigation:navigation-integration-tests", "navigation/integration-tests", [BuildType.MAIN, BuildType.FLAN]) includeProject(":navigation:navigation-integration-tests:testapp", "navigation/integration-tests/testapp", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":navigation:navigation-runtime", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE]) -includeProject(":navigation:navigation-runtime-ktx", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE]) -includeProject(":navigation:navigation-runtime-truth", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":navigation:navigation-safe-args-generator", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":navigation:navigation-safe-args-gradle-plugin", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":navigation:navigation-testing", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE]) -includeProject(":navigation:navigation-ui", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":navigation:navigation-ui-ktx", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":paging:integration-tests:testapp", [BuildType.MAIN]) -includeProject(":paging:paging-common", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":paging:paging-common-ktx", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":paging:paging-compose", [BuildType.COMPOSE]) +includeProject(":navigation:navigation-runtime", "navigation/navigation-runtime", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE]) +includeProject(":navigation:navigation-runtime-ktx", "navigation/navigation-runtime-ktx", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE]) +includeProject(":navigation:navigation-runtime-truth", "navigation/navigation-runtime-truth", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":navigation:navigation-safe-args-generator", "navigation/navigation-safe-args-generator", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":navigation:navigation-safe-args-gradle-plugin", "navigation/navigation-safe-args-gradle-plugin", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":navigation:navigation-testing", "navigation/navigation-testing", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE]) +includeProject(":navigation:navigation-ui", "navigation/navigation-ui", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":navigation:navigation-ui-ktx", "navigation/navigation-ui-ktx", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":paging:integration-tests:testapp", "paging/integration-tests/testapp", [BuildType.MAIN]) +includeProject(":paging:paging-common", "paging/paging-common", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":paging:paging-common-ktx", "paging/paging-common-ktx", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":paging:paging-compose", "paging/paging-compose", [BuildType.COMPOSE]) includeProject(":paging:paging-compose:paging-compose-samples", "paging/paging-compose/samples", [BuildType.COMPOSE]) -includeProject(":paging:paging-compose:integration-tests:paging-demos", [BuildType.COMPOSE]) -includeProject(":paging:paging-guava", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":paging:paging-runtime", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":paging:paging-runtime-ktx", [BuildType.MAIN]) -includeProject(":paging:paging-rxjava2", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":paging:paging-rxjava2-ktx", [BuildType.MAIN]) -includeProject(":paging:paging-rxjava3", [BuildType.MAIN]) +includeProject(":paging:paging-compose:integration-tests:paging-demos", "paging/paging-compose/integration-tests/paging-demos", [BuildType.COMPOSE]) +includeProject(":paging:paging-guava", "paging/paging-guava", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":paging:paging-runtime", "paging/paging-runtime", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":paging:paging-runtime-ktx", "paging/paging-runtime-ktx", [BuildType.MAIN]) +includeProject(":paging:paging-rxjava2", "paging/paging-rxjava2", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":paging:paging-rxjava2-ktx", "paging/paging-rxjava2-ktx", [BuildType.MAIN]) +includeProject(":paging:paging-rxjava3", "paging/paging-rxjava3", [BuildType.MAIN]) includeProject(":paging:paging-samples", "paging/samples", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":palette:palette", [BuildType.MAIN]) -includeProject(":palette:palette-ktx", [BuildType.MAIN]) -includeProject(":percentlayout:percentlayout", [BuildType.MAIN]) -includeProject(":preference:preference", [BuildType.MAIN]) -includeProject(":preference:preference-ktx", [BuildType.MAIN]) -includeProject(":print:print", [BuildType.MAIN]) -includeProject(":profileinstaller:profileinstaller", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":profileinstaller:integration-tests:init-macrobenchmark", [BuildType.MAIN]) -includeProject(":profileinstaller:integration-tests:init-macrobenchmark-target", [BuildType.MAIN]) -includeProject(":profileinstaller:profileinstaller-benchmark", [BuildType.MAIN]) -includeProject(":recommendation:recommendation", [BuildType.MAIN]) -includeProject(":recyclerview:recyclerview", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":recyclerview:recyclerview-benchmark", [BuildType.MAIN]) -includeProject(":recyclerview:recyclerview-lint", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":recyclerview:recyclerview-selection", [BuildType.MAIN]) -includeProject(":remotecallback:remotecallback", [BuildType.MAIN]) +includeProject(":palette:palette", "palette/palette", [BuildType.MAIN]) +includeProject(":palette:palette-ktx", "palette/palette-ktx", [BuildType.MAIN]) +includeProject(":percentlayout:percentlayout", "percentlayout/percentlayout", [BuildType.MAIN]) +includeProject(":preference:preference", "preference/preference", [BuildType.MAIN]) +includeProject(":preference:preference-ktx", "preference/preference-ktx", [BuildType.MAIN]) +includeProject(":print:print", "print/print", [BuildType.MAIN]) +includeProject(":profileinstaller:profileinstaller", "profileinstaller/profileinstaller", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":profileinstaller:integration-tests:init-macrobenchmark", "profileinstaller/integration-tests/init-macrobenchmark", [BuildType.MAIN]) +includeProject(":profileinstaller:integration-tests:init-macrobenchmark-target", "profileinstaller/integration-tests/init-macrobenchmark-target", [BuildType.MAIN]) +includeProject(":profileinstaller:profileinstaller-benchmark", "profileinstaller/profileinstaller-benchmark", [BuildType.MAIN]) +includeProject(":recommendation:recommendation", "recommendation/recommendation", [BuildType.MAIN]) +includeProject(":recyclerview:recyclerview", "recyclerview/recyclerview", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":recyclerview:recyclerview-benchmark", "recyclerview/recyclerview-benchmark", [BuildType.MAIN]) +includeProject(":recyclerview:recyclerview-lint", "recyclerview/recyclerview-lint", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":recyclerview:recyclerview-selection", "recyclerview/recyclerview-selection", [BuildType.MAIN]) +includeProject(":remotecallback:remotecallback", "remotecallback/remotecallback", [BuildType.MAIN]) includeProject(":remotecallback:remotecallback-processor", "remotecallback/processor", [BuildType.MAIN]) -includeProject(":resourceinspection:resourceinspection-annotation") -includeProject(":resourceinspection:resourceinspection-processor", [BuildType.MAIN]) +includeProject(":resourceinspection:resourceinspection-annotation", "resourceinspection/resourceinspection-annotation") +includeProject(":resourceinspection:resourceinspection-processor", "resourceinspection/resourceinspection-processor", [BuildType.MAIN]) includeProject(":room:integration-tests:room-incremental-annotation-processing", "room/integration-tests/incremental-annotation-processing", [BuildType.MAIN]) includeProject(":room:integration-tests:room-testapp", "room/integration-tests/testapp", [BuildType.MAIN]) includeProject(":room:integration-tests:room-testapp-autovalue", "room/integration-tests/autovaluetestapp", [BuildType.MAIN]) includeProject(":room:integration-tests:room-testapp-kotlin", "room/integration-tests/kotlintestapp", [BuildType.MAIN]) includeProject(":room:integration-tests:room-testapp-noappcompat", "room/integration-tests/noappcompattestapp", [BuildType.MAIN]) includeProject(":room:room-benchmark", "room/benchmark", [BuildType.MAIN]) -includeProject(":room:room-common", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":room:room-compiler", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":room:room-compiler-processing", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":room:room-compiler-processing-testing", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":room:room-guava", [BuildType.MAIN]) -includeProject(":room:room-ktx", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":room:room-migration", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":room:room-paging", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":room:room-runtime", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":room:room-runtime-lint", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":room:room-rxjava2", [BuildType.MAIN]) -includeProject(":room:room-rxjava3", [BuildType.MAIN]) -includeProject(":room:room-testing", [BuildType.MAIN]) -includeProject(":savedstate:savedstate", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.WEAR]) -includeProject(":savedstate:savedstate-ktx", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN]) -includeProject(":security:security-app-authenticator", [BuildType.MAIN]) -includeProject(":security:security-app-authenticator-testing", [BuildType.MAIN]) -includeProject(":security:security-biometric", [BuildType.MAIN]) -includeProject(":security:security-crypto", [BuildType.MAIN]) -includeProject(":security:security-crypto-ktx", [BuildType.MAIN]) -includeProject(":security:security-identity-credential", [BuildType.MAIN]) -includeProject(":sharetarget:integration-tests:testapp", [BuildType.MAIN]) -includeProject(":sharetarget:sharetarget", [BuildType.MAIN]) -includeProject(":slice:slice-benchmark", [BuildType.MAIN]) -includeProject(":slice:slice-builders", [BuildType.MAIN]) -includeProject(":slice:slice-builders-ktx", [BuildType.MAIN]) -includeProject(":slice:slice-core", [BuildType.MAIN]) -includeProject(":slice:slice-remotecallback", [BuildType.MAIN]) -includeProject(":slice:slice-test", [BuildType.MAIN]) -includeProject(":slice:slice-view", [BuildType.MAIN]) -includeProject(":slidingpanelayout:slidingpanelayout", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":sqlite:integration-tests:inspection-room-testapp", [BuildType.MAIN]) -includeProject(":sqlite:integration-tests:inspection-sqldelight-testapp", [BuildType.MAIN]) -includeProject(":sqlite:sqlite", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":sqlite:sqlite-framework", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":sqlite:sqlite-inspection", [BuildType.MAIN]) -includeProject(":sqlite:sqlite-ktx", [BuildType.MAIN]) -includeProject(":startup:integration-tests:first-library", [BuildType.MAIN]) -includeProject(":startup:integration-tests:second-library", [BuildType.MAIN]) -includeProject(":startup:integration-tests:test-app", [BuildType.MAIN]) -includeProject(":startup:startup-runtime", [BuildType.MAIN]) -includeProject(":startup:startup-runtime-lint", [BuildType.MAIN]) -includeProject(":swiperefreshlayout:swiperefreshlayout", [BuildType.MAIN]) -includeProject(":template:template", [BuildType.MAIN, BuildType.GLANCE]) -includeProject(":template:template-appwidget", [BuildType.MAIN, BuildType.GLANCE]) -includeProject(":template:template-appwidget:integration-tests:demos", [BuildType.MAIN, BuildType.GLANCE]) -includeProject(":test:ext:junit-gtest", [BuildType.MAIN]) -includeProject(":test:screenshot:screenshot") +includeProject(":room:room-common", "room/room-common", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":room:room-compiler", "room/room-compiler", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":room:room-compiler-processing", "room/room-compiler-processing", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":room:room-compiler-processing-testing", "room/room-compiler-processing-testing", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":room:room-guava", "room/room-guava", [BuildType.MAIN]) +includeProject(":room:room-ktx", "room/room-ktx", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":room:room-migration", "room/room-migration", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":room:room-paging", "room/room-paging", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":room:room-runtime", "room/room-runtime", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":room:room-rxjava2", "room/room-rxjava2", [BuildType.MAIN]) +includeProject(":room:room-rxjava3", "room/room-rxjava3", [BuildType.MAIN]) +includeProject(":room:room-testing", "room/room-testing", [BuildType.MAIN]) +includeProject(":savedstate:savedstate", "savedstate/savedstate", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.WEAR]) +includeProject(":savedstate:savedstate-ktx", "savedstate/savedstate-ktx", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN]) +includeProject(":security:security-app-authenticator", "security/security-app-authenticator", [BuildType.MAIN]) +includeProject(":security:security-app-authenticator-testing", "security/security-app-authenticator-testing", [BuildType.MAIN]) +includeProject(":security:security-biometric", "security/security-biometric", [BuildType.MAIN]) +includeProject(":security:security-crypto", "security/security-crypto", [BuildType.MAIN]) +includeProject(":security:security-crypto-ktx", "security/security-crypto-ktx", [BuildType.MAIN]) +includeProject(":security:security-identity-credential", "security/security-identity-credential", [BuildType.MAIN]) +includeProject(":sharetarget:integration-tests:testapp", "sharetarget/integration-tests/testapp", [BuildType.MAIN]) +includeProject(":sharetarget:sharetarget", "sharetarget/sharetarget", [BuildType.MAIN]) +includeProject(":slice:slice-benchmark", "slice/slice-benchmark", [BuildType.MAIN]) +includeProject(":slice:slice-builders", "slice/slice-builders", [BuildType.MAIN]) +includeProject(":slice:slice-builders-ktx", "slice/slice-builders-ktx", [BuildType.MAIN]) +includeProject(":slice:slice-core", "slice/slice-core", [BuildType.MAIN]) +includeProject(":slice:slice-remotecallback", "slice/slice-remotecallback", [BuildType.MAIN]) +includeProject(":slice:slice-test", "slice/slice-test", [BuildType.MAIN]) +includeProject(":slice:slice-view", "slice/slice-view", [BuildType.MAIN]) +includeProject(":slidingpanelayout:slidingpanelayout", "slidingpanelayout/slidingpanelayout", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":sqlite:integration-tests:inspection-room-testapp", "sqlite/integration-tests/inspection-room-testapp", [BuildType.MAIN]) +includeProject(":sqlite:integration-tests:inspection-sqldelight-testapp", "sqlite/integration-tests/inspection-sqldelight-testapp", [BuildType.MAIN]) +includeProject(":sqlite:sqlite", "sqlite/sqlite", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":sqlite:sqlite-framework", "sqlite/sqlite-framework", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":sqlite:sqlite-inspection", "sqlite/sqlite-inspection", [BuildType.MAIN]) +includeProject(":sqlite:sqlite-ktx", "sqlite/sqlite-ktx", [BuildType.MAIN]) +includeProject(":startup:integration-tests:first-library", "startup/integration-tests/first-library", [BuildType.MAIN]) +includeProject(":startup:integration-tests:second-library", "startup/integration-tests/second-library", [BuildType.MAIN]) +includeProject(":startup:integration-tests:test-app", "startup/integration-tests/test-app", [BuildType.MAIN]) +includeProject(":startup:startup-runtime", "startup/startup-runtime", [BuildType.MAIN]) +includeProject(":startup:startup-runtime-lint", "startup/startup-runtime-lint", [BuildType.MAIN]) +includeProject(":swiperefreshlayout:swiperefreshlayout", "swiperefreshlayout/swiperefreshlayout", [BuildType.MAIN]) +includeProject(":template:template", "template/template", [BuildType.MAIN, BuildType.GLANCE]) +includeProject(":template:template-appwidget", "template/template-appwidget", [BuildType.MAIN, BuildType.GLANCE]) +includeProject(":template:template-appwidget:integration-tests:demos", "template/template-appwidget/integration-tests/demos", [BuildType.MAIN, BuildType.GLANCE]) + +includeProject(":test:ext:junit-gtest", "test/ext/junit-gtest", [BuildType.MAIN]) +includeProject(":test:screenshot:screenshot", "test/screenshot/screenshot") includeProject(":test:screenshot:screenshot-proto", "test/screenshot/screenshot/proto", [BuildType.MAIN]) -includeProject(":text:text", [BuildType.COMPOSE]) -includeProject(":textclassifier:integration-tests:testapp", [BuildType.MAIN]) -includeProject(":textclassifier:textclassifier", [BuildType.MAIN]) -includeProject(":tracing:tracing") -includeProject(":tracing:tracing-ktx") -includeProject(":tracing:tracing-perfetto", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":tracing:tracing-perfetto-binary", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":transition:transition", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":transition:transition-ktx", [BuildType.MAIN, BuildType.FLAN]) -includeProject(":tvprovider:tvprovider", [BuildType.MAIN]) -includeProject(":vectordrawable:integration-tests:testapp", [BuildType.MAIN]) -includeProject(":vectordrawable:vectordrawable", [BuildType.MAIN]) -includeProject(":vectordrawable:vectordrawable-animated", [BuildType.MAIN]) -includeProject(":vectordrawable:vectordrawable-seekable", [BuildType.MAIN]) -includeProject(":versionedparcelable:versionedparcelable", [BuildType.MAIN]) -includeProject(":versionedparcelable:versionedparcelable-compiler", [BuildType.MAIN, BuildType.MEDIA, BuildType.FLAN, BuildType.COMPOSE, BuildType.WEAR]) -includeProject(":viewpager2:integration-tests:testapp", [BuildType.MAIN]) -includeProject(":viewpager2:integration-tests:targetsdk-tests", [BuildType.MAIN]) -includeProject(":viewpager2:viewpager2", [BuildType.MAIN]) -includeProject(":viewpager:viewpager", [BuildType.MAIN]) -includeProject(":wear:wear", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:benchmark:integration-tests:macrobenchmark-target", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":wear:benchmark:integration-tests:macrobenchmark", [BuildType.MAIN, BuildType.COMPOSE]) -includeProject(":wear:compose:compose-foundation", [BuildType.COMPOSE]) +includeProject(":text:text", "text/text", [BuildType.COMPOSE]) +includeProject(":textclassifier:integration-tests:testapp", "textclassifier/integration-tests/testapp", [BuildType.MAIN]) +includeProject(":textclassifier:textclassifier", "textclassifier/textclassifier", [BuildType.MAIN]) +includeProject(":tracing:tracing", "tracing/tracing") +includeProject(":tracing:tracing-ktx", "tracing/tracing-ktx") +includeProject(":tracing:tracing-perfetto", "tracing/tracing-perfetto", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":tracing:tracing-perfetto-binary", "tracing/tracing-perfetto-binary", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":transition:transition", "transition/transition", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":transition:transition-ktx", "transition/transition-ktx", [BuildType.MAIN, BuildType.FLAN]) +includeProject(":tvprovider:tvprovider", "tvprovider/tvprovider", [BuildType.MAIN]) +includeProject(":vectordrawable:integration-tests:testapp", "vectordrawable/integration-tests/testapp", [BuildType.MAIN]) +includeProject(":vectordrawable:vectordrawable", "vectordrawable/vectordrawable", [BuildType.MAIN]) +includeProject(":vectordrawable:vectordrawable-animated", "vectordrawable/vectordrawable-animated", [BuildType.MAIN]) +includeProject(":vectordrawable:vectordrawable-seekable", "vectordrawable/vectordrawable-seekable", [BuildType.MAIN]) +includeProject(":versionedparcelable:versionedparcelable", "versionedparcelable/versionedparcelable", [BuildType.MAIN]) +includeProject(":versionedparcelable:versionedparcelable-compiler", "versionedparcelable/versionedparcelable-compiler", [BuildType.MAIN, BuildType.MEDIA, BuildType.FLAN, BuildType.COMPOSE, BuildType.WEAR]) +includeProject(":viewpager2:integration-tests:testapp", "viewpager2/integration-tests/testapp", [BuildType.MAIN]) +includeProject(":viewpager2:integration-tests:targetsdk-tests", "viewpager2/integration-tests/targetsdk-tests", [BuildType.MAIN]) +includeProject(":viewpager2:viewpager2", "viewpager2/viewpager2", [BuildType.MAIN]) +includeProject(":viewpager:viewpager", "viewpager/viewpager", [BuildType.MAIN]) +includeProject(":wear:wear", "wear/wear", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:benchmark:integration-tests:macrobenchmark-target", "wear/benchmark/integration-tests/macrobenchmark-target", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":wear:benchmark:integration-tests:macrobenchmark", "wear/benchmark/integration-tests/macrobenchmark", [BuildType.MAIN, BuildType.COMPOSE]) +includeProject(":wear:compose:compose-foundation", "wear/compose/compose-foundation", [BuildType.COMPOSE]) includeProject(":wear:compose:compose-foundation-samples", "wear/compose/compose-foundation/samples", [BuildType.COMPOSE]) -includeProject(":wear:compose:compose-material", [BuildType.COMPOSE]) +includeProject(":wear:compose:compose-material", "wear/compose/compose-material", [BuildType.COMPOSE]) includeProject(":wear:compose:compose-material-benchmark", "wear/compose/compose-material/benchmark", [BuildType.COMPOSE]) includeProject(":wear:compose:compose-material-samples", "wear/compose/compose-material/samples", [BuildType.COMPOSE]) -includeProject(":wear:compose:compose-navigation", [BuildType.COMPOSE]) +includeProject(":wear:compose:compose-navigation", "wear/compose/compose-navigation", [BuildType.COMPOSE]) includeProject(":wear:compose:compose-navigation-samples", "wear/compose/compose-navigation/samples", [BuildType.COMPOSE]) -includeProject(":wear:compose:integration-tests:demos", [BuildType.COMPOSE]) -includeProject(":wear:compose:integration-tests:macrobenchmark", [BuildType.COMPOSE]) -includeProject(":wear:compose:integration-tests:macrobenchmark-target", [BuildType.COMPOSE]) -includeProject(":wear:compose:integration-tests:navigation", [BuildType.COMPOSE]) -includeProject(":wear:wear-input", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:compose:integration-tests:demos", "wear/compose/integration-tests/demos", [BuildType.COMPOSE]) +includeProject(":wear:compose:integration-tests:macrobenchmark", "wear/compose/integration-tests/macrobenchmark", [BuildType.COMPOSE]) +includeProject(":wear:compose:integration-tests:macrobenchmark-target", "wear/compose/integration-tests/macrobenchmark-target", [BuildType.COMPOSE]) +includeProject(":wear:compose:integration-tests:navigation", "wear/compose/integration-tests/navigation", [BuildType.COMPOSE]) +includeProject(":wear:wear-input", "wear/wear-input", [BuildType.MAIN, BuildType.WEAR]) includeProject(":wear:wear-input-samples", "wear/wear-input/samples", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:wear-input-testing", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:wear-ongoing", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:wear-phone-interactions", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:wear-remote-interactions", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:wear-samples-ambient", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:tiles:tiles", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:tiles:tiles-material", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:tiles:tiles-proto", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:tiles:tiles-renderer", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:tiles:tiles-testing", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:watchface:watchface", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:watchface:watchface-complications", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:watchface:watchface-complications-permission-dialogs-sample", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:watchface:watchface-complications-data", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:watchface:watchface-complications-data-source", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:watchface:watchface-complications-data-source-ktx", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:watchface:watchface-complications-data-source-samples", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:watchface:watchface-complications-rendering", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:watchface:watchface-client", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:watchface:watchface-client-guava", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:watchface:watchface-data", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:watchface:watchface-editor", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:watchface:watchface-editor-guava", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:wear-input-testing", "wear/wear-input-testing", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:wear-ongoing", "wear/wear-ongoing", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:wear-phone-interactions", "wear/wear-phone-interactions", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:wear-remote-interactions", "wear/wear-remote-interactions", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:wear-samples-ambient", "wear/wear-samples-ambient", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:tiles:tiles", "wear/tiles/tiles", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:tiles:tiles-material", "wear/tiles/tiles-material", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:tiles:tiles-proto", "wear/tiles/tiles-proto", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:tiles:tiles-renderer", "wear/tiles/tiles-renderer", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:tiles:tiles-testing", "wear/tiles/tiles-testing", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:watchface:watchface", "wear/watchface/watchface", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:watchface:watchface-complications", "wear/watchface/watchface-complications", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:watchface:watchface-complications-permission-dialogs-sample", "wear/watchface/watchface-complications-permission-dialogs-sample", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:watchface:watchface-complications-data", "wear/watchface/watchface-complications-data", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:watchface:watchface-complications-data-source", "wear/watchface/watchface-complications-data-source", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:watchface:watchface-complications-data-source-ktx", "wear/watchface/watchface-complications-data-source-ktx", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:watchface:watchface-complications-data-source-samples", "wear/watchface/watchface-complications-data-source-samples", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:watchface:watchface-complications-rendering", "wear/watchface/watchface-complications-rendering", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:watchface:watchface-client", "wear/watchface/watchface-client", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:watchface:watchface-client-guava", "wear/watchface/watchface-client-guava", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:watchface:watchface-data", "wear/watchface/watchface-data", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:watchface:watchface-editor", "wear/watchface/watchface-editor", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:watchface:watchface-editor-guava", "wear/watchface/watchface-editor-guava", [BuildType.MAIN, BuildType.WEAR]) includeProject(":wear:watchface:watchface-editor-samples", "wear/watchface/watchface-editor/samples", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:watchface:watchface-guava", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:watchface:watchface-guava", "wear/watchface/watchface-guava", [BuildType.MAIN, BuildType.WEAR]) includeProject(":wear:watchface:watchface-samples", "wear/watchface/watchface/samples", [BuildType.MAIN, BuildType.WEAR]) includeProject(":wear:watchface:watchface-samples-app", "wear/watchface/watchface/samples/app", [BuildType.MAIN, BuildType.WEAR]) includeProject(":wear:watchface:watchface-samples-minimal", "wear/watchface/watchface/samples/minimal", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:watchface:watchface-samples-minimal-complications", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:watchface:watchface-samples-minimal-style", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":wear:watchface:watchface-style", [BuildType.MAIN, BuildType.WEAR]) -includeProject(":webkit:integration-tests:testapp", [BuildType.MAIN]) -includeProject(":webkit:webkit", [BuildType.MAIN]) -includeProject(":window:window", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN]) -includeProject(":window:extensions:extensions", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN]) -includeProject(":window:sidecar:sidecar", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN]) -includeProject(":window:window-java", [BuildType.MAIN]) -includeProject(":window:window-rxjava2", [BuildType.MAIN]) -includeProject(":window:window-rxjava3", [BuildType.MAIN]) -includeProject(":window:window-samples", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN]) -includeProject(":window:window-testing", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN]) -includeProject(":work:integration-tests:testapp", [BuildType.MAIN]) -includeProject(":work:work-benchmark", [BuildType.MAIN]) -includeProject(":work:work-gcm", [BuildType.MAIN]) -includeProject(":work:work-inspection", [BuildType.MAIN]) -includeProject(":work:work-multiprocess", [BuildType.MAIN]) -includeProject(":work:work-runtime", [BuildType.MAIN]) -includeProject(":work:work-runtime-ktx", [BuildType.MAIN]) +includeProject(":wear:watchface:watchface-samples-minimal-complications", "wear/watchface/watchface-samples-minimal-complications", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:watchface:watchface-samples-minimal-style", "wear/watchface/watchface-samples-minimal-style", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":wear:watchface:watchface-style", "wear/watchface/watchface-style", [BuildType.MAIN, BuildType.WEAR]) +includeProject(":webkit:integration-tests:testapp", "webkit/integration-tests/testapp", [BuildType.MAIN]) +includeProject(":webkit:webkit", "webkit/webkit", [BuildType.MAIN]) +includeProject(":window:window", "window/window", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN]) +includeProject(":window:extensions:extensions", "window/extensions/extensions", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN]) +includeProject(":window:sidecar:sidecar", "window/sidecar/sidecar", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN]) +includeProject(":window:window-java", "window/window-java", [BuildType.MAIN]) +includeProject(":window:window-rxjava2", "window/window-rxjava2", [BuildType.MAIN]) +includeProject(":window:window-rxjava3", "window/window-rxjava3", [BuildType.MAIN]) +includeProject(":window:window-samples", "window/window-samples", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN]) +includeProject(":window:window-testing", "window/window-testing", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN]) +includeProject(":work:integration-tests:testapp", "work/integration-tests/testapp", [BuildType.MAIN]) +includeProject(":work:work-benchmark", "work/work-benchmark", [BuildType.MAIN]) +includeProject(":work:work-gcm", "work/work-gcm", [BuildType.MAIN]) +includeProject(":work:work-inspection", "work/work-inspection", [BuildType.MAIN]) +includeProject(":work:work-multiprocess", "work/work-multiprocess", [BuildType.MAIN]) +includeProject(":work:work-runtime", "work/work-runtime", [BuildType.MAIN]) +includeProject(":work:work-runtime-ktx", "work/work-runtime-ktx", [BuildType.MAIN]) includeProject(":work:work-runtime-lint", "work/work-lint", [BuildType.MAIN]) -includeProject(":work:work-rxjava2", [BuildType.MAIN]) -includeProject(":work:work-rxjava3", [BuildType.MAIN]) -includeProject(":work:work-testing", [BuildType.MAIN]) +includeProject(":work:work-rxjava2", "work/work-rxjava2", [BuildType.MAIN]) +includeProject(":work:work-rxjava3", "work/work-rxjava3", [BuildType.MAIN]) +includeProject(":work:work-testing", "work/work-testing", [BuildType.MAIN]) ///////////////////////////// // @@ -858,7 +856,8 @@ includeProject(":media:version-compat-tests:service", "media/version-compat-tests/current/service", [BuildType.MAIN, BuildType.MEDIA]) includeProject(":media:version-compat-tests:service-previous", "media/version-compat-tests/previous/service", [BuildType.MAIN, BuildType.MEDIA]) -includeProject(":media:version-compat-tests:lib", [BuildType.MAIN, BuildType.MEDIA]) +includeProject(":media:version-compat-tests:lib", "media/version-compat-tests/lib", + [BuildType.MAIN, BuildType.MEDIA]) includeProject(":media2:media2-session:version-compat-tests:client", "media2/media2-session/version-compat-tests/current/client", [BuildType.MAIN, BuildType.MEDIA]) @@ -868,7 +867,8 @@ includeProject(":media2:media2-session:version-compat-tests:service", "media2/media2-session/version-compat-tests/current/service", [BuildType.MAIN, BuildType.MEDIA]) includeProject(":media2:media2-session:version-compat-tests:service-previous", "media2/media2-session/version-compat-tests/previous/service", [BuildType.MAIN, BuildType.MEDIA]) -includeProject(":media2:media2-session:version-compat-tests:common", [BuildType.MAIN, BuildType.MEDIA]) +includeProject(":media2:media2-session:version-compat-tests:common", + "media2/media2-session/version-compat-tests/common", [BuildType.MAIN, BuildType.MEDIA]) ///////////////////////////// // @@ -881,20 +881,20 @@ File externalRoot = new File(rootDir, "../../external") includeProject(":icing", new File(externalRoot, "icing"), [BuildType.MAIN]) includeProject(":icing:nativeLib", new File(externalRoot, "icing/nativeLib"), [BuildType.MAIN]) -includeProject(":external:libyuv", [BuildType.MAIN]) +includeProject(":external:libyuv", "external/libyuv", [BuildType.MAIN]) includeProject(":noto-emoji-compat-font", new File(externalRoot, "noto-fonts/emoji-compat"), [BuildType.MAIN]) includeProject(":noto-emoji-compat-flatbuffers", new File(externalRoot, "noto-fonts/emoji-compat-flatbuffers"), [BuildType.MAIN]) if (isAllProjects()) { - includeProject(":docs-tip-of-tree") - includeProject(":docs-public") + includeProject(":docs-tip-of-tree", "docs-tip-of-tree") + includeProject(":docs-public", "docs-public") } // placeholder test project that has a test for each size to ensure that at least one test is run // for each size and test runner is happy when there is nothing to test. -includeProject(":placeholder-tests") +includeProject(":placeholder-tests", "placeholder-tests") -includeProject(":fakeannotations") +includeProject(":fakeannotations", "fakeannotations") ///////////////////////////// // diff --git a/wear/tiles/tiles-material/src/main/java/androidx/wear/tiles/material/layouts/MultiSlotLayout.java b/wear/tiles/tiles-material/src/main/java/androidx/wear/tiles/material/layouts/MultiSlotLayout.java index 246f664d0c0..f4529bc8383 100644 --- a/wear/tiles/tiles-material/src/main/java/androidx/wear/tiles/material/layouts/MultiSlotLayout.java +++ b/wear/tiles/tiles-material/src/main/java/androidx/wear/tiles/material/layouts/MultiSlotLayout.java @@ -156,8 +156,8 @@ public class MultiSlotLayout implements LayoutElement { @NonNull @Override // The @Dimension(unit = DP) on mVerticalSpacerHeight.getValue() is seemingly being ignored, - // so lint complains that we're passing PX to something expecting DP. Just suppress the - // warning for now. + // so lint complains that we're passing PX to something expecting DP. + // Just suppress the warning for now. @SuppressLint("ResourceType") public MultiSlotLayout build() { PrimaryLayout.Builder layoutBuilder = new PrimaryLayout.Builder(mDeviceParameters); |