1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
/*
* Copyright (C) 2019 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 com.android.build.api.component.impl
import com.android.build.api.variant.AndroidVersion
import com.android.build.api.variant.impl.getFeatureLevel
import com.android.build.gradle.internal.component.ConsumableCreationConfig
import com.android.build.gradle.internal.component.DynamicFeatureCreationConfig
import com.android.build.gradle.internal.core.dsl.ConsumableComponentDslInfo
import com.android.build.gradle.internal.scope.Java8LangSupport
import com.android.builder.dexing.DexingType
import com.android.builder.errors.IssueReporter
/**
* This class and subclasses are implementing methods defined in the CreationConfig
* interfaces but should not be necessarily implemented by the VariantImpl
* and subclasses. The reasons are usually because it makes more sense to implement
* the method in a class hierarchy that follows the interface definition so to avoid
* repeating implementation in various disparate VariantImpl sub-classes.
*
* Instead [com.android.build.api.variant.impl.VariantImpl] will delegate
* to these objects for methods which are cross cutting across the Variant
* implementation hierarchy.
*/
/**
* Constructor for [ConsumableCreationConfigImpl].
*
* @param config configuration object that will be delegating calls to this
* object, and will also provide access to other Variant configuration data
* @param dslInfo variant configuration coming from the DSL.
*/
open class ConsumableCreationConfigImpl<T: ConsumableCreationConfig>(
protected val config: T,
protected open val dslInfo: ConsumableComponentDslInfo
) {
val dexingType: DexingType
get() =
if (config is DynamicFeatureCreationConfig) {
// dynamic features can always be build in native multidex mode
DexingType.NATIVE_MULTIDEX
} else if (config.isMultiDexEnabled) {
if (config.minSdkVersion.getFeatureLevel() >= 21 ||
dslInfo.targetDeployApiFromIDE?.let { it >= 21 } == true
) {
// if minSdkVersion is 21+ or we are deploying to 21+ device, use native multidex
DexingType.NATIVE_MULTIDEX
} else DexingType.LEGACY_MULTIDEX
} else {
DexingType.MONO_DEX
}
fun getNeedsMergedJavaResStream(): Boolean {
// We need to create a stream from the merged java resources if we're in a library module,
// or if we're in an app/feature module which uses the transform pipeline.
return (dslInfo.componentType.isAar
|| dslInfo.transforms.isNotEmpty()
|| config.minifiedEnabled)
}
fun getJava8LangSupportType(): Java8LangSupport {
// in order of precedence
return if (!dslInfo.compileOptions.targetCompatibility.isJava8Compatible) {
Java8LangSupport.UNUSED
} else if (config.services.projectInfo.hasPlugin("me.tatarka.retrolambda")) {
Java8LangSupport.RETROLAMBDA
} else if (config.minifiedEnabled) {
Java8LangSupport.R8
} else {
// D8 cannot be used if R8 is used
Java8LangSupport.D8
}
}
val isCoreLibraryDesugaringEnabled: Boolean
get() = isCoreLibraryDesugaringEnabled(config)
open val needsShrinkDesugarLibrary: Boolean
get() = isCoreLibraryDesugaringEnabled(config)
/**
* Returns if core library desugaring is enabled.
*
* Java language desugaring and multidex are required for enabling core library desugaring.
* @param creationConfig
*/
fun isCoreLibraryDesugaringEnabled(creationConfig: ConsumableCreationConfig): Boolean {
val libDesugarEnabled = dslInfo.compileOptions.isCoreLibraryDesugaringEnabled
val multidexEnabled = creationConfig.isMultiDexEnabled
val langSupportType = getJava8LangSupportType()
val langDesugarEnabled = langSupportType == Java8LangSupport.D8 ||
langSupportType == Java8LangSupport.R8
if (libDesugarEnabled && !langDesugarEnabled) {
config
.services
.issueReporter
.reportError(
IssueReporter.Type.GENERIC, "In order to use core library desugaring, "
+ "please enable java 8 language desugaring with D8 or R8.")
}
if (libDesugarEnabled && !multidexEnabled) {
config
.services
.issueReporter
.reportError(
IssueReporter.Type.GENERIC, "In order to use core library desugaring, "
+ "please enable multidex.")
}
return libDesugarEnabled
}
open val minSdkVersionForDexing: AndroidVersion
get() = config.minSdkVersion
}
|