Suppose I want to develop an application that extends in some way (let me say "cooperate with") a very popular application I obviously don't have control over. Let us also suppose, for sake of simplicity, that the very famous application author won't release an update to block my application.
I studied the application's functionality and identified that it widely uses BroadcastReceivers. I also know, from manifest, the com.famousvendor.intent.INTENT_NAME constants I might use.
The question is straightforward: if I create an application, namely org.zighinetto.tinyapp with a broadcast receiver set for intent com.famousvendor.intent.INTENT_NAME will the tiny app catch the broadcast? Or can those broadcast be received only by the process that fires them?
will the tiny app catch the broadcast? Or can those broadcast be received only by the process that fires them?
There are a number of things that control this.
If the broadcast is secured with a permission, you will not be able to receive that broadcast unless you also hold that permission. It may not be possible for you to hold that permission, depending on the type of permission that it is.
Also, if the broadcast is an ordered broadcast, higher priority apps will receive that broadcast and can abort it (consuming the event, so lower-priority receivers do not get the broadcast). The priority is set via the <intent-filter> (or IntentFilter), and it may not be possible for you to have one that is higher priority than is their own app, depending upon the priority value the original developer held.
There are also other local-only scenarios (e.g., LocalBroadcastManager), though you would not see those in the manifest, and so we can assume that they are not what is being used here... today.
Let us also suppose, for sake of simplicity, that the very famous application author won't release an update to block my application.
They do not need to specifically block your application. They just need to decide whether or not they really want to have the API you are trying to exploit, and they may choose to lock it down if this was more of an accidental API. They might do so in response to a blog post by a balding guy, for example.
Related
I am currently working on an architecture to pass traffic messages (“stationary traffic on A9 between Como-Monte Olimpino and Brogeda”) between applications.
Sources of these messages are dedicated apps: one picks up messages via TMC, others might pull them from various services on the Internet.
Consumers are navigation apps in the typical use case, though other use cases are possible as well.
Multiple sources and consumers can be active at the same time.
When a source receives a new message, it sends a broadcast Intent with the message as an extra. Consumers register a BroadcastReceiver to pick up these messages. (Payload for a message typically being a few hundred bytes.)
When a consumer starts up, I need to provide a way for it to poll every source for messages which the source might have in its cache (while bearing in mind that the consumer has no way of knowing which sources are available).
My initial idea was to do that via broadcasts as well: on startup, the consumer would send an implicit broadcast and each source would respond with a broadcast feed of its currently active messages.
Some sources might not be running at the time a consumer starts up, but may still have messages in their cache that need to be delivered to the consumer. As a context-registered BroadcastReceiver would not be able to catch the poll broadcast if the app is not running, it would seem logical to declare te receiver in the manifest.
However, as of Android 8.0, manifest-declared receivers can no longer be used to receive implicit broadcasts. Furthermore, this comment suggests that even on earlier versions and with some flavors of Android, waking up an app via an implicit broadcast does not work as expected (and the device on which I am developing sems to have that restriction as well).
What would be a good mechanism to let a consumer retrieve all currently active messages from all sources, even if they are not running? Implementing a content provider looks a bit like overkill, so what other options are available?
Your consumer app will need to know:
What sources are installed
What subset of those sources the user wants the consumer app to use (as the user might not want all of them)
Possible ways to know what sources are installed include:
Iterating over a list of known possible source application IDs and using PackageManager to see which are installed
Using some application ID naming convention (if you will be the developer of all source apps) and using PackageManager to see which installed apps adhere to that convention
Using PackageManager and queryBroadcastReceivers() to see which apps implement a receiver for some known action string
Using PackageManager to iterate over all installed apps and see which have a certain <meta-data> entry
You can use SharedPreference and a MultiSelectListPreference, or some similar UI, to allow the user to uncheck particular sources that they do not want the consumer app to use.
Given that you are planning on the sources sending broadcasts to consumers, you will also need the same basic flow in the source apps, to see:
What consumers are installed
What subset of those consumers the user wants the source app to work with
Given that the sources know the eligible consumers, and vice versa, you have a variety of IPC options.
It feels like that most of the communications is source -> consumer. In that case, having sources use broadcasts is reasonable. Bear in mind that those will need to be explicit broadcasts:
Create an Intent with the desired action string
Iterate over the application IDs of the eligible consumers
Use setPackage() on a copy of the Intent to associate it with a particular consumer
Send the "broadcast" of that copy
If I am correct that most of the communications is source -> consumer, then using a broadcast from consumer -> source to "wake up" the sources and get cached data is reasonable, if this will simplify the implementation of the sources. It may be that a regular update broadcast is very similar to the "send the cached events" broadcast.
If there will be substantial differences between those two broadcasts, such that not a lot of code would be shared either on the source or the consumer, you might eliminate the asynchronous nature of that approach and use a ContentProvider, where the source has a provider that the consumer can query.
IMHO, your #1 problem with all of this is privacy and security. N-party communications like this gets tricky to make sure that it is not accidentally N+1-party communications, where the +1 is a piece of spyware.
I have an App which is a BroadcastReceiver and which processes NEW_OUTGOING_CALL intents. There are also other apps on my phone that are registered as receivers for these intents, but mine is registered with a higher priority intent filter, so my BroadcastReceiver gets to see the intents first.
I would like to programmatically be able to prevent any other registered BroadcastReceiver for NEW_OUTGOING_CALL from processing these intents, but I would like to allow the phone call to proceed. Is this possible?
I don't think you can actually do what you want to do. The documentation for this action describes pretty clearly how the system expects this broadcast to be handled:
For consistency, any receiver whose purpose is to prohibit phone calls should have a priority of 0, to ensure it will see the final phone number to be dialed. Any receiver whose purpose is to rewrite phone numbers to be called should have a positive priority. Negative priorities are reserved for the system for this broadcast; using them may cause problems.
If you want to see the number first, you can do that (with a higher priority), but then you have to live with other receivers seeing it after you do. Alternatively, you can see the number last (by lowering your priority to 0), but then you have to live with other receivers seeing the number before you do.
Note that another person suggested aborting the broadcast. Not only does this not make sense since the system needs the result of the broadcast, it also is stated explicitly in the documentation not to abort this broadcast.
Any BroadcastReceiver receiving this Intent must not abort the broadcast.
I'm reading the documentation on developer.android.com (for example, http://developer.android.com/reference/android/content/Context.html#sendBroadcastAsUser%28android.content.Intent,%20android.os.UserHandle%29)
And I don't understand what does sending a broadcast as a user mean. I'm reading this "the user the broadcast will be sent to" but what is the user?
If it means an app, then why sendStickyBroadcastAsUser isn't safe, it should be delivered to the application and no one else.
Please give me detailed clarification with examples. Thanks!
The user is what it says it is : a user of the device. Multi-user mode was introduced in Android 4.2, so that method is there to let you specify which user "session" the broadcast Intent will received on.
Sticky broadcasts are not safe when using the multi-users mode because one user might not want his/her data shared across the device, yet sendStickyBroadcastAsUser makes the broadcast available across all users.
I need to check the vulnerability of my app. I am trying to intercept a broadcast message in android such that no other app is able to use that broadcast, is there any way for this?
No.
The closest you can come is if it is an ordered broadcast, if your receiver is higher priority than any other, you can abort the broadcast when you receive it. However, there is nothing preventing some other app from specifying an even higher priority, and where there is a tie (Integer.MAX_VALUE), there's a tiebreaker. I think the tiebreaker is first-one-installed wins, as that tiebreaker is used elsewhere.
If the broadcast is not ordered -- IOW, most broadcasts -- then you cannot abort it, and all registered receivers will receive it.
FWIW, I fail to see how preventing broadcasts being delivered to other apps helps "check the vulnerability of [your] app".
I'm coming up to speed on Android development and the distinction between an implicit intent and a broadcast receiver is unclear. I was hoping for help in distinguishing these concepts and when to use the two.
Both receive intents, both react to system messages, so why is a broadcast receiver even needed and when is it used as opposed to an implicit intent and intent filter to accept the implicit intent?
Broadcasts are just that -- messages broadcast to anyone listening. They are inherently insecure, and delivery to the intended recipient isn't guaranteed, because there really isn't an intended recipient. For example, the CONNECTIVITY_CHANGE broadcast makes this quite clear: When connectivity changes in an Android device, many apps might be interested. Rather than the ConnectivityManager having to notify each app via specific Intent, it sends a broadcast. Any app that has registered interest in this event will be notified. Any app that isn't running or doesn't care... won't.
An Intent is "sent" when one app or Activity wants to launch another to do something very specific. For example, a file-manager might want to launch an image viewer or video player. Your app might want to launch a very specific Activity within another one of your apps, etc. The communication by specific intents (i.e. including package name and component name) can not easily be intercepted, so it's somewhat more secure. Most importantly, there's only and exactly one "receiver" -- if none can be found, the Intent will fail.
Further, a BroacastReceiver will be active within an Activity or Service and received broadcasts will generally only change state and/or do minor UI updates... for example, you might disable a few actions if your internet connectivity is dropped. By comparison, a specific Intent will usually launch a new Activity or bring an existing one to the foreground.
I am going to compile a list here of all the differences between Implicit Intents (sent via startActivity()) and Broadcasts (sent via sendBroadcast())
Broadcasts, by default, can affect multiple applications at once (Ordered Broadcasts have the potential to be disrupted). In contrast, Implicit Intents will only affect one application. Please note that there may be multiple possibilities of applications that could be affected, but eventually only one will be.
Implicit Intents are handled via Intent-Filters, and Broadcasts are handled via Broadcast Receivers (albeit the intent-filters play a role here too). I have seen in many instances over the web that Broadcasts are compared to Intent-filters and that does not make sense to me.
An Implicit Intent launches an Activity, or a Service. By contrast, a Broadcast launches a Broadcast Receiver. (This, if you think about it, is the core difference between Intents and Broadcasts. It is because of this reason that Broadcasts aren't meant to do too much heavy work, and especially not UI work!)
From the Developers Website:
There is no way for a BroadcastReceiver to see or capture Intents used
with startActivity(); likewise, when you broadcast an Intent, you will
never find or start an Activity. These two operations are semantically
very different: starting an Activity with an Intent is a foreground
operation that modifies what the user is currently interacting with;
broadcasting an Intent is a background operation that the user is not
normally aware of.
I'll add more if I find anything else.