1// Copyright 2020 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package java 16 17import ( 18 "android/soong/android" 19) 20 21type partitionGroup int 22 23// Representation of partition group for checking inter-partition library dependencies. 24// Between system and system_ext, there are no restrictions of dependencies, 25// so we can treat these partitions as the same in terms of inter-partition dependency. 26// Same policy is applied between vendor and odm partiton. 27const ( 28 partitionGroupNone partitionGroup = iota 29 // group for system, and system_ext partition 30 partitionGroupSystem 31 // group for vendor and odm partition 32 partitionGroupVendor 33 // product partition 34 partitionGroupProduct 35) 36 37func (g partitionGroup) String() string { 38 switch g { 39 case partitionGroupSystem: 40 return "system" 41 case partitionGroupVendor: 42 return "vendor" 43 case partitionGroupProduct: 44 return "product" 45 } 46 47 return "" 48} 49 50// Get partition group of java module that can be used at inter-partition dependency check. 51// We currently have three groups 52// 53// (system, system_ext) => system partition group 54// (vendor, odm) => vendor partition group 55// (product) => product partition group 56func (j *Module) partitionGroup(ctx android.EarlyModuleContext) partitionGroup { 57 // system and system_ext partition can be treated as the same in terms of inter-partition dependency. 58 if j.Platform() || j.SystemExtSpecific() { 59 return partitionGroupSystem 60 } 61 62 // vendor and odm partition can be treated as the same in terms of inter-partition dependency. 63 if j.SocSpecific() || j.DeviceSpecific() { 64 return partitionGroupVendor 65 } 66 67 // product partition is independent. 68 if j.ProductSpecific() { 69 return partitionGroupProduct 70 } 71 72 panic("Cannot determine partition type") 73} 74 75func (j *Module) allowListedInterPartitionJavaLibrary(ctx android.EarlyModuleContext) bool { 76 return inList(j.Name(), ctx.Config().InterPartitionJavaLibraryAllowList()) 77} 78 79func (j *Module) syspropWithPublicStubs() bool { 80 return j.deviceProperties.SyspropPublicStub != "" 81} 82 83type javaSdkLibraryEnforceContext interface { 84 Name() string 85 allowListedInterPartitionJavaLibrary(ctx android.EarlyModuleContext) bool 86 partitionGroup(ctx android.EarlyModuleContext) partitionGroup 87 syspropWithPublicStubs() bool 88} 89 90var _ javaSdkLibraryEnforceContext = (*Module)(nil) 91 92func (j *Module) checkPartitionsForJavaDependency(ctx android.EarlyModuleContext, propName string, dep javaSdkLibraryEnforceContext) { 93 if dep.allowListedInterPartitionJavaLibrary(ctx) { 94 return 95 } 96 97 if dep.syspropWithPublicStubs() { 98 return 99 } 100 101 // If product interface is not enforced, skip check between system and product partition. 102 // But still need to check between product and vendor partition because product interface flag 103 // just represents enforcement between product and system, and vendor interface enforcement 104 // that is enforced here by precondition is representing enforcement between vendor and other partitions. 105 if !ctx.Config().EnforceProductPartitionInterface() { 106 productToSystem := j.partitionGroup(ctx) == partitionGroupProduct && dep.partitionGroup(ctx) == partitionGroupSystem 107 systemToProduct := j.partitionGroup(ctx) == partitionGroupSystem && dep.partitionGroup(ctx) == partitionGroupProduct 108 109 if productToSystem || systemToProduct { 110 return 111 } 112 } 113 114 // If module and dependency library is inter-partition 115 if j.partitionGroup(ctx) != dep.partitionGroup(ctx) { 116 errorFormat := "dependency on java_library (%q) is not allowed across the partitions (%s -> %s), use java_sdk_library instead" 117 ctx.PropertyErrorf(propName, errorFormat, dep.Name(), j.partitionGroup(ctx), dep.partitionGroup(ctx)) 118 } 119} 120