Problem with overlaying complex resource

2,935 views
Skip to first unread message

JNC

unread,
Feb 22, 2021, 7:09:29 PM2/22/21
to android-platform
Hi,

I am working with a package overlay and ran into a problem.

Here is the summary of what I am trying to do:
In AOSP Android 10, I am overlaying the default icon (consider this as "sym_def_app_icon") with a complex resource (https://developer.android.com/guide/topics/resources/complex-xml-resources), shown below:
```
<vector android:height="24dp" android:viewportHeight="70"
    android:viewportWidth="70" android:width="24dp"
    <path android:fillAlpha="0.98" android:fillColor="#ffffff"
        android:pathData="M9.1707,..." android:strokeAlpha="0.98"/>
    <path android:pathData="M7,0L63,0A7,...">
        <aapt:attr name="android:fillColor">
            <gradient android:endX="34.6839" android:endY="104.052"
                android:startX="-34.6839" android:startY="34.6839" android:type="linear">
                <item android:color="#FFFBBB90" android:offset="0"/>
                <item android:color="#FF764D30" android:offset="1"/>
            </gradient>
        </aapt:attr>
    </path>
    <path android:fillColor="#ffffff" android:pathData="M28.0461,15..."/>
</vector>
```

In a Makefile, I added:
PRODUCT_PACKAGE_OVERLAYS += overlay_directory
This generates the package "framework-res__auto_generated_rro_product.apk"

Error that I am seeing:
Below is the stacktrace for the exception:

```
12-07 10:00:35.119  2771  2805 E JavaBinder: Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.String java.lang.CharSequence.toString()' on a null object reference
12-07 10:00:35.119  2771  2805 E JavaBinder:    at android.content.res.ResourcesImpl.loadComplexColor(ResourcesImpl.java:1075)
12-07 10:00:35.119  2771  2805 E JavaBinder:    at android.content.res.Resources.loadComplexColor(Resources.java:1070)
12-07 10:00:35.119  2771  2805 E JavaBinder:    at android.content.res.TypedArray.getComplexColor(TypedArray.java:564)
12-07 10:00:35.119  2771  2805 E JavaBinder:    at android.graphics.drawable.VectorDrawable$VFullPath.updateStateFromTypedArray(VectorDrawable.java:2043)
12-07 10:00:35.119  2771  2805 E JavaBinder:    at android.graphics.drawable.VectorDrawable$VFullPath.inflate(VectorDrawable.java:1990)
12-07 10:00:35.119  2771  2805 E JavaBinder:    at android.graphics.drawable.VectorDrawable.inflateChildElements(VectorDrawable.java:836)
12-07 10:00:35.119  2771  2805 E JavaBinder:    at android.graphics.drawable.VectorDrawable.inflate(VectorDrawable.java:734)
12-07 10:00:35.119  2771  2805 E JavaBinder:    at android.graphics.drawable.DrawableInflater.inflateFromXmlForDensity(DrawableInflater.java:144)
12-07 10:00:35.119  2771  2805 E JavaBinder:    at android.graphics.drawable.Drawable.createFromXmlInnerForDensity(Drawable.java:1402)
12-07 10:00:35.119  2771  2805 E JavaBinder:    at android.graphics.drawable.Drawable.createFromXmlForDensity(Drawable.java:1361)
12-07 10:00:35.119  2771  2805 E JavaBinder:    at android.content.res.ResourcesImpl.loadXmlDrawable(ResourcesImpl.java:964)
12-07 10:00:35.119  2771  2805 E JavaBinder:    at android.content.res.ResourcesImpl.loadDrawableForCookie(ResourcesImpl.java:887)
12-07 10:00:35.119  2771  2805 E JavaBinder:    ... 13 more
```

What I had found so far:
When a complex resource is compiled by aapt2, it is split into two files, in which the parent file gets the default name and the child gets a name something like "$sym_def_app_icon__0" (which is referred to by the parent).
But in the function loadComplexColor() in the file ResourcesImpl.java:1075 (from the stacktrace above), the file being returned from the TypedValue is null, instead of the child's filename (which in this case is "$sym_def_app_icon__0"). In Android 8.1, this is indeed the case (the file name is "$sym_def_app_icon__0").

I had looked at the source code for ResourcesImpl and couldn't figure out what's causing this problem.
This issue is not seen in Android 8. Additionally, I changed the aforementioned complex resource to a simple resource and it was being displayed just fine.

Why is this happening? Has something changed in Android 10, that needs additional changes?
If possible could you please explain briefly how the resources are managed and mapped?

Thanks,
Naveen

JNC

unread,
Feb 26, 2021, 12:01:41 PM2/26/21
to android-platform
I made some more investigation into this and it seems more like a bug.

To reproduce this, create a application with an ImageView and set it to a drawable android.R.drawable.sym_def_app_icon.
Using something like this:
```
Resources res = getResources();
ImageView iv = (ImageView) findViewById(R.id.myimageview);
Drawable dr = res.getDrawable(android.R.drawable.sym_def_app_icon, null);
iv.setImageDrawable(dr);
```
This app should appear as following, without any modification to the framework overlays.
default-res.png

Now, try to use a simple resource (something like ic_corp_badge.xml) and try to overlay the file sym_def_app_icon.xml, in a similar manner as mentioned in the example frameworks overlays (aosp_root/frameworks/base/packages/overlays/).
This results in the following:
simple-res-overlay.png

Everything works as expected till now. Now when the same overlay happens to be a complex resource (for example, having a gradient field in the drawable), the overlay fails.
The following image shows this failure:
complex-res-overlay.png

Thanks,
Naveen.

Matthew Morgan

unread,
Jul 6, 2021, 12:27:16 PM7/6/21
to android-...@googlegroups.com


Sent from my iPhone

On Feb 26, 2021, at 12:01 PM, JNC <jnave...@gmail.com> wrote:

I made some more investigation into this and it seems more like a bug.

To reproduce this, create a application with an ImageView and set it to a drawable android.R.drawable.sym_def_app_icon.
Using something like this:
```
Resources res = getResources();
ImageView iv = (ImageView) findViewById(R.id.myimageview);
Drawable dr = res.getDrawable(android.R.drawable.sym_def_app_icon, null);
iv.setImageDrawable(dr);
```
This app should appear as following, without any modification to the framework overlays.
<default-res.png>


Now, try to use a simple resource (something like ic_corp_badge.xml) and try to overlay the file sym_def_app_icon.xml, in a similar manner as mentioned in the example frameworks overlays (aosp_root/frameworks/base/packages/overlays/).
This results in the following:
<simple-res-overlay.png>


Everything works as expected till now. Now when the same overlay happens to be a complex resource (for example, having a gradient field in the drawable), the overlay fails.
The following image shows this failure:
--
You received this message because you are subscribed to the Google Groups "android-platform" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-platfo...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/android-platform/753f921f-1b3b-4291-94ee-f0ad4e2fc308n%40googlegroups.com.
<complex-res-overlay.png>
<simple-res-overlay.png>
<default-res.png>
Reply all
Reply to author
Forward
0 new messages