| /* |
| * Copyright (C) 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. |
| */ |
| |
| import java.lang.reflect.InvocationTargetException; |
| |
| public class Linking { |
| public static boolean canAccess(String className, boolean takesParameter) throws Exception { |
| try { |
| Class<?> c = Class.forName(className); |
| if (takesParameter) { |
| c.getDeclaredMethod("access", Integer.TYPE).invoke(null, 42); |
| } else { |
| c.getDeclaredMethod("access").invoke(null); |
| } |
| return true; |
| } catch (InvocationTargetException ex) { |
| if (ex.getCause() instanceof NoSuchFieldError || ex.getCause() instanceof NoSuchMethodError) { |
| return false; |
| } else { |
| throw ex; |
| } |
| } |
| } |
| } |
| |
| // INSTANCE FIELD GET |
| |
| class LinkFieldGetSdk { |
| public static int access() { |
| return new ParentClass().fieldPublicSdk; |
| } |
| } |
| |
| class LinkFieldGetUnsupported { |
| public static int access() { |
| return new ParentClass().fieldPublicUnsupported; |
| } |
| } |
| |
| class LinkFieldGetConditionallyBlocked { |
| public static int access() { |
| return new ParentClass().fieldPublicConditionallyBlocked; |
| } |
| } |
| |
| class LinkFieldGetBlocklist { |
| public static int access() { |
| return new ParentClass().fieldPublicBlocklist; |
| } |
| } |
| |
| class LinkFieldGetBlocklistAndCorePlatformApi { |
| public static int access() { |
| return new ParentClass().fieldPublicBlocklistAndCorePlatformApi; |
| } |
| } |
| |
| // INSTANCE FIELD SET |
| |
| class LinkFieldSetSdk { |
| public static void access(int x) { |
| // Need to use a different field from the getter to bypass DexCache. |
| new ParentClass().fieldPublicSdkB = x; |
| } |
| } |
| |
| class LinkFieldSetUnsupported { |
| public static void access(int x) { |
| // Need to use a different field from the getter to bypass DexCache. |
| new ParentClass().fieldPublicUnsupportedB = x; |
| } |
| } |
| |
| class LinkFieldSetConditionallyBlocked { |
| public static void access(int x) { |
| // Need to use a different field from the getter to bypass DexCache. |
| new ParentClass().fieldPublicConditionallyBlockedB = x; |
| } |
| } |
| |
| class LinkFieldSetBlocklist { |
| public static void access(int x) { |
| // Need to use a different field from the getter to bypass DexCache. |
| new ParentClass().fieldPublicBlocklistB = x; |
| } |
| } |
| |
| class LinkFieldSetBlocklistAndCorePlatformApi { |
| public static void access(int x) { |
| // Need to use a different field from the getter to bypass DexCache. |
| new ParentClass().fieldPublicBlocklistAndCorePlatformApiB = x; |
| } |
| } |
| |
| // STATIC FIELD GET |
| |
| class LinkFieldGetStaticSdk { |
| public static int access() { |
| return ParentClass.fieldPublicStaticSdk; |
| } |
| } |
| |
| class LinkFieldGetStaticUnsupported { |
| public static int access() { |
| return ParentClass.fieldPublicStaticUnsupported; |
| } |
| } |
| |
| class LinkFieldGetStaticConditionallyBlocked { |
| public static int access() { |
| return ParentClass.fieldPublicStaticConditionallyBlocked; |
| } |
| } |
| |
| class LinkFieldGetStaticBlocklist { |
| public static int access() { |
| return ParentClass.fieldPublicStaticBlocklist; |
| } |
| } |
| |
| class LinkFieldGetStaticBlocklistAndCorePlatformApi { |
| public static int access() { |
| return ParentClass.fieldPublicStaticBlocklistAndCorePlatformApi; |
| } |
| } |
| |
| // STATIC FIELD SET |
| |
| class LinkFieldSetStaticSdk { |
| public static void access(int x) { |
| // Need to use a different field from the getter to bypass DexCache. |
| ParentClass.fieldPublicStaticSdkB = x; |
| } |
| } |
| |
| class LinkFieldSetStaticUnsupported { |
| public static void access(int x) { |
| // Need to use a different field from the getter to bypass DexCache. |
| ParentClass.fieldPublicStaticUnsupportedB = x; |
| } |
| } |
| |
| class LinkFieldSetStaticConditionallyBlocked { |
| public static void access(int x) { |
| // Need to use a different field from the getter to bypass DexCache. |
| ParentClass.fieldPublicStaticConditionallyBlockedB = x; |
| } |
| } |
| |
| class LinkFieldSetStaticBlocklist { |
| public static void access(int x) { |
| // Need to use a different field from the getter to bypass DexCache. |
| ParentClass.fieldPublicStaticBlocklistB = x; |
| } |
| } |
| |
| class LinkFieldSetStaticBlocklistAndCorePlatformApi { |
| public static void access(int x) { |
| // Need to use a different field from the getter to bypass DexCache. |
| ParentClass.fieldPublicStaticBlocklistAndCorePlatformApiB = x; |
| } |
| } |
| |
| // INVOKE INSTANCE METHOD |
| |
| class LinkMethodSdk { |
| public static int access() { |
| return new ParentClass().methodPublicSdk(); |
| } |
| } |
| |
| class LinkMethodUnsupported { |
| public static int access() { |
| return new ParentClass().methodPublicUnsupported(); |
| } |
| } |
| |
| class LinkMethodConditionallyBlocked { |
| public static int access() { |
| return new ParentClass().methodPublicConditionallyBlocked(); |
| } |
| } |
| |
| class LinkMethodBlocklist { |
| public static int access() { |
| return new ParentClass().methodPublicBlocklist(); |
| } |
| } |
| |
| class LinkMethodBlocklistAndCorePlatformApi { |
| public static int access() { |
| return new ParentClass().methodPublicBlocklistAndCorePlatformApi(); |
| } |
| } |
| |
| // INVOKE INSTANCE INTERFACE METHOD |
| |
| class LinkMethodInterfaceSdk { |
| public static int access() { |
| return SampleClass.getInterfaceInstance().methodPublicSdk(); |
| } |
| } |
| |
| class LinkMethodInterfaceUnsupported { |
| public static int access() { |
| return SampleClass.getInterfaceInstance().methodPublicUnsupported(); |
| } |
| } |
| |
| class LinkMethodInterfaceConditionallyBlocked { |
| public static int access() { |
| return SampleClass.getInterfaceInstance().methodPublicConditionallyBlocked(); |
| } |
| } |
| |
| class LinkMethodInterfaceBlocklist { |
| public static int access() { |
| return SampleClass.getInterfaceInstance().methodPublicBlocklist(); |
| } |
| } |
| |
| class LinkMethodInterfaceBlocklistAndCorePlatformApi { |
| public static int access() { |
| return SampleClass.getInterfaceInstance().methodPublicBlocklistAndCorePlatformApi(); |
| } |
| } |
| |
| // INVOKE STATIC METHOD |
| |
| class LinkMethodStaticSdk { |
| public static int access() { |
| return ParentClass.methodPublicStaticSdk(); |
| } |
| } |
| |
| class LinkMethodStaticUnsupported { |
| public static int access() { |
| return ParentClass.methodPublicStaticUnsupported(); |
| } |
| } |
| |
| class LinkMethodStaticConditionallyBlocked { |
| public static int access() { |
| return ParentClass.methodPublicStaticConditionallyBlocked(); |
| } |
| } |
| |
| class LinkMethodStaticBlocklist { |
| public static int access() { |
| return ParentClass.methodPublicStaticBlocklist(); |
| } |
| } |
| |
| class LinkMethodStaticBlocklistAndCorePlatformApi { |
| public static int access() { |
| return ParentClass.methodPublicStaticBlocklistAndCorePlatformApi(); |
| } |
| } |
| |
| // INVOKE INTERFACE STATIC METHOD |
| |
| class LinkMethodInterfaceStaticSdk { |
| public static int access() { |
| return ParentInterface.methodPublicStaticSdk(); |
| } |
| } |
| |
| class LinkMethodInterfaceStaticUnsupported { |
| public static int access() { |
| return ParentInterface.methodPublicStaticUnsupported(); |
| } |
| } |
| |
| class LinkMethodInterfaceStaticConditionallyBlocked { |
| public static int access() { |
| return ParentInterface.methodPublicStaticConditionallyBlocked(); |
| } |
| } |
| |
| class LinkMethodInterfaceStaticBlocklist { |
| public static int access() { |
| return ParentInterface.methodPublicStaticBlocklist(); |
| } |
| } |
| |
| class LinkMethodInterfaceStaticBlocklistAndCorePlatformApi { |
| public static int access() { |
| return ParentInterface.methodPublicStaticBlocklistAndCorePlatformApi(); |
| } |
| } |