Patch up certain kinds of broken notifications.

Notifications in which the icon resource ID is changed after
Builder.build() is called (even, and particularly, as the
last step in the current implementation of
setLatestEventInfo()) were not having their icons properly
parceled. In these cases we now attempt to catch this at
parcel time and construct the necessary Icon object.

But wait! Parceling does not require a Context. So we don't
actually know which package to load the resource from.
Therefore we now allow an Icon to be constructed with an
empty ("") package name, which allows us to complete this
parceling task despite the fact that a Notification does not
know its own package name. (In case you attempt to load a
drawable for such an Icon, loadDrawable will spot the ""
package and instead substitute the Context from its
parameters to try to load the resource.)

As it happens, even though the Notification does not know
its own package name, BaseStatusBar does, because it was
provided at NM.notify() time and is therefore included in
the StatusBarNotification structure. So we can actually
patch up the Icon (if it is TYPE_RESOURCE) and be sure to
get the icon loaded out of the correct package.

While we've got the hood open, this change fixes a couple of
related problems:

  • Foreground service notifications synthetically
    constructed for naughty icon==0 notifications (which we
    are still allowing...FOR NOW) were losing the
    FLAG_FOREGROUND_SERVICE flag (because we're
    re-build()-ing them from scratch rather than rewriting
    the provided Notification object). Now we set the flag
    and hang onto the new notification for next time
    setForeground() is called.

  • We now allow media notifications to avoid getting bumped
    to the top of the notification list if they're
    PRIORITY_MIN. You might want to do that, I guess?

Bug: 21333763
Change-Id: Ia5d1f1acb594c7677bcc75ee3d624da4ffca671f
7 files changed