Merge "Marking SystemAlarmDispatcherTest#testDelayMet_withUnMetConstraint() a @LargeTest." into pi-preview1-androidx-dev
diff --git a/buildSrc/init.gradle b/buildSrc/init.gradle
index eddb3a6..ce416f9 100644
--- a/buildSrc/init.gradle
+++ b/buildSrc/init.gradle
@@ -167,7 +167,11 @@
buildOnServerTask.dependsOn task
}
}
+ def docsProject = rootProject.findProject(":docs-fake")
subprojects {
+ if (docsProject == project) {
+ return
+ }
project.tasks.whenTaskAdded { task ->
if ("assembleErrorProne".equals(task.name)
|| "assembleAndroidTest".equals(task.name)
diff --git a/buildSrc/repos.gradle b/buildSrc/repos.gradle
index f3d71e6..d6f69af 100644
--- a/buildSrc/repos.gradle
+++ b/buildSrc/repos.gradle
@@ -47,7 +47,9 @@
// Full checkout prebuilts updated by update_current.py
"${repos.prebuiltsRoot}/sdk/current/support/m2repository",
// Unbundled checkout prebuilts updated by fullsdk drop
- "${getFullSdkPath(repos.prebuiltsRoot)}/extras/android/m2repository"]
+ "${getFullSdkPath(repos.prebuiltsRoot)}/extras/android/m2repository",
+ // temporary: com.android.support.constraint:constraint-layout:1.0.2 is there
+ "${getFullSdkPath(repos.prebuiltsRoot)}/extras/m2repository/"]
/**
* Adds maven repositories to the given repository handler.
diff --git a/buildSrc/src/main/kotlin/androidx/build/DiffAndDocs.kt b/buildSrc/src/main/kotlin/androidx/build/DiffAndDocs.kt
index 40d3802..c167769 100644
--- a/buildSrc/src/main/kotlin/androidx/build/DiffAndDocs.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/DiffAndDocs.kt
@@ -16,43 +16,152 @@
package androidx.build
+import androidx.build.PublishDocsRules.Strategy.Prebuilts
+import androidx.build.PublishDocsRules.Strategy.TipOfTree
import androidx.build.checkapi.ApiXmlConversionTask
import androidx.build.checkapi.CheckApiTask
import androidx.build.checkapi.UpdateApiTask
import androidx.build.doclava.DoclavaTask
import androidx.build.docs.GenerateDocsTask
import androidx.build.jdiff.JDiffTask
+import com.android.build.gradle.AppExtension
import com.android.build.gradle.LibraryExtension
+import com.android.build.gradle.api.BaseVariant
import com.android.build.gradle.api.LibraryVariant
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.artifacts.Configuration
import org.gradle.api.file.FileCollection
+import org.gradle.api.file.FileTree
import org.gradle.api.plugins.JavaBasePlugin
import org.gradle.api.tasks.TaskContainer
import org.gradle.api.tasks.bundling.Zip
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.api.tasks.javadoc.Javadoc
import java.io.File
+import kotlin.collections.Collection
+import kotlin.collections.List
+import kotlin.collections.MutableMap
+import kotlin.collections.emptyList
+import kotlin.collections.emptySet
+import kotlin.collections.filter
+import kotlin.collections.find
+import kotlin.collections.forEach
+import kotlin.collections.listOf
+import kotlin.collections.mapNotNull
+import kotlin.collections.minus
+import kotlin.collections.mutableMapOf
+import kotlin.collections.plus
+import kotlin.collections.set
+import kotlin.collections.toList
+import kotlin.collections.toSet
data class DacOptions(val libraryroot: String, val dataname: String)
object DiffAndDocs {
private lateinit var allChecksTask: Task
private lateinit var generateDocsTask: GenerateDocsTask
+ private var docsProject: Project? = null
+
+ private val rules: List<PublishDocsRules> = listOf(RELEASE_RULE)
+ private val docsTasks: MutableMap<String, DoclavaTask> = mutableMapOf()
@JvmStatic
fun configureDiffAndDocs(root: Project, supportRootFolder: File, dacOptions: DacOptions): Task {
+ docsProject = root.findProject(":docs-fake")
allChecksTask = root.tasks.create("anchorCheckApis")
val doclavaConfiguration = root.configurations.getByName("doclava")
val generateSdkApiTask = createGenerateSdkApiTask(root, doclavaConfiguration)
- generateDocsTask = createGenerateDocsTask(root, generateSdkApiTask,
- doclavaConfiguration, supportRootFolder, dacOptions)
+ generateDocsTask = createGenerateDocsTask(
+ project = root, generateSdkApiTask = generateSdkApiTask,
+ doclavaConfig = doclavaConfiguration, supportRootFolder = supportRootFolder,
+ dacOptions = dacOptions, destDir = root.docsDir())
+
+ rules.forEach {
+ val task = createGenerateDocsTask(
+ project = root, generateSdkApiTask = generateSdkApiTask,
+ doclavaConfig = doclavaConfiguration,
+ supportRootFolder = supportRootFolder, dacOptions = dacOptions,
+ destDir = File(root.docsDir(), it.name),
+ taskName = "${it.name}DocsTask")
+ docsTasks[it.name] = task
+ }
+
+ setupDocsProject()
createDistDocsTask(root, generateDocsTask)
return allChecksTask
}
+ private fun prebuiltSources(root: Project, mavenId: String): FileTree {
+ val configName = "docs-temp_$mavenId"
+ val configuration = root.configurations.create(configName)
+ root.dependencies.add(configName, mavenId)
+
+ val artifacts = configuration.resolvedConfiguration.resolvedArtifacts
+ val artifact = artifacts.find { it.moduleVersion.id.toString() == mavenId }
+ ?: throw GradleException("Failed to resolve $mavenId")
+
+ val folder = artifact.file.parentFile
+ val tree = root.zipTree(File(folder, "${artifact.file.nameWithoutExtension}-sources.jar"))
+ .matching {
+ it.exclude("**/*.MF")
+ it.exclude("**/*.aidl")
+ it.exclude("**/*.html")
+ it.exclude("**/*.kt")
+ }
+ root.configurations.remove(configuration)
+ return tree
+ }
+
+ private fun setupDocsProject() {
+ docsProject?.afterEvaluate { docs ->
+ val appExtension = docs.extensions.findByType(AppExtension::class.java)
+ ?: throw GradleException("Android app plugin is missing on docsProject")
+
+ rules.forEach { rule ->
+ appExtension.productFlavors.create(rule.name) {
+ it.dimension = "library-group"
+ }
+ }
+ appExtension.applicationVariants.all { v ->
+ val task = docsTasks[v.flavorName]
+ if (v.buildType.name == "release" && task != null) {
+ registerAndroidProjectForDocsTask(task, v)
+ task.exclude { fileTreeElement ->
+ fileTreeElement.path.endsWith(v.rFile())
+ }
+ }
+ }
+ }
+
+ docsProject?.rootProject?.subprojects
+ ?.filter { docsProject != it }
+ ?.forEach { docsProject?.evaluationDependsOn(it.path) }
+ }
+
+ private fun registerPrebuilts(extension: SupportLibraryExtension)
+ = docsProject?.afterEvaluate { docs ->
+ val depHandler = docs.dependencies
+ val root = docs.rootProject
+ rules.mapNotNull { rule ->
+ (rule.resolve(extension) as? Prebuilts)?.let { rule.name to it } }
+ .forEach { (name, prebuilt) ->
+ val dependency = prebuilt.dependency(extension)
+ depHandler.add("${name}Implementation", dependency)
+ prebuilt.stubs?.forEach { path ->
+ depHandler.add("${name}CompileOnly", root.files(path))
+ }
+ docsTasks[name]!!.source(prebuiltSources(root, dependency))
+ }
+ }
+
+ private fun tipOfTreeTasks(extension: SupportLibraryExtension, setup: (DoclavaTask) -> Unit) {
+ rules.filter { rule -> rule.resolve(extension) == TipOfTree }
+ .mapNotNull { rule -> docsTasks[rule.name] }
+ .forEach(setup)
+ }
+
/**
* Registers a Java project for global docs generation, local API file generation, and
* local API diff generation tasks.
@@ -63,7 +172,14 @@
}
val compileJava = project.properties["compileJava"] as JavaCompile
registerJavaProjectForDocsTask(generateDocsTask, compileJava)
- if (!hasApiFolder(project)) {
+
+ registerPrebuilts(extension)
+
+ tipOfTreeTasks(extension) { task ->
+ registerJavaProjectForDocsTask(task, compileJava)
+ }
+
+ if (!project.hasApiFolder()) {
project.logger.info("Project ${project.name} doesn't have an api folder, " +
"ignoring API tasks.")
return
@@ -86,13 +202,28 @@
if (!hasApiTasks(project, extension)) {
return
}
+
+ registerPrebuilts(extension)
+
library.libraryVariants.all { variant ->
if (variant.name == "release") {
registerAndroidProjectForDocsTask(generateDocsTask, variant)
- if (!hasJavaSources(variant)) {
+
+ // include R.file generated for prebuilts
+ rules.filter { it.resolve(extension) is Prebuilts }.forEach { rule ->
+ docsTasks[rule.name]?.include { fileTreeElement ->
+ fileTreeElement.path.endsWith(variant.rFile())
+ }
+ }
+
+ tipOfTreeTasks(extension) { task ->
+ registerAndroidProjectForDocsTask(task, variant)
+ }
+
+ if (!variant.hasJavaSources()) {
return@all
}
- if (!hasApiFolder(project)) {
+ if (!project.hasApiFolder()) {
project.logger.info("Project ${project.name} doesn't have " +
"an api folder, ignoring API tasks.")
return@all
@@ -119,7 +250,7 @@
"annotation paired with the @RestrictTo(LIBRARY_GROUP) code annotation."
@Suppress("DEPRECATION")
-private fun hasJavaSources(variant: LibraryVariant) = !variant.javaCompile.source
+private fun LibraryVariant.hasJavaSources() = !javaCompile.source
.filter { file -> file.name != "R.java" && file.name != "BuildConfig.java" }
.isEmpty
@@ -155,7 +286,7 @@
onFailMessage = "Public API definition may not change in finalized or patch releases.\n" +
"\n" + MSG_HIDE_API)
-private fun hasApiFolder(project: Project) = File(project.projectDir, "api").exists()
+fun Project.hasApiFolder() = File(projectDir, "api").exists()
private fun stripExtension(fileName: String) = fileName.substringBeforeLast('.')
@@ -273,17 +404,15 @@
* <p>
* @see #registerJavaProjectForDocsTask
*/
-private fun registerAndroidProjectForDocsTask(task: Javadoc, releaseVariant: LibraryVariant) {
+private fun registerAndroidProjectForDocsTask(task: Javadoc, releaseVariant: BaseVariant) {
// This code makes a number of unsafe assumptions about Android Gradle Plugin,
// and there's a good chance that this will break in the near future.
@Suppress("DEPRECATION")
task.dependsOn(releaseVariant.javaCompile)
- val packageDir = releaseVariant.applicationId.replace('.', '/')
+ task.include { fileTreeElement ->
+ fileTreeElement.name != "R.java" || fileTreeElement.path.endsWith(releaseVariant.rFile()) }
@Suppress("DEPRECATION")
- val sources = releaseVariant.javaCompile.source.filter { file ->
- file.name != "R.java" || file.parent.endsWith(packageDir)
- }
- task.source(sources)
+ task.source(releaseVariant.javaCompile.source)
@Suppress("DEPRECATION")
task.classpath += releaseVariant.getCompileClasspath(null) +
task.project.files(releaseVariant.javaCompile.destinationDir)
@@ -467,8 +596,10 @@
generateSdkApiTask: DoclavaTask,
doclavaConfig: Configuration,
supportRootFolder: File,
- dacOptions: DacOptions): GenerateDocsTask =
- project.tasks.createWithConfig("generateDocs", GenerateDocsTask::class.java) {
+ dacOptions: DacOptions,
+ destDir: File,
+ taskName: String = "generateDocs"): GenerateDocsTask =
+ project.tasks.createWithConfig(taskName, GenerateDocsTask::class.java) {
dependsOn(generateSdkApiTask, doclavaConfig)
group = JavaBasePlugin.DOCUMENTATION_GROUP
description = "Generates d.android.com-style documentation. To generate offline docs " +
@@ -476,9 +607,9 @@
setDocletpath(doclavaConfig.resolve())
val offline = project.processProperty("offlineDocs") != null
- destinationDir = File(project.docsDir(), if (offline) "offline" else "online")
+ destinationDir = File(destDir, if (offline) "offline" else "online")
classpath = androidJarFile(project)
- val hidden = listOf<Int>(105, 106, 107, 111, 112, 113, 115, 116, 121)
+ val hidden = listOf(105, 106, 107, 111, 112, 113, 115, 116, 121)
doclavaErrors = ((101..122) - hidden).toSet()
doclavaWarnings = emptySet()
doclavaHidden += hidden
@@ -619,6 +750,14 @@
private fun androidSrcJarFile(project: Project): File = File(project.fullSdkPath(),
"platforms/android-${SupportConfig.CURRENT_SDK_VERSION}/android-stubs-src.jar")
+private fun PublishDocsRules.resolve(extension: SupportLibraryExtension) =
+ resolve(extension.mavenGroup!!, extension.project.name)
+
+private fun Prebuilts.dependency(extension: SupportLibraryExtension) =
+ "${extension.mavenGroup}:${extension.project.name}:$version"
+
+private fun BaseVariant.rFile() = "${applicationId.replace('.', '/')}/R.java"
+
// Nasty part. Get rid of that eventually!
private fun Project.docsDir(): File = properties["docsDir"] as File
diff --git a/buildSrc/src/main/kotlin/androidx/build/PublishDocsRules.kt b/buildSrc/src/main/kotlin/androidx/build/PublishDocsRules.kt
new file mode 100644
index 0000000..511d961
--- /dev/null
+++ b/buildSrc/src/main/kotlin/androidx/build/PublishDocsRules.kt
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2018 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 androidx.build.PublishDocsRules.Strategy.TipOfTree
+import androidx.build.PublishDocsRules.Strategy.Prebuilts
+import androidx.build.PublishDocsRules.Strategy.Ignore
+
+val RELEASE_RULE = docsRules("public") {
+ val defaultVersion = "1.0.0-alpha1"
+ prebuilts(LibraryGroups.ANNOTATION, defaultVersion)
+ prebuilts(LibraryGroups.APPCOMPAT, defaultVersion)
+ prebuilts(LibraryGroups.ASYNCLAYOUTINFLATER, defaultVersion)
+ prebuilts(LibraryGroups.BROWSER, defaultVersion)
+ prebuilts(LibraryGroups.CAR, defaultVersion)
+ .addStubs("car/car-stubs/android.car.jar")
+ prebuilts(LibraryGroups.CARDVIEW, defaultVersion)
+ prebuilts(LibraryGroups.COLLECTION, defaultVersion)
+ // misses prebuilts, because it was released under different name in alpha1
+ tipOfTree(LibraryGroups.CONTENTPAGER)
+
+ prebuilts(LibraryGroups.COORDINATORLAYOUT, defaultVersion)
+ prebuilts(LibraryGroups.CORE, defaultVersion)
+ prebuilts(LibraryGroups.CURSORADAPTER, defaultVersion)
+ prebuilts(LibraryGroups.CUSTOMVIEW, defaultVersion)
+ prebuilts(LibraryGroups.DOCUMENTFILE, defaultVersion)
+ prebuilts(LibraryGroups.DRAWERLAYOUT, defaultVersion)
+ prebuilts(LibraryGroups.DYNAMICANIMATION, defaultVersion)
+ prebuilts(LibraryGroups.EMOJI, defaultVersion)
+ prebuilts(LibraryGroups.EXIFINTERFACE, defaultVersion)
+ prebuilts(LibraryGroups.FRAGMENT, defaultVersion)
+ prebuilts(LibraryGroups.GRIDLAYOUT, defaultVersion)
+ prebuilts(LibraryGroups.HEIFWRITER, defaultVersion)
+ prebuilts(LibraryGroups.INTERPOLATOR, defaultVersion)
+ prebuilts(LibraryGroups.LEANBACK, defaultVersion)
+ prebuilts(LibraryGroups.LEGACY, defaultVersion)
+ prebuilts(LibraryGroups.LOADER, defaultVersion)
+ prebuilts(LibraryGroups.LOCALBROADCASTMANAGER, defaultVersion)
+ prebuilts(LibraryGroups.MEDIA, defaultVersion)
+ prebuilts(LibraryGroups.MEDIAROUTER, defaultVersion)
+ prebuilts(LibraryGroups.PALETTE, defaultVersion)
+ prebuilts(LibraryGroups.PERCENTLAYOUT, defaultVersion)
+ prebuilts(LibraryGroups.PREFERENCE, defaultVersion)
+ prebuilts(LibraryGroups.PRINT, defaultVersion)
+ prebuilts(LibraryGroups.RECOMMENDATION, defaultVersion)
+ prebuilts(LibraryGroups.RECYCLERVIEW, defaultVersion)
+ prebuilts(LibraryGroups.SLICE, defaultVersion)
+ prebuilts(LibraryGroups.SLIDINGPANELAYOUT, defaultVersion)
+ prebuilts(LibraryGroups.SWIPEREFRESHLAYOUT, defaultVersion)
+ prebuilts(LibraryGroups.TEXTCLASSIFIER, defaultVersion)
+ prebuilts(LibraryGroups.TRANSITION, defaultVersion)
+ prebuilts(LibraryGroups.TVPROVIDER, defaultVersion)
+ prebuilts(LibraryGroups.VECTORDRAWABLE, defaultVersion)
+ prebuilts(LibraryGroups.VIEWPAGER, defaultVersion)
+ prebuilts(LibraryGroups.VIEWPAGER2, defaultVersion)
+ prebuilts(LibraryGroups.WEAR, defaultVersion)
+ .addStubs("wear/wear_stubs/com.google.android.wearable-stubs.jar")
+ prebuilts(LibraryGroups.WEBKIT, defaultVersion)
+ val flatfootVersion = "2.0.0-alpha1"
+ prebuilts(LibraryGroups.ROOM, flatfootVersion)
+ prebuilts(LibraryGroups.PERSISTENCE, flatfootVersion)
+ // lifecycle-viewmodel-ktx / lifecycle-process / lifecycle-service miss their prebuilts
+ tipOfTree(LibraryGroups.LIFECYCLE, "lifecycle-viewmodel-ktx")
+ tipOfTree(LibraryGroups.LIFECYCLE, "lifecycle-process")
+ tipOfTree(LibraryGroups.LIFECYCLE, "lifecycle-service")
+ prebuilts(LibraryGroups.LIFECYCLE, flatfootVersion)
+ prebuilts(LibraryGroups.ARCH_CORE, flatfootVersion)
+ prebuilts(LibraryGroups.PAGING, "paging-rxjava2", "1.0.0-alpha1")
+ prebuilts(LibraryGroups.PAGING, "2.0.0-alpha1")
+ // navigation & workmanager don't have prebuilts currently
+ tipOfTree(LibraryGroups.NAVIGATION)
+ tipOfTree(LibraryGroups.WORKMANAGER)
+ default(Ignore)
+}
+
+typealias ArtifactsPredicate = (String, String) -> Boolean
+
+/**
+ * Rules are resolved in addition order. So if you have two rules that specify how docs should be
+ * built for a module, first defined rule wins.
+ */
+fun docsRules(name: String, init: PublishDocsRulesBuilder.() -> Unit): PublishDocsRules {
+ val f = PublishDocsRulesBuilder(name)
+ f.init()
+ return f.build()
+}
+
+class PublishDocsRulesBuilder(private val name: String) {
+
+ private val rules: MutableList<Pair<ArtifactsPredicate, PublishDocsRules.Strategy>>
+ = mutableListOf()
+
+ private fun groupPredicate(name: String) = { group: String, _: String -> name == group }
+
+ private fun artifactPredicate(group: String, name: String) = {
+ inGroup: String, inName: String -> group == inGroup && name == inName }
+
+ private val allPredicate = { _: String, _: String -> true }
+
+ /**
+ * docs for projects within [groupName] will be built from sources.
+ */
+ fun tipOfTree(groupName: String) {
+ rules.add(groupPredicate(groupName) to TipOfTree)
+ }
+
+ /**
+ * docs for a project with the given [groupName] and [name] will be built from sources.
+ */
+ fun tipOfTree(groupName: String, name: String) {
+ rules.add(artifactPredicate(groupName, name) to TipOfTree)
+ }
+
+ /**
+ * docs for a project with the given [groupName] and [name] will be built from a prebuilt with
+ * the given [version].
+ */
+ fun prebuilts(groupName: String, moduleName: String , version: String) {
+ rules.add(artifactPredicate(groupName, moduleName) to Prebuilts(Version(version)))
+ }
+
+ /**
+ * docs for projects within [groupName] will be built from prebuilts with the given [version]
+ */
+ fun prebuilts(groupName: String, version: String) = prebuilts(groupName, Version(version))
+
+ /**
+ * docs for projects within [groupName] will be built from prebuilts with the given [version]
+ */
+ fun prebuilts(groupName: String, version: Version): Prebuilts {
+ val strategy = Prebuilts(version)
+ rules.add(groupPredicate(groupName) to strategy)
+ return strategy
+ }
+
+ /**
+ * defines a default strategy for building docs
+ */
+ fun default(strategy: PublishDocsRules.Strategy) {
+ rules.add(allPredicate to strategy)
+ }
+
+ /**
+ * docs for projects within [groupName] won't be built
+ */
+ fun ignore(groupName: String) {
+ rules.add(groupPredicate(groupName) to Ignore)
+ }
+
+ /**
+ * docs for a specified project won't be built
+ */
+ fun ignore(groupName: String, name: String) {
+ rules.add(artifactPredicate(groupName, name) to Ignore)
+ }
+
+ fun build() = PublishDocsRules(name, rules)
+}
+
+class PublishDocsRules(
+ val name: String,
+ private val rules: List<Pair<ArtifactsPredicate, Strategy>>
+) {
+ sealed class Strategy {
+ object TipOfTree : Strategy()
+ object Ignore : Strategy()
+ class Prebuilts(val version: Version) : Strategy() {
+ var stubs: MutableList<String>? = null
+ constructor(version: String) : this(Version(version))
+ fun addStubs(path: String) {
+ if (stubs == null) {
+ stubs = mutableListOf()
+ }
+ stubs!!.add(path)
+ }
+ }
+ }
+
+ fun resolve(groupName: String, moduleName: String): Strategy {
+ return rules.find { it.first(groupName, moduleName) }?.second ?: throw Error()
+ }
+}
\ No newline at end of file
diff --git a/compat/res/values/attrs.xml b/compat/res/values/attrs.xml
index 8fd6915..e171e9f 100644
--- a/compat/res/values/attrs.xml
+++ b/compat/res/values/attrs.xml
@@ -34,9 +34,9 @@
<!-- The strategy to be used when fetching font data from a font provider in XML layouts.
This attribute is ignored when the resource is loaded from code, as it is equivalent to the
choice of API between {@link
- androidx.core.contenttent.res.ResourcesCompat#getFont(Context, int)} (blocking) and
+ androidx.core.content.res.ResourcesCompat#getFont(Context, int)} (blocking) and
{@link
- androidx.core.contenttent.res.ResourcesCompat#getFont(Context, int, FontCallback, Handler)}
+ androidx.core.content.res.ResourcesCompat#getFont(Context, int, FontCallback, Handler)}
(async). -->
<attr name="fontProviderFetchStrategy">
<!-- The blocking font fetch works as follows.
diff --git a/core/ktx/src/androidTest/java/androidx/core/content/ContextTest.kt b/core/ktx/src/androidTest/java/androidx/core/content/ContextTest.kt
index 09d2355..102899c 100644
--- a/core/ktx/src/androidTest/java/androidx/core/content/ContextTest.kt
+++ b/core/ktx/src/androidTest/java/androidx/core/content/ContextTest.kt
@@ -42,7 +42,7 @@
return if (name == "unit") Unit else null
}
}
- val actual = context.systemService<Unit>()
+ val actual = context.getSystemService<Unit>()
assertEquals(Unit::class.java, lookup)
assertSame(Unit, actual)
}
diff --git a/core/ktx/src/main/java/androidx/core/content/Context.kt b/core/ktx/src/main/java/androidx/core/content/Context.kt
index 2ffb17b..fec1165 100644
--- a/core/ktx/src/main/java/androidx/core/content/Context.kt
+++ b/core/ktx/src/main/java/androidx/core/content/Context.kt
@@ -20,7 +20,6 @@
import android.content.res.TypedArray
import android.util.AttributeSet
import androidx.annotation.AttrRes
-import androidx.annotation.RequiresApi
import androidx.annotation.StyleRes
/**
@@ -32,9 +31,12 @@
*
* @see Context.getSystemService(Class)
*/
-@RequiresApi(23)
-@Suppress("HasPlatformType") // Intentionally propagating platform type with unknown nullability.
-inline fun <reified T> Context.systemService() = getSystemService(T::class.java)
+inline fun <reified T> Context.getSystemService(): T? =
+ ContextCompat.getSystemService(this, T::class.java)
+
+@Deprecated("Use getSystemService", ReplaceWith("this.getSystemService<T>()"))
+inline fun <reified T> Context.systemService(): T? =
+ ContextCompat.getSystemService(this, T::class.java)
/**
* Executes [block] on a [TypedArray] receiver. The [TypedArray] holds the attribute
@@ -62,12 +64,7 @@
@StyleRes defStyleRes: Int = 0,
block: TypedArray.() -> Unit
) {
- val typedArray = obtainStyledAttributes(set, attrs, defStyleAttr, defStyleRes)
- try {
- typedArray.block()
- } finally {
- typedArray.recycle()
- }
+ obtainStyledAttributes(set, attrs, defStyleAttr, defStyleRes).apply(block).recycle()
}
/**
@@ -84,10 +81,5 @@
attrs: IntArray,
block: TypedArray.() -> Unit
) {
- val typedArray = obtainStyledAttributes(resourceId, attrs)
- try {
- typedArray.block()
- } finally {
- typedArray.recycle()
- }
+ obtainStyledAttributes(resourceId, attrs).apply(block).recycle()
}
diff --git a/core/ktx/src/main/java/androidx/core/preference/PreferenceGroup.kt b/core/ktx/src/main/java/androidx/core/preference/PreferenceGroup.kt
index 2efab64..5df18a6 100644
--- a/core/ktx/src/main/java/androidx/core/preference/PreferenceGroup.kt
+++ b/core/ktx/src/main/java/androidx/core/preference/PreferenceGroup.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-@file:Suppress("NOTHING_TO_INLINE")
+@file:Suppress("NOTHING_TO_INLINE", "DeprecatedCallableAddReplaceWith", "DEPRECATION")
package androidx.core.preference
@@ -26,6 +26,7 @@
*
* @throws NullPointerException if no preference is found with that key.
*/
+@Deprecated("Use Jetpack preference library")
inline operator fun PreferenceGroup.get(key: CharSequence): Preference = findPreference(key)
/**
@@ -33,10 +34,12 @@
*
* @throws IndexOutOfBoundsException if index is less than 0 or greater than or equal to the count.
*/
+@Deprecated("Use Jetpack preference library")
operator fun PreferenceGroup.get(index: Int): Preference = getPreference(index)
?: throw IndexOutOfBoundsException("Index: $index, Size: $preferenceCount")
/** Returns `true` if `preference` is found in this preference group. */
+@Deprecated("Use Jetpack preference library")
operator fun PreferenceGroup.contains(preference: Preference): Boolean {
for (index in 0 until preferenceCount) {
if (getPreference(index) == preference) {
@@ -47,25 +50,31 @@
}
/** Adds `preference` to this preference group. */
+@Deprecated("Use Jetpack preference library")
inline operator fun PreferenceGroup.plusAssign(preference: Preference) {
addPreference(preference)
}
/** Removes `preference` from this preference group. */
+@Deprecated("Use Jetpack preference library")
inline operator fun PreferenceGroup.minusAssign(preference: Preference) {
removePreference(preference)
}
/** Returns the number of preferences in this preference group. */
+@Deprecated("Use Jetpack preference library")
inline val PreferenceGroup.size: Int get() = preferenceCount
/** Returns true if this preference group contains no preferences. */
+@Deprecated("Use Jetpack preference library")
inline fun PreferenceGroup.isEmpty(): Boolean = size == 0
/** Returns true if this preference group contains one or more preferences. */
+@Deprecated("Use Jetpack preference library")
inline fun PreferenceGroup.isNotEmpty(): Boolean = size != 0
/** Performs the given action on each preference in this preference group. */
+@Deprecated("Use Jetpack preference library")
inline fun PreferenceGroup.forEach(action: (preference: Preference) -> Unit) {
for (index in 0 until preferenceCount) {
action(get(index))
@@ -73,6 +82,7 @@
}
/** Performs the given action on each preference in this preference group, providing its sequential index. */
+@Deprecated("Use Jetpack preference library")
inline fun PreferenceGroup.forEachIndexed(action: (index: Int, preference: Preference) -> Unit) {
for (index in 0 until preferenceCount) {
action(index, get(index))
@@ -80,6 +90,7 @@
}
/** Returns a [MutableIterator] over the preferences in this preference group. */
+@Deprecated("Use Jetpack preference library")
operator fun PreferenceGroup.iterator() = object : MutableIterator<Preference> {
private var index = 0
override fun hasNext() = index < size
@@ -90,6 +101,7 @@
}
/** Returns a [Sequence] over the preferences in this preference group. */
+@Deprecated("Use Jetpack preference library")
val PreferenceGroup.children: Sequence<Preference>
get() = object : Sequence<Preference> {
override fun iterator() = this@children.iterator()
diff --git a/docs-fake/AndroidManifest.xml b/docs-fake/AndroidManifest.xml
new file mode 100644
index 0000000..b094662
--- /dev/null
+++ b/docs-fake/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright 2018 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.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools" package="total.fake.sad">
+
+ <application tools:ignore="AllowBackup,GoogleAppIndexingWarning,MissingApplicationIcon"/>
+</manifest>
diff --git a/docs-fake/build.gradle b/docs-fake/build.gradle
new file mode 100644
index 0000000..cb5b1c1
--- /dev/null
+++ b/docs-fake/build.gradle
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2018 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.
+ */
+
+plugins {
+ id("SupportAndroidTestAppPlugin")
+}
+
+// replace all tests etc with empty task, so we don't run anything
+// it is more effective then task.enabled = false, because we avoid executing deps as well
+def reentrance = false
+project.tasks.whenTaskAdded { task ->
+ if (task instanceof org.gradle.api.tasks.testing.Test || task.name.startsWith("assemble")) {
+ if (!reentrance) {
+ reentrance = true
+ project.tasks.replace(task.name)
+ reentrance = false
+ }
+ }
+}
+
+android {
+ sourceSets {
+ main {
+ manifest.srcFile "AndroidManifest.xml"
+ }
+ }
+ flavorDimensions("library-group")
+}
+
+
+supportTestApp {
+ minSdkVersion = 'P'
+}
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index e73df47..059a289 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -222,3 +222,10 @@
///// FLATFOOT START
///// FLATFOOT END
+
+// fake project which is used for docs generation from prebuilts
+// we need real android project to generate R.java, aidl etc files that mentioned in sources
+if (!startParameter.projectProperties.containsKey('android.injected.invoked.from.ide')) {
+ // we don't need it in ide, so we don't configure it there
+ includeProject(":docs-fake", "docs-fake")
+}