resources/src/main/java/org/robolectric/res/android/AttributeResolution10.java
public static boolean ResolveAttrs(Theme theme, int def_style_attr,
            int def_style_res, int[] src_values,
            int src_values_length, int[] attrs,
            int attrs_length, int[] out_values, int[] out_indices) {
        if (kDebugStyles) {
            ALOGI("APPLY STYLE: theme=0x%p defStyleAttr=0x%x defStyleRes=0x%x", theme,
                    def_style_attr, def_style_res);
        }

        CppAssetManager2 assetmanager = theme.GetAssetManager();
        ResTable_config config = new ResTable_config();
        Res_value value;

        int indicesIdx = 0;

        // Load default style from attribute, if specified...
        final Ref<Integer> def_style_flags = new Ref<>(0);
        if (def_style_attr != 0) {
            final Ref<Res_value> valueRef = new Ref<>(null);
            if (theme.GetAttribute(def_style_attr, valueRef, def_style_flags).intValue() != kInvalidCookie) {
                value = valueRef.get();
                if (value.dataType == Res_value.TYPE_REFERENCE) {
                    def_style_res = value.data;
                }
            }
        }

        // Retrieve the default style bag, if requested.
        ResolvedBag default_style_bag = null;
        if (def_style_res != 0) {
            default_style_bag = assetmanager.GetBag(def_style_res);
            if (default_style_bag != null) {
                def_style_flags.set(def_style_flags.get() | default_style_bag.type_spec_flags);
            }
        }
        BagAttributeFinder def_style_attr_finder = new BagAttributeFinder(default_style_bag);

        // Now iterate through all of the attributes that the client has requested,
        // filling in each with whatever data we can find.
        int destOffset = 0;
        for (int ii=0; ii<attrs_length; ii++) {
            final int cur_ident = attrs[ii];

            if (kDebugStyles) {
                ALOGI("RETRIEVING ATTR 0x%08x...", cur_ident);
            }

            ApkAssetsCookie cookie = K_INVALID_COOKIE;
            int type_set_flags = 0;

            value = Res_value.NULL_VALUE;
            config.density = 0;

            // Try to find a value for this attribute...  we prioritize values
            // coming from, first XML attributes, then XML style, then default
            // style, and finally the theme.

            // Retrieve the current input value if available.
            if (src_values_length > 0 && src_values[ii] != 0) {
                value = new Res_value((byte) Res_value.TYPE_ATTRIBUTE, src_values[ii]);
                if (kDebugStyles) {
                    ALOGI("-> From values: type=0x%x, data=0x%08x", value.dataType, value.data);
                }
            } else {
                final Entry entry = def_style_attr_finder.Find(cur_ident);
                if (entry != null) {
                    cookie = entry.cookie;
                    type_set_flags = def_style_flags.get();
                    value = entry.value;
                    if (kDebugStyles) {
                        ALOGI("-> From def style: type=0x%x, data=0x%08x", value.dataType, value.data);
                    }
                }
            }

            int resid = 0;
            final Ref<Res_value> valueRef = new Ref<>(value);
            final Ref<Integer> residRef = new Ref<>(resid);
            final Ref<Integer> type_set_flagsRef = new Ref<>(type_set_flags);
            final Ref<ResTable_config> configRef = new Ref<>(config);
            if (value.dataType != Res_value.TYPE_NULL) {
                // Take care of resolving the found resource to its final value.
                ApkAssetsCookie new_cookie =
                        theme.ResolveAttributeReference(cookie, valueRef, configRef, type_set_flagsRef, residRef);
                if (new_cookie.intValue() != kInvalidCookie) {
                    cookie = new_cookie;
                }
                if (kDebugStyles) {
                    ALOGI("-> Resolved attr: type=0x%x, data=0x%08x", value.dataType, value.data);
                }
            } else if (value.data != Res_value.DATA_NULL_EMPTY) {
                // If we still don't have a value for this attribute, try to find it in the theme!
                ApkAssetsCookie new_cookie = theme.GetAttribute(cur_ident, valueRef, type_set_flagsRef);
                if (new_cookie.intValue() != kInvalidCookie) {
                    if (kDebugStyles) {
                        ALOGI("-> From theme: type=0x%x, data=0x%08x", value.dataType, value.data);
                    }
                    new_cookie =
                            assetmanager.ResolveReference(new_cookie, valueRef, configRef, type_set_flagsRef, residRef);
                    if (new_cookie.intValue() != kInvalidCookie) {
                        cookie = new_cookie;
                    }
                    if (kDebugStyles) {
                        ALOGI("-> Resolved theme: type=0x%x, data=0x%08x", value.dataType, value.data);
                    }
                }
            }
            value = valueRef.get();
            resid = residRef.get();
            type_set_flags = type_set_flagsRef.get();
            config = configRef.get();

            // Deal with the special @null value -- it turns back to TYPE_NULL.
            if (value.dataType == Res_value.TYPE_REFERENCE && value.data == 0) {
                if (kDebugStyles) {
                    ALOGI("-> Setting to @null!");
                }
                value = Res_value.NULL_VALUE;
                cookie = K_INVALID_COOKIE;
            }

            if (kDebugStyles) {
                ALOGI("Attribute 0x%08x: type=0x%x, data=0x%08x", cur_ident, value.dataType,
                        value.data);
            }

            // Write the final value back to Java.
            out_values[destOffset + STYLE_TYPE] = value.dataType;
            out_values[destOffset + STYLE_DATA] = value.data;
            out_values[destOffset + STYLE_ASSET_COOKIE] = ApkAssetsCookieToJavaCookie(cookie);
            out_values[destOffset + STYLE_RESOURCE_ID] = resid;
            out_values[destOffset + STYLE_CHANGING_CONFIGURATIONS] = type_set_flags;
            out_values[destOffset + STYLE_DENSITY] = config.density;

            if (out_indices != null && value.dataType != Res_value.TYPE_NULL) {
                indicesIdx++;
                out_indices[indicesIdx] = ii;
            }

            destOffset += STYLE_NUM_ENTRIES;
        }

        if (out_indices != null) {
            out_indices[0] = indicesIdx;
        }
        return true;
    }
public static boolean ResolveAttrs(Theme theme, int def_style_attr,
            int def_style_res, int[] src_values,
            int src_values_length, int[] attrs,
            int attrs_length, int[] out_values, int[] out_indices) {
        if (kDebugStyles) {
            ALOGI("APPLY STYLE: theme=0x%p defStyleAttr=0x%x defStyleRes=0x%x", theme,
                    def_style_attr, def_style_res);
        }

        CppAssetManager2 assetmanager = theme.GetAssetManager();
        ResTable_config config = new ResTable_config();
        Res_value value;

        int indicesIdx = 0;

        // Load default style from attribute, if specified...
        final Ref<Integer> def_style_flags = new Ref<>(0);
        if (def_style_attr != 0) {
            final Ref<Res_value> valueRef = new Ref<>(null);
            if (theme.GetAttribute(def_style_attr, valueRef, def_style_flags).intValue() != kInvalidCookie) {
                value = valueRef.get();
                if (value.dataType == Res_value.TYPE_REFERENCE) {
                    def_style_res = value.data;
                }
            }
        }

        // Retrieve the default style bag, if requested.
        ResolvedBag default_style_bag = null;
        if (def_style_res != 0) {
            default_style_bag = assetmanager.GetBag(def_style_res);
            if (default_style_bag != null) {
                def_style_flags.set(def_style_flags.get() | default_style_bag.type_spec_flags);
            }
        }
        BagAttributeFinder def_style_attr_finder = new BagAttributeFinder(default_style_bag);

        // Now iterate through all of the attributes that the client has requested,
        // filling in each with whatever data we can find.
        int destOffset = 0;
        for (int ii=0; ii<attrs_length; ii++) {
            final int cur_ident = attrs[ii];

            if (kDebugStyles) {
                ALOGI("RETRIEVING ATTR 0x%08x...", cur_ident);
            }

            ApkAssetsCookie cookie = K_INVALID_COOKIE;
            int type_set_flags = 0;

            value = Res_value.NULL_VALUE;
            config.density = 0;

            // Try to find a value for this attribute...  we prioritize values
            // coming from, first XML attributes, then XML style, then default
            // style, and finally the theme.

            // Retrieve the current input value if available.
            if (src_values_length > 0 && src_values[ii] != 0) {
                value = new Res_value((byte) Res_value.TYPE_ATTRIBUTE, src_values[ii]);
                if (kDebugStyles) {
                    ALOGI("-> From values: type=0x%x, data=0x%08x", value.dataType, value.data);
                }
            } else {
                final Entry entry = def_style_attr_finder.Find(cur_ident);
                if (entry != null) {
                    cookie = entry.cookie;
                    type_set_flags = def_style_flags.get();
                    value = entry.value;
                    if (kDebugStyles) {
                        ALOGI("-> From def style: type=0x%x, data=0x%08x", value.dataType, value.data);
                    }
                }
            }

            int resid = 0;
            final Ref<Res_value> valueRef = new Ref<>(value);
            final Ref<Integer> residRef = new Ref<>(resid);
            final Ref<Integer> type_set_flagsRef = new Ref<>(type_set_flags);
            final Ref<ResTable_config> configRef = new Ref<>(config);
            if (value.dataType != Res_value.TYPE_NULL) {
                // Take care of resolving the found resource to its final value.
                ApkAssetsCookie new_cookie =
                        theme.ResolveAttributeReference(cookie, valueRef, configRef, type_set_flagsRef, residRef);
                if (new_cookie.intValue() != kInvalidCookie) {
                    cookie = new_cookie;
                }
                if (kDebugStyles) {
                    ALOGI("-> Resolved attr: type=0x%x, data=0x%08x", value.dataType, value.data);
                }
            } else if (value.data != Res_value.DATA_NULL_EMPTY) {
                // If we still don't have a value for this attribute, try to find it in the theme!
                ApkAssetsCookie new_cookie = theme.GetAttribute(cur_ident, valueRef, type_set_flagsRef);
                if (new_cookie.intValue() != kInvalidCookie) {
                    if (kDebugStyles) {
                        ALOGI("-> From theme: type=0x%x, data=0x%08x", value.dataType, value.data);
                    }
                    new_cookie =
                            assetmanager.ResolveReference(new_cookie, valueRef, configRef, type_set_flagsRef, residRef);
                    if (new_cookie.intValue() != kInvalidCookie) {
                        cookie = new_cookie;
                    }
                    if (kDebugStyles) {
                        ALOGI("-> Resolved theme: type=0x%x, data=0x%08x", value.dataType, value.data);
                    }
                }
            }
            value = valueRef.get();
            resid = residRef.get();
            type_set_flags = type_set_flagsRef.get();
            config = configRef.get();

            // Deal with the special @null value -- it turns back to TYPE_NULL.
            if (value.dataType == Res_value.TYPE_REFERENCE && value.data == 0) {
                if (kDebugStyles) {
                    ALOGI("-> Setting to @null!");
                }
                value = Res_value.NULL_VALUE;
                cookie = K_INVALID_COOKIE;
            }

            if (kDebugStyles) {
                ALOGI("Attribute 0x%08x: type=0x%x, data=0x%08x", cur_ident, value.dataType,
                        value.data);
            }

            // Write the final value back to Java.
            out_values[destOffset + STYLE_TYPE] = value.dataType;
            out_values[destOffset + STYLE_DATA] = value.data;
            out_values[destOffset + STYLE_ASSET_COOKIE] = ApkAssetsCookieToJavaCookie(cookie);
            out_values[destOffset + STYLE_RESOURCE_ID] = resid;
            out_values[destOffset + STYLE_CHANGING_CONFIGURATIONS] = type_set_flags;
            out_values[destOffset + STYLE_DENSITY] = config.density;

            if (out_indices != null && value.dataType != Res_value.TYPE_NULL) {
                indicesIdx++;
                out_indices[indicesIdx] = ii;
            }

            destOffset += STYLE_NUM_ENTRIES;
        }

        if (out_indices != null) {
            out_indices[0] = indicesIdx;
        }
        return true;
    }
`out_indices` may be nullptr.