What you describe still doesn't quite cover the amount of feature separation that I'm talking about. Yes, when you start implementing a feature separately, you still have some degree of separation by keeping it in a branch, but once you start pulling stuff into your master branch and merging back and forth between the master branch and the feature branches, that becomes lost too.
Or what about switching to a newer upstream version? Sure, you could go ahead and first rebase every single feature branch individually, then try to merge them back in the same order that they were merged initially (if you even kept that information and assuming that you didn't touch the same code parts in different branches), but again that's much more expensive than keeping a set of simple, readable patches around in the first place.
To sum things up:
- it is possible to do this with git, but it's more work and requires more discipline
- devs at google did not have time to do this part right, thus the result is a set of forks that due to their structure are not easy to merge back upstream
- even with patches or commits from less experienced developers, the same chaos does not happen in openwrt packages
- in openwrt you can get away with not having to fork a lot packages
- in android you have to fork every single package and if it's just for replacing the makefile with an Android.mk file
- in openwrt you have to pay less attention to how a package works internally, most autoconf based stuff can be handled with very few changes compared to a template makefile (often only changing the package name, description and download location)
In my opinion those differences are quite significant