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// (system, system_ext) => system partition group 53// (vendor, odm) => vendor partition group 54// (product) => product partition group 55func (j *Module) partitionGroup(ctx android.EarlyModuleContext) partitionGroup { 56 // system and system_ext partition can be treated as the same in terms of inter-partition dependency. 57 if j.Platform() || j.SystemExtSpecific() { 58 return partitionGroupSystem 59 } 60 61 // vendor and odm partition can be treated as the same in terms of inter-partition dependency. 62 if j.SocSpecific() || j.DeviceSpecific() { 63 return partitionGroupVendor 64 } 65 66 // product partition is independent. 67 if j.ProductSpecific() { 68 return partitionGroupProduct 69 } 70 71 panic("Cannot determine partition type") 72} 73 74func (j *Module) allowListedInterPartitionJavaLibrary(ctx android.EarlyModuleContext) bool { 75 return inList(j.Name(), ctx.Config().InterPartitionJavaLibraryAllowList()) 76} 77 78func (j *Module) syspropWithPublicStubs() bool { 79 return j.deviceProperties.SyspropPublicStub != "" 80} 81 82type javaSdkLibraryEnforceContext interface { 83 Name() string 84 allowListedInterPartitionJavaLibrary(ctx android.EarlyModuleContext) bool 85 partitionGroup(ctx android.EarlyModuleContext) partitionGroup 86 syspropWithPublicStubs() bool 87} 88 89var _ javaSdkLibraryEnforceContext = (*Module)(nil) 90 91func (j *Module) checkPartitionsForJavaDependency(ctx android.EarlyModuleContext, propName string, dep javaSdkLibraryEnforceContext) { 92 if dep.allowListedInterPartitionJavaLibrary(ctx) { 93 return 94 } 95 96 if dep.syspropWithPublicStubs() { 97 return 98 } 99 100 // If product interface is not enforced, skip check between system and product partition. 101 // But still need to check between product and vendor partition because product interface flag 102 // just represents enforcement between product and system, and vendor interface enforcement 103 // that is enforced here by precondition is representing enforcement between vendor and other partitions. 104 if !ctx.Config().EnforceProductPartitionInterface() { 105 productToSystem := j.partitionGroup(ctx) == partitionGroupProduct && dep.partitionGroup(ctx) == partitionGroupSystem 106 systemToProduct := j.partitionGroup(ctx) == partitionGroupSystem && dep.partitionGroup(ctx) == partitionGroupProduct 107 108 if productToSystem || systemToProduct { 109 return 110 } 111 } 112 113 // If module and dependency library is inter-partition 114 if j.partitionGroup(ctx) != dep.partitionGroup(ctx) { 115 errorFormat := "dependency on java_library (%q) is not allowed across the partitions (%s -> %s), use java_sdk_library instead" 116 ctx.PropertyErrorf(propName, errorFormat, dep.Name(), j.partitionGroup(ctx), dep.partitionGroup(ctx)) 117 } 118} 119