Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 395cd017 authored by Alan Viverette's avatar Alan Viverette
Browse files

Rebase system theme on configuration change

Also makes native theme accesses thread-safe to avoid a race condition
when modifying the theme off the UI thread. Since drawable loading can
occur off the UI thread, we need to ensure Theme access is thread-safe
anyway.

This reverts commit c12ec70d.

Change-Id: If8fecde76d62738a8e55eddf898eafc468afdba2
parent 5894b434
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -4316,6 +4316,11 @@ public final class ActivityThread {

            configDiff = mConfiguration.updateFrom(config);
            config = applyCompatConfiguration(mCurDefaultDisplayDpi);

            final Theme systemTheme = getSystemContext().getTheme();
            if ((systemTheme.getChangingConfigurations() & configDiff) != 0) {
                systemTheme.rebase();
            }
        }

        ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
+85 −122
Original line number Diff line number Diff line
@@ -1426,11 +1426,13 @@ public class Resources {
         *              if not already defined in the theme.
         */
        public void applyStyle(int resId, boolean force) {
            synchronized (mKey) {
                AssetManager.applyThemeStyle(mTheme, resId, force);

                mThemeResId = resId;
                mKey.append(resId, force);
            }
        }

        /**
         * Set this theme to hold the same contents as the theme
@@ -1442,11 +1444,15 @@ public class Resources {
         * @param other The existing Theme to copy from.
         */
        public void setTo(Theme other) {
            synchronized (mKey) {
                synchronized (other.mKey) {
                    AssetManager.copyTheme(mTheme, other.mTheme);

                    mThemeResId = other.mThemeResId;
                    mKey.setTo(other.getKey());
                }
            }
        }

        /**
         * Return a TypedArray holding the values defined by
@@ -1468,12 +1474,14 @@ public class Resources {
         * @see #obtainStyledAttributes(AttributeSet, int[], int, int)
         */
        public TypedArray obtainStyledAttributes(@StyleableRes int[] attrs) {
            synchronized (mKey) {
                final int len = attrs.length;
                final TypedArray array = TypedArray.obtain(Resources.this, len);
                array.mTheme = this;
                AssetManager.applyStyle(mTheme, 0, 0, 0, attrs, array.mData, array.mIndices);
                return array;
            }
        }

        /**
         * Return a TypedArray holding the values defined by the style
@@ -1482,7 +1490,7 @@ public class Resources {
         * <p>Be sure to call {@link TypedArray#recycle() TypedArray.recycle()} when you are done
         * with the array.
         * 
         * @param resid The desired style resource.
         * @param resId The desired style resource.
         * @param attrs The desired attributes in the style.
         * 
         * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
@@ -1495,40 +1503,16 @@ public class Resources {
         * @see #obtainStyledAttributes(int[])
         * @see #obtainStyledAttributes(AttributeSet, int[], int, int)
         */
        public TypedArray obtainStyledAttributes(@StyleRes int resid, @StyleableRes int[] attrs)
        public TypedArray obtainStyledAttributes(@StyleRes int resId, @StyleableRes int[] attrs)
                throws NotFoundException {
            synchronized (mKey) {
                final int len = attrs.length;
                final TypedArray array = TypedArray.obtain(Resources.this, len);
                array.mTheme = this;
            if (false) {
                int[] data = array.mData;
                
                System.out.println("**********************************************************");
                System.out.println("**********************************************************");
                System.out.println("**********************************************************");
                System.out.println("Attributes:");
                String s = "  Attrs:";
                int i;
                for (i=0; i<attrs.length; i++) {
                    s = s + " 0x" + Integer.toHexString(attrs[i]);
                }
                System.out.println(s);
                s = "  Found:";
                TypedValue value = new TypedValue();
                for (i=0; i<attrs.length; i++) {
                    int d = i*AssetManager.STYLE_NUM_ENTRIES;
                    value.type = data[d+AssetManager.STYLE_TYPE];
                    value.data = data[d+AssetManager.STYLE_DATA];
                    value.assetCookie = data[d+AssetManager.STYLE_ASSET_COOKIE];
                    value.resourceId = data[d+AssetManager.STYLE_RESOURCE_ID];
                    s = s + " 0x" + Integer.toHexString(attrs[i])
                        + "=" + value;
                }
                System.out.println(s);
            }
            AssetManager.applyStyle(mTheme, 0, resid, 0, attrs, array.mData, array.mIndices);
                AssetManager.applyStyle(mTheme, 0, resId, 0, attrs, array.mData, array.mIndices);
                return array;
            }
        }

        /**
         * Return a TypedArray holding the attribute values in
@@ -1580,6 +1564,7 @@ public class Resources {
         */
        public TypedArray obtainStyledAttributes(AttributeSet set,
                @StyleableRes int[] attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {
            synchronized (mKey) {
                final int len = attrs.length;
                final TypedArray array = TypedArray.obtain(Resources.this, len);

@@ -1589,42 +1574,14 @@ public class Resources {
                // contained in the resources and such).
                final XmlBlock.Parser parser = (XmlBlock.Parser) set;
                AssetManager.applyStyle(mTheme, defStyleAttr, defStyleRes,
                    parser != null ? parser.mParseState : 0, attrs, array.mData, array.mIndices);

                        parser != null ? parser.mParseState : 0,
                        attrs, array.mData, array.mIndices);
                array.mTheme = this;
                array.mXml = parser;

            if (false) {
                int[] data = array.mData;
                
                System.out.println("Attributes:");
                String s = "  Attrs:";
                int i;
                for (i=0; i<set.getAttributeCount(); i++) {
                    s = s + " " + set.getAttributeName(i);
                    int id = set.getAttributeNameResource(i);
                    if (id != 0) {
                        s = s + "(0x" + Integer.toHexString(id) + ")";
                    }
                    s = s + "=" + set.getAttributeValue(i);
                }
                System.out.println(s);
                s = "  Found:";
                TypedValue value = new TypedValue();
                for (i=0; i<attrs.length; i++) {
                    int d = i*AssetManager.STYLE_NUM_ENTRIES;
                    value.type = data[d+AssetManager.STYLE_TYPE];
                    value.data = data[d+AssetManager.STYLE_DATA];
                    value.assetCookie = data[d+AssetManager.STYLE_ASSET_COOKIE];
                    value.resourceId = data[d+AssetManager.STYLE_RESOURCE_ID];
                    s = s + " 0x" + Integer.toHexString(attrs[i])
                        + "=" + value;
                }
                System.out.println(s);
            }

                return array;
            }
        }

        /**
         * Retrieve the values for a set of attributes in the Theme. The
@@ -1642,6 +1599,7 @@ public class Resources {
         */
        @NonNull
        public TypedArray resolveAttributes(@NonNull int[] values, @NonNull int[] attrs) {
            synchronized (mKey) {
                final int len = attrs.length;
                if (values == null || len != values.length) {
                    throw new IllegalArgumentException(
@@ -1655,6 +1613,7 @@ public class Resources {

                return array;
            }
        }

        /**
         * Retrieve the value of an attribute in the Theme.  The contents of
@@ -1674,14 +1633,9 @@ public class Resources {
         *         <var>outValue</var> is valid, else false.
         */
        public boolean resolveAttribute(int resid, TypedValue outValue, boolean resolveRefs) {
            boolean got = mAssets.getThemeValue(mTheme, resid, outValue, resolveRefs);
            if (false) {
                System.out.println(
                    "resolveAttribute #" + Integer.toHexString(resid)
                    + " got=" + got + ", type=0x" + Integer.toHexString(outValue.type)
                    + ", data=0x" + Integer.toHexString(outValue.data));
            synchronized (mKey) {
                return mAssets.getThemeValue(mTheme, resid, outValue, resolveRefs);
            }
            return got;
        }

        /**
@@ -1727,9 +1681,12 @@ public class Resources {
         * @see ActivityInfo
         */
        public int getChangingConfigurations() {
            final int nativeChangingConfig = AssetManager.getThemeChangingConfigurations(mTheme);
            synchronized (mKey) {
                final int nativeChangingConfig =
                        AssetManager.getThemeChangingConfigurations(mTheme);
                return ActivityInfo.activityInfoConfigNativeToJava(nativeChangingConfig);
            }
        }

        /**
         * Print contents of this theme out to the log.  For debugging only.
@@ -1739,8 +1696,10 @@ public class Resources {
         * @param prefix Text to prefix each line printed.
         */
        public void dump(int priority, String tag, String prefix) {
            synchronized (mKey) {
                AssetManager.dumpTheme(mTheme, priority, tag, prefix);
            }
        }

        @Override
        protected void finalize() throws Throwable {
@@ -1789,6 +1748,7 @@ public class Resources {
         */
        @ViewDebug.ExportedProperty(category = "theme", hasAdjacentMapping = true)
        public String[] getTheme() {
            synchronized (mKey) {
                final int N = mKey.mCount;
                final String[] themes = new String[N * 2];
                for (int i = 0, j = N - 1; i < themes.length; i += 2, --j) {
@@ -1803,6 +1763,7 @@ public class Resources {
                }
                return themes;
            }
        }

        /** @hide */
        public void encode(@NonNull ViewHierarchyEncoder encoder) {
@@ -1822,6 +1783,7 @@ public class Resources {
         * @hide
         */
        public void rebase() {
            synchronized (mKey) {
                AssetManager.clearTheme(mTheme);

                // Reapply the same styles in the same order.
@@ -1832,6 +1794,7 @@ public class Resources {
                }
            }
        }
    }

    static class ThemeKey implements Cloneable {
        int[] mResId;
+6 −0
Original line number Diff line number Diff line
@@ -1022,6 +1022,12 @@ public final class SystemServer {
        w.getDefaultDisplay().getMetrics(metrics);
        context.getResources().updateConfiguration(config, metrics);

        // The system context's theme may be configuration-dependent.
        final Theme systemTheme = context.getTheme();
        if (systemTheme.getChangingConfigurations() != 0) {
            systemTheme.rebase();
        }

        try {
            // TODO: use boot phase
            mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());