I've looked at this a bit, to see if there is a workaround, especially a workaround that could be transparent to app developers. Here is what I've found thus far.
Prior to Android 4.4, Android's WebChromeClient class had an undocumented public openFileChooser() method that had a default implementation to ignore what was passed to it. CordovaChromeClient.java would override that method to grab a reference to the ValueCallback, start a file picker activity and get the result, and pass the value back by invoking ValueCallback.onReceiveValue(filePickerResult). I think that is basically the callback which allows us to take the result from the file picker and set the value of the form's input object. There has been chatter that this undocumented public method has disappeared in 4.4, but I think that is a red herring, it should still be there: see https://android.googlesource.com/platform/frameworks/base/+/android-4.4_r1/core/java/android/webkit/WebChromeClient.java - it is still there and unchanged from 4.3. But note that the javadoc for that method has always had a "@hide" tag, which keeps it out of the generated javadoc and appears to also remove that method from the android.jar in the SDK on the workstation (which is why Eclipse complains if @Override is used in CordovaChromeClient.java - android.jar on the workstation has only the non-hidden public methods). That's fine, because the android.jar from the workstation doesn't go into the apk, I'm assuming that the full class with public-hidden and private methods (in dex format) gets resolved at runtime on the device, which includes the openFileChooser() method in WebChromeClient. So I think it is safe to ignore the "openFileChooser() method was removed in 4.4" discussion, though it is hard to explicitly prove it other than looking at the Android source.
So then that means that our openFileChooser() probably isn't getting called. https://code.google.com/p/android/issues/detail?id=62220 fits right on that, and reading comment #24 there indicates there is a Chromium bug that was fixed in the Chromium source on Nov 19, which will be shippable in a later version of Chromium. So the hope is that fixes it, assuming there is a way to get that newer Chromium on the device ( see https://plus.google.com/+GoogleChromeDevelopers/posts/4QYG9AE589M )
So on to looking for any viable workarounds...
The type="file" input button does generate an onClick event. So anyone can write js to respond to that event. But the value property of the type="file" input object in the DOM is read-only in js, so it isn't possible to set it from js. That is for security reasons.
So if it is not possible to set the input value via js, and openFileChooser() in CordovaChromeClient no longer gets called so we never get a handle to the ValueCallback, I'm not seeing any way that we could set the value of the file input button, even if we were to provide our own picker activity. This means there is no way for a type="file" input to be used to store the result from a picker.
So then that leaves the us with having to use some other type of input object to store the filename. And the expected issue with that is the browser's form processing wouldn't know to send the file's contents instead of the filename. Perhaps we could take over the submit action and do an xhr2.send(FormData) using a transient form we constructed ourselves from the original HTML one, with the same action and method. But this sounds like a bad idea, similar to our earlier effort to recreate a camera app to keep our suspended activity from getting killed when RAM runs short.
So now it sounds like there is no viable way to workaround this in a way that is transparent to an app developer. The only workaround is for them to modify their app to use the FileTransfer plugin in the case of Android 4.4, assuming their server's service endpoint can deal with that input/upload.
Does anyone have other ideas on a viable workaround? Anything I've gotten wrong?