|  | // Copyright 2020 Google Inc. All rights reserved. | 
|  | // | 
|  | // 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 java | 
|  |  | 
|  | import ( | 
|  | "android/soong/android" | 
|  | ) | 
|  |  | 
|  | type partitionGroup int | 
|  |  | 
|  | // Representation of partition group for checking inter-partition library dependencies. | 
|  | // Between system and system_ext, there are no restrictions of dependencies, | 
|  | // so we can treat these partitions as the same in terms of inter-partition dependency. | 
|  | // Same policy is applied between vendor and odm partiton. | 
|  | const ( | 
|  | partitionGroupNone partitionGroup = iota | 
|  | // group for system, and system_ext partition | 
|  | partitionGroupSystem | 
|  | // group for vendor and odm partition | 
|  | partitionGroupVendor | 
|  | // product partition | 
|  | partitionGroupProduct | 
|  | ) | 
|  |  | 
|  | func (g partitionGroup) String() string { | 
|  | switch g { | 
|  | case partitionGroupSystem: | 
|  | return "system" | 
|  | case partitionGroupVendor: | 
|  | return "vendor" | 
|  | case partitionGroupProduct: | 
|  | return "product" | 
|  | } | 
|  |  | 
|  | return "" | 
|  | } | 
|  |  | 
|  | // Get partition group of java module that can be used at inter-partition dependency check. | 
|  | // We currently have three groups | 
|  | // | 
|  | //	(system, system_ext) => system partition group | 
|  | //	(vendor, odm) => vendor partition group | 
|  | //	(product) => product partition group | 
|  | func (j *Module) partitionGroup(ctx android.EarlyModuleContext) partitionGroup { | 
|  | // system and system_ext partition can be treated as the same in terms of inter-partition dependency. | 
|  | if j.Platform() || j.SystemExtSpecific() { | 
|  | return partitionGroupSystem | 
|  | } | 
|  |  | 
|  | // vendor and odm partition can be treated as the same in terms of inter-partition dependency. | 
|  | if j.SocSpecific() || j.DeviceSpecific() { | 
|  | return partitionGroupVendor | 
|  | } | 
|  |  | 
|  | // product partition is independent. | 
|  | if j.ProductSpecific() { | 
|  | return partitionGroupProduct | 
|  | } | 
|  |  | 
|  | panic("Cannot determine partition type") | 
|  | } | 
|  |  | 
|  | func (j *Module) allowListedInterPartitionJavaLibrary(ctx android.EarlyModuleContext) bool { | 
|  | return inList(j.Name(), ctx.Config().InterPartitionJavaLibraryAllowList()) | 
|  | } | 
|  |  | 
|  | func (j *Module) syspropWithPublicStubs() bool { | 
|  | return j.deviceProperties.SyspropPublicStub != "" | 
|  | } | 
|  |  | 
|  | type javaSdkLibraryEnforceContext interface { | 
|  | Name() string | 
|  | allowListedInterPartitionJavaLibrary(ctx android.EarlyModuleContext) bool | 
|  | partitionGroup(ctx android.EarlyModuleContext) partitionGroup | 
|  | syspropWithPublicStubs() bool | 
|  | } | 
|  |  | 
|  | var _ javaSdkLibraryEnforceContext = (*Module)(nil) | 
|  |  | 
|  | func (j *Module) checkPartitionsForJavaDependency(ctx android.EarlyModuleContext, propName string, dep javaSdkLibraryEnforceContext) { | 
|  | if dep.allowListedInterPartitionJavaLibrary(ctx) { | 
|  | return | 
|  | } | 
|  |  | 
|  | if dep.syspropWithPublicStubs() { | 
|  | return | 
|  | } | 
|  |  | 
|  | // If product interface is not enforced, skip check between system and product partition. | 
|  | // But still need to check between product and vendor partition because product interface flag | 
|  | // just represents enforcement between product and system, and vendor interface enforcement | 
|  | // that is enforced here by precondition is representing enforcement between vendor and other partitions. | 
|  | if !ctx.Config().EnforceProductPartitionInterface() { | 
|  | productToSystem := j.partitionGroup(ctx) == partitionGroupProduct && dep.partitionGroup(ctx) == partitionGroupSystem | 
|  | systemToProduct := j.partitionGroup(ctx) == partitionGroupSystem && dep.partitionGroup(ctx) == partitionGroupProduct | 
|  |  | 
|  | if productToSystem || systemToProduct { | 
|  | return | 
|  | } | 
|  | } | 
|  |  | 
|  | // If module and dependency library is inter-partition | 
|  | if j.partitionGroup(ctx) != dep.partitionGroup(ctx) { | 
|  | errorFormat := "dependency on java_library (%q) is not allowed across the partitions (%s -> %s), use java_sdk_library instead" | 
|  | ctx.PropertyErrorf(propName, errorFormat, dep.Name(), j.partitionGroup(ctx), dep.partitionGroup(ctx)) | 
|  | } | 
|  | } |