Adding OEM shared resources? (Or current status of the old topic)

962 views
Skip to first unread message

Pekka Nikander

unread,
Jun 28, 2012, 11:26:14 AM6/28/12
to android-...@googlegroups.com
I'm returning to an old topic, discussed a few times in the past:

https://groups.google.com/d/topic/android-framework/6ZdL1aQq8Qo/discussion
https://groups.google.com/d/topic/android-platform/1wFriR-6vOo/discussion
https://groups.google.com/d/topic/android-platform/eCVnMlQYjZc/discussion
https://groups.google.com/d/topic/android-platform/u4o3hNUqzec/discussion

At the time of those discussions, the conclusion was that there was no supported way for adding shared OEM resources.

However, now in the ICS (at least in 4.0.3) there is code, in frameworks/base/libs/utils/AssetManager.cpp, in AssetManager::addAssetPath(), that checks if the resource file that is being loaded starts with "/system/framework". If so, then after having loaded those resources, it loads any corresponding file at "/vendor/overlay/framework/". The resources are apparently added as an overlay to the resource being loaded, clearly augmenting the set of resources, but apparently also allowing one to override some existing resource values.

Now, given this, it looks like there is a way to add OEM shared resources!

In practical terms, and what we have tested in real life, it suffices to generate "another" framework-res.apk, place that at /vendor/overlay/framework/framework-res.apk, and the AssetManager will add the resources from that whenever it reads the /system/framework/framework-res.apk. It "just works".

Now, I'd like to know if this is a supported feature, at any level? Is it supposed to work, or is more that it just happens to work? Furthermore, is the feature likely to stay there in the AssetManager, or is it considered as a hack that may be removed at any time?

Finally, yes, we are fully aware of the problems of that shared resource IDs will cause to binaries and binary-level backwards compatibility. We do understand that Google cannot afford people setting their own shared resource IDs and assume that they can use those code points forever. However, given that what we are doing is essentially a prototype for a platform extension, we are more interested in doing a prototype that looks like a genuine platform extension, which may or may not be integrated to the Android proper, than providing something that can be used as an add-on for a long time.

--Pekka Nikander

PS. For those that are curios to see the details, here is what we have tested:

1. Android.mk for the <package>-res.apk and <package>.apk

In the Android.mk of the shared library, we create a separate target for <package>-res.apk. In that target, we set the following, as has been discussed earlier:

LOCAL_AAPT_FLAGS := -x
LOCAL_EXPORT_PACKAGE_RESOURCES := true

To install the <package>-res.apk as /vendor/overlay/network, we add the following definitions:

LOCAL_MODULE_PATH := $(TARGET_OUT)/vendor/overlay/framework
LOCAL_MODULE_STEM := framework-res

To resolve make dependency problems during a clean build, we further set (*after* including $(BUILD_PACKAGE)) the following:

$(resource_export_package): framework-res-package-target

For other packages that depend on our target, we set up a phony target:

.PHONY: <package>-package-target
<package>-package-target: $(LOCAL_BUILT_MODULE)

For the Java library compilation, we declare a name for the R.java file:

<package>_R_file_java := $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),,COMMON)/src\
/$(subst -res,,$(subst .,/,$(LOCAL_PACKAGE_NAME)))/R.java

Then, in the target for the library itself (<package>.jar), we include the R.java from the resources:

LOCAL_INTERMEDIATE_RESOURCES += $(subst out/target/common/obj/,,$(<package>_R_file_java))


2. Providing shared resources

In the package itself, we have to declare which resources are public. For that, each time we add a new shared resource, we first compile the package once. Then, we copy the relevant new settings from

out/target/common/obj/APPS/<package>_intermediates/public_resources.xml

to

res/values/public.xml

That manual process takes care of what is actually shared, and what IDs they do get. That also avoids having resources to change their values in the future. (And this exactly is what causes the potential problems to Google, if this was a fully-supported feature, as anyone could start making their own shared IDs and assume the IDs to be fixed. I guess Google could set up a registration service, but given how the resource ID space is currently managed, it doesn't seem to be very scalable.)


Here is a complete (but edited) example of an Android.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_PACKAGE_NAME := <package>-res # e.g. com.example.foo-res
LOCAL_MODULE_TAGS := optional
LOCAL_AAPT_FLAGS := -x

<package>_R_file_java := \
$(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),,COMMON)/src/$(subst -res,,$(subst .,/,$(LOCAL_PACKAGE_NAME)))/R.java

<package>_res_package_export := \
$(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),,COMMON)/package-export.apk

LOCAL_MODULE_PATH := $(TARGET_OUT)/vendor/overlay/framework
LOCAL_MODULE_STEM := framework-res

LOCAL_EXPORT_PACKAGE_RESOURCES := true

include $(BUILD_PACKAGE)

ifeq (,$(ONE_SHOT_MAKEFILE))
$(resource_export_package): framework-res-package-target
endif

.PHONY: <package>-res-package-target
<package>-res-package-target: $(LOCAL_BUILT_MODULE)

include $(CLEAR_VARS)

LOCAL_MODULE := <package> # e.g. com.example.foo
LOCAL_MODULE_TAGS := optional

LOCAL_CERTIFICATE := platform

LOCAL_SRC_FILES := $(call all-java-files-under, src)

LOCAL_JAVA_RESOURCE_DIRS :=
LOCAL_JAVA_RESOURCE_FILES :=

LOCAL_INTERMEDIATE_SOURCES += $(subst out/target/common/obj/,,$(<package>_R_file_java))

include $(BUILD_JAVA_LIBRARY)

$(full_classes_compiled_jar): <package>-res-package-target

Dianne Hackborn

unread,
Jun 29, 2012, 8:03:49 PM6/29/12
to android-...@googlegroups.com
This is a feature Sony has been contributing.  To be honest, I don't know how stable it is for production use, because we don't use it in the devices we do.


--
You received this message because you are subscribed to the Google Groups "android-platform" group.
To post to this group, send email to android-...@googlegroups.com.
To unsubscribe from this group, send email to android-platfo...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/android-platform?hl=en.




--
Dianne Hackborn
Android framework engineer
hac...@android.com

Note: please don't send private questions to me, as I don't have time to provide private support, and so won't reply to such e-mails.  All such questions should be posted on public forums, where I and others can see and answer them.

Jean-Baptiste Queru

unread,
Jun 29, 2012, 8:52:16 PM6/29/12
to android-...@googlegroups.com
Those changes haven't been fully merged yet. There's additional work
to do, which I expect will restart after Jelly Bean gets pushed to
AOSP.

JBQ
Jean-Baptiste M. "JBQ" Queru
Technical Lead, Android Open Source Project, Google.

Questions sent directly to me that have no reason for being private
will likely get ignored or forwarded to a public forum with no further
warning.

Pekka Nikander

unread,
Jul 25, 2012, 9:36:34 AM7/25/12
to android-...@googlegroups.com
There are apparently bugs/limitations related to this in AOSP ICS 4.0.3 and 4.0.4. CyanogenMod has some fixes/changes that affect resource overlays. It appears that their changes are not in the main resource overlay code path, but somehow it affects how the resource overlays work. According to JBQ there will be more changes for AOSP JB.

We did our work originally on CyanogenMod, where it "just worked" (hence my earlier report). A couple of days more work was needed to get it working also on plain 4.0.4, and there our solution is right now quite brittle. Our plan is to have a closer look at the situation in AOSP JB, but we haven't had time for that yet.

--Pekka Nikander

On 2012–07–23, at 16:39 , FLZYUP@LiGux wrote:

> I did this method, and it can compile the jar and apk for me. But When I using the resources I added , it said:
> frameworks/base/packages/SystemUI/res/layout/status_bar_expanded.xml:68: error: Error: No resource found that matches the given name (at 'text' with value '@com.ligux:string/test')
> i.e. The other packages like SystemUI cann't find the source.
> LOCAL_PATH:= $(call my-dir)
> include $(CLEAR_VARS)
>
> LOCAL_MODULE_TAGS := optional
>
> LOCAL_SRC_FILES := $(call all-java-files-under, src) \
> ../../../ex/carousel/java/com/android/ex/carousel/carousel.rs
>
> LOCAL_JAVA_LIBRARIES := services framework-ligux
>
> LOCAL_STATIC_JAVA_LIBRARIES := android-common-carousel
>
> #ligux-framework-res-source-path := APPS/framework-ligux-res_intermediates/src
> #LOCAL_INTERMEDIATE_SOURCES := \
> # $(ligux-framework-res-source-path)/com/ligux/R.java
>
> ligux_framework_res_R_stamp := \
> $(call intermediates-dir-for,APPS,framework-ligux-res,,COMMON)/src/R.stamp
> $(full_classes_compiled_jar): $(ligux_framework_res_R_stamp)
>
> $(LOCAL_INSTALLED_MODULE): | $(dir $(LOCAL_INSTALLED_MODULE))framework-ligux-res.apk
>
> LOCAL_PACKAGE_NAME := SystemUI
> LOCAL_CERTIFICATE := platform
>
> LOCAL_PROGUARD_FLAG_FILES := proguard.flags
>
> include $(BUILD_PACKAGE)
>
> include $(call all-makefiles-under,$(LOCAL_PATH))
>
> This is the SystemUI mk file that i modified, anyone has ideas?
> --
> You received this message because you are subscribed to the Google Groups "android-platform" group.
> To view this discussion on the web visit https://groups.google.com/d/msg/android-platform/-/3l36kkTyy2sJ.

FLZYUP@LiGux

unread,
Jul 25, 2012, 11:06:42 AM7/25/12
to android-...@googlegroups.com
I was doing this based on CM10 which is the latest jellbean cyanogenmod version.The apk and jar were built and also add the params in Android.mk, however the other apps like SystemUI cann't refer the resource in my own resources apk
> To post to this group, send email to android-platform@googlegroups.com.
> To unsubscribe from this group, send email to android-platform+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages