Yes, that is what it would be limited to. But making a cross-platform app which runs on everyone’s devices is no easy task. So I’d probably design it as a web page with most of the features implemented via javascript. And then make a different version of the page for each version of each supported model of flashlight. Abstract out the options so each version and each light can be loaded in from a bunch of definition files. The app would most likely involve significantly more code than the actual firmware it’s meant to configure.
But doing it via a phone app isn’t really much faster or easier than clicking the button a few times to configure it. And if the flashlight needs a companion app in order to configure it, that’s mostly a sign of a bad UI design.
It could be pretty useful as a means of reflashing the firmware or for makers who want an easy way to calibrate things before shipping an item to a customer. Sending an entire ROM is slow though. With no meaningful control over the device being used to transmit data, it would be unsafe to assume a high frame rate. In a browser, for example, even 15 fps may be pushing it. And although the sensor is pretty fast, the sender (screen) is generally pretty slow and possibly even inconsistent because it’s common to see timing aberrations when other parts of the system are busy. Like, if the OS decides to do a routine maintenance task in the middle of transmission, the browser is likely to lose some time slices here and there. So the data transmission timing windows need to be pretty large. And it’ll need a way to detect corrupt or failed data transfers. But when errors happen, the light has no way to send data back so it can’t request corrections. It may thus be necessary to send each byte two or three times to be sure.
Basically, with all the complications added up, it’s an awful lot of effort for very little benefit, and would only be usable for small amounts of data. Maybe a few dozen bytes. And it would likely mean removing other firmware features to make room.