Harden reflection

Summary:
Changelog: Fix theme reflection logging lot of errors if the APIs aren't accessible, see #1736

Harden theme reflection based on the comments in https://github.com/facebook/flipper/issues/1736

Reviewed By: jknoxville

Differential Revision: D32202434

fbshipit-source-id: 99178df56c91715f9eff1e4764ebc55b29ecb6f3
This commit is contained in:
Michel Weststrate
2021-11-10 04:33:12 -08:00
committed by Facebook GitHub Bot
parent 750f26eaa3
commit 9d74728dfe

View File

@@ -21,6 +21,7 @@ import java.util.Map;
public final class ContextDescriptorUtils { public final class ContextDescriptorUtils {
private static String TAG = "ContextDescriptor"; private static String TAG = "ContextDescriptor";
private static boolean doneFieldDiscovery = false;
private static Field sThemeImplField; private static Field sThemeImplField;
private static Field sThemeImplThemeKeyField; private static Field sThemeImplThemeKeyField;
private static Field sThemeImplAssetManagerField; private static Field sThemeImplAssetManagerField;
@@ -47,30 +48,61 @@ public final class ContextDescriptorUtils {
final Object themeKey; final Object themeKey;
// Nasty reflection to get a list of theme attributes that apply to this context. // Nasty reflection to get a list of theme attributes that apply to this context.
if (sThemeImplField == null if (!doneFieldDiscovery) {
|| sThemeImplThemeKeyField == null doneFieldDiscovery = true; // even if it fails, we don't want to retry
|| sThemeKeyResIdField == null try {
|| sThemeImplAssetManagerField == null) { sThemeImplField = theme.getClass().getDeclaredField("mThemeImpl");
sThemeImplField = theme.getClass().getDeclaredField("mThemeImpl"); sThemeImplField.setAccessible(true);
sThemeImplField.setAccessible(true); } catch (NoSuchFieldException e) {
// hardening against #1736
return builderMap;
}
themeImpl = sThemeImplField.get(theme); themeImpl = sThemeImplField.get(theme);
sThemeImplThemeKeyField = themeImpl.getClass().getDeclaredField("mKey"); try {
sThemeImplThemeKeyField.setAccessible(true); sThemeImplThemeKeyField = themeImpl.getClass().getDeclaredField("mKey");
sThemeImplThemeKeyField.setAccessible(true);
} catch (NoSuchFieldException e) {
// hardening against #1736
return builderMap;
}
sThemeImplAssetManagerField = themeImpl.getClass().getDeclaredField("mAssets"); try {
sThemeImplAssetManagerField.setAccessible(true); sThemeImplAssetManagerField = themeImpl.getClass().getDeclaredField("mAssets");
sThemeImplAssetManagerField.setAccessible(true);
} catch (NoSuchFieldException e) {
// hardening against #1736
return builderMap;
}
sAssetManagerGetStyleAttributesMethod = try {
assetManager.getClass().getDeclaredMethod("getStyleAttributes", int.class); sAssetManagerGetStyleAttributesMethod =
sAssetManagerGetStyleAttributesMethod.setAccessible(true); assetManager.getClass().getDeclaredMethod("getStyleAttributes", int.class);
sAssetManagerGetStyleAttributesMethod.setAccessible(true);
} catch (NoSuchMethodException e) {
// hardening against #1736
return builderMap;
}
themeKey = sThemeImplThemeKeyField.get(themeImpl); themeKey = sThemeImplThemeKeyField.get(themeImpl);
sThemeKeyResIdField = themeKey.getClass().getDeclaredField("mResId"); try {
sThemeKeyResIdField.setAccessible(true); sThemeKeyResIdField = themeKey.getClass().getDeclaredField("mResId");
sThemeKeyResIdField.setAccessible(true);
} catch (NoSuchFieldException e) {
// hardening against #1736
return builderMap;
}
} else if (sThemeImplField != null && sThemeImplThemeKeyField != null) {
themeImpl = sThemeImplField.get(theme);
themeKey = sThemeImplThemeKeyField.get(themeImpl);
} else { } else {
themeImpl = sThemeImplField.get(theme); themeKey = null;
themeKey = sThemeImplThemeKeyField.get(themeImpl); }
if (sThemeKeyResIdField == null
|| sAssetManagerGetStyleAttributesMethod == null
|| themeKey == null) {
return builderMap;
} }
int[] appliedThemeResIds = (int[]) sThemeKeyResIdField.get(themeKey); int[] appliedThemeResIds = (int[]) sThemeKeyResIdField.get(themeKey);