anyone knows why the Android developers team have implemented the Content-Resolver as a middleman to get data from a Content-Provider. Why not asking data directly from the Content-Provider ?
It means that the Content-Resolver has a special job, what is it ?
Why not asking data directly from the Content-Provider ?
A content: Uri may refer to a ContentProvider in another app. You cannot work with that ContentProvider directly; inter-process communication (IPC) is required. Hence, the API was designed around that IPC model.
ContentResolvers are designed to create an interface for applications to securely access and/or modify data in other applications which run in separate processes. It creates a common contract for content consumer registrations, requests, updates, binding, etc. to be passed between a particular ContentProvider and the content consumer that runs in another process.
Creating a proper and durable interface for transferring data across processes in Android is complex. If you had to create your own IPC client then it would be time consuming and you would likely overlook important aspects of the implementation. A "direct" connection to the ContentProvider is what a ContentResolver provides, but with a lot of the complexity already addressed. It is a convenience to already have that created and well-defined on both sides.
This is a little like a postal delivery system. If you use the postal service, you put an address on a piece of mail and the postal service (ContentResolver) finds the appropriate place to deliver the message (ContentProvider), and then returns any messages to you in response to your message. Your postal service will also handle new address registrations, tell you if the address is invalid, if the package is too big, if the recipient at the destination address is not accepting messages right now, waits if the message queue is full, handles situations where the vehicle carrying the message breaks down, etc. And in the case of ContentResolvers there are a few other things.
You could handle all of that yourself but when you think about real-life message delivery, it's not simple and much easier to use something built by someone else. Likewise for interprocess communication (IPC) in Android. It's not a perfect analogy but hopefully that helps clarify the need for a ContentResolver.
Related
I am working on sharing road traffic information between Android applications, and wondering what is a good transport mechanism.
There are two classes of applications: Publishers post traffic messages they have obtained from various sources (say, an Internet service or a TMC receiver device) and converted to a standard format. Subscribers listen for messages and work with them (e.g. displaying them in a list or guiding drivers around congestions). The system is intended to be decentral: there will be multiple publishers, multiple subscribers and users can mix and match them as they like.
Messages are identified by a unique ID, which remains stable over their entire life cycle. They have an expiration time, after which they are considered invalid. Until then, they can be updated at any time. An update can also cancel the message (replacing it with a tombstone until it expires), or extend its expiration time.
Subscribers get new messages as they arrive. (Filtering may happen in a later phase.) They also need a way to retrieve all currently cached messages from all publishers.
A message is around 1 kByte in size. A publisher can easily hold several hundred active messages at any given time.
In terms of security, the messages are generally public information. The only sensitive information is geodata, as it may allow for conclusions on the location of the device or where its user intends to travel. The precision of such data is low, anywhere from city to country level. Therefore I don’t see a need to hide this information from any app, as long as it has location permission.
Now I am wondering what a good transport mechanism would be:
Option 1: Broadcast intents
Initially I have been working with broadcast intents: whenever a publisher has any new messages, it sends an implicit broadcast with the messages in the extras. Subscribers can register a broadcast receiver at run time to receive messages. They also have the option to send a poll broadcast (an explicit broadcast, with the corresponding broadcast receiver declared in the publisher’s Manifest). Publishers will then respond with a feed of all currently cached messages. To address security concerns, any app sending a broadcast with geodata requires that the receiver hold one of the location permissions.
There is an issue with large feeds, as the Android request broker supports a maximum of 1 MByte for all concurrent transactions (so the maximum amount of data in a feed can be even less if things are busy). I am currently working around that by breaking down feeds into chunks of 100 messages or less.
An advantage of this system is that all central infrastructure is provided by the OS. Having one publisher and one subscriber app installed is sufficient.
Option 2: Content Providers
Some people have pointed out that broadcast intents are not the best way to go, and have suggested I implement a content provider, a territory into which I have not ventured so far. Looking at the documentation, it is not clear if there is a way to have multiple backends (each backend being a separate app) implement functionally identical content providers and advertise them as such. Since content providers support both read and write operations, I could set up one central component as the content provider, and have both publishers and subscribers connect to it. However, that would require providing a central component in order to work, which I would rather avoid.
Questions:
Is there a way to implement the above multi-publisher, multi-subscriber model with content providers, and without having to supply a central component not already provided by the OS?
Specifically, can a single content provider have multiple backends? Alternatively, can multiple, functionally identical content providers advertise themselves as a group?
How would I implement the above using content providers?
What are advantages and drawbacks of broadcast intents or content providers that I may have missed?
Is there a way to implement the above multi-publisher, multi-subscriber model with content providers
Keep the broadcasts. Replace the payload.
Publishers would implement a ContentProvider that serve up the current roster of messages. You can think of a ContentProvider as being a quirky sort of REST-style Web service, where Uri values get mapped to responses by the provider.
Publishers would then send broadcasts as they are today, but perhaps with only two extras:
One that identifies the protocol version that the broadcast is using, since you have lots of independently-updated parties. Rceivers need to know how to interpret the broadcast, as you might change the rules over time.
One that contains a Uri pointing to the publisher's ContentProvider.
If there are other extras that you are using today that you know will remain small, and you want to still put those in the broadcast, that's cool. Just keep the indeterminate-sized ones out of the broadcast.
Receivers would then:
Look at the protocol version extra and branch to the code to handle that version (today, just one branch, but, hey, future-proofing)
Use that Uri and a ContentResolver to get the messages (and other stuff if needed) from the publisher
You might consider developing this communications infrastructure as an SDK. Even if you are the only one developing apps, you'll want to avoid duplicating all this logic across the apps. And, if third parties will develop apps, you're better off giving them an SDK to work from, rather than forcing them "roll their own".
I am new in android app development and while studying about the basic android components I got confused between intents and content provider as both are being used to send data from one application/component to another application/component . In case of intents we can send data using bundle or extras so why do we use content providers. Can someone please explain me this with a example . Also can we access database in android only using content provider and is this the sole reason why we use content providers ?
both are being used to send data from one application/component to another application/component
Not really.
There are four components in Android:
Activity
Service
BroadcastReceiver
ContentProvider
An Intent is none of those. An Intent is involved when we start an activity, start or bind to a service, or send a broadcast. However, comparing an Intent to a ContentProvider is akin to comparing a shovel with a boot, arguing that both can be used to carry dirt. While true, usually a boot is involved in carrying dirt, but the actual means of carrying dirt is handled by something else, such as a wheelbarrow.
In case of intents we can send data using bundle or extras so why do we use content providers.
We often use different tools for different circumstances. For example, you will find it rather difficult to carry water in a fishing net.
Each of the four components has a different role, particularly in relationship to inter-process communication (IPC):
An Activity drives the bulk of our user interface, including starting up activities from other apps (or having one of our activities be started by other apps)
A Service exists for longer-running operations that are logically decoupled from the user interface, including working with services that are implemented by other apps (or having other apps work with services that you publish)
A BroadcastReceiver is a publish/subscribe messaging system, to allow you to send messages to arbitrary subscribers, or to subscribe to messages from arbitrary senders, across process boundaries
A ContentProvider is for bulk data transfer, whether in the form of a database-style structure (rows and columns) or in the form of a stream, particularly for working with other apps
Also can we access database in android only using content provider
No. After all, if that were true, it would be impossible to access a database. A ContentProvider does not appear by magic. It has to be written by a programmer. If a ContentProvider could only access a database by means of a ContentProvider, we would have a problem.
is this the sole reason why we use content providers ?
No. In addition to offering a database-style API, a ContentProvider can also publish a stream. This is important for getting arbitrary data between apps, such as an email client making a PDF attachment available to a PDF viewer.
Intents are a messaging architecture for sending /receiving transactional commands and data. Content providers are an abstract interface to stored data for create,update, delete and sync operations.
to understand the AIDL in android, i want one real life example, means the at what scenario of development we need to use AIDL.
by reading the Android Docs ... It puts me in confusion and so many question, so it is hard to read whole doc for me, can anyone help me
is it for communicating with outside the phone.
or to communicating with different apps, (why we need to communicate with other apps)
what kind of service they are talking in docs
AIDL is used for Binder. Binder is a mechanism to do RPC calls on/from an Android Service.
When to use AIDL? When you need a Service. When do you need a Service? If you want to share data and control something in another application, you need a service using AIDL as an interface. (A Content Provider is used when sharing data only).
Services can be used within your application as the model roll in the MVC-pattern.
AIDL is Android Interface Definition Language. This basically allows you to do IPC calls.
Use: There are situations where one process would need to talk to other to obtain certain information.
Example: Process A needs info of Call status to determine whether it needs to change Call Type (for example Audio to Video Call or Vice-versa). You may get call status from certain listeners but to change Call type from Audio to Video, Process A needs a hook to change. This "Hook" or way of changing calls is typically part of Telephony Classes which are part of Telephony Process. So in order to obtain such an information from Telephony process, One may write a telephony service (which runs as a part of android telephony process), which will allow you to query or change call type. Since Process A(Client) here is using this remote Service which communicates with Telephony process to alter call type, it needs to have an interface to talk to service. Since Telephony service is the provider, and Process A (client) is the user, they both need to agree on an interface (protocol) they can understand and adhere to. Such an interface is AIDL, which allows you to talk (via a remote service) to Telephony process and get some work done.
Simply put in laymen terms, AIDL is an "agreement" Client gets, which tells it about how to talk to service. Service itself will have a copy of that agreement(since it published for it's clients). Service will then implement details on how it handles once a request arrives or say when someone is talking to it
So process A requests to change call via Service, Service gets the request, it talks to telephony process(since it's part of it) and changes call to video.
An important point to note is, AIDL is only necessary for multithreading environment. You could do away with Binders if you don't need to deal with multithreaded arch.
Another real world example is Google Play License is using AIDL.
I have the same thinking about an example of AIDL, it's very difficult to find an idea to make an example app which uses AIDL. Then I have an idea about it create a LocalLogServerApp. Maybe it can not become a production app but it still shows some value in using AIDL
The main function of this app is
Receive the local log from other local apps (another app need to implement AIDL to send log)
Save the log to datastore
Display the logs
Maybe do something with the local log (eg: search, delete)
Maybe notify developer when error log happened
The benefit of this app
The local log can use when you have some very strange issues which sometimes happened in a few moments and in some specific device. In this case, common Log won't help, debug won't help, Firebase Log may help but Firebase receive log from multiple device.
Reusable, many apps can use it with less code
Hope you find this idea helpful to find another better AIDL example
https://github.com/PhanVanLinh/AndroidLocalLogServer
https://github.com/PhanVanLinh/AndroidLocalLogClientTest
1 - is it for communicating with outside the phone.
Its communicating with outside the app.
2 - or to communicating with different apps, (why we need to communicate with other apps)
As #GodOnScooter mentioned, when your app communicates with telephony service which is actually an other part.
3 - what kind of service they are talking in docs?
This is a service which runs in different process of a system, To bind to this service you need IPC(inter process communication), AIDL is used to implement this.
Is the interprocess communication provided by Binder in Android protected against man in the middle attacks? Is there any documentation that provides this info?
Binder uses a capability-based security model. Each binder object represents a capability; handing that object to another process grants the process access to that capability. From that perspective, you prevent man in the middle attacks by not handing an important binder object to the man in the middle. If a process doesn't get handed a binder object, it can not access it in any way.
Regarding the "cross-binder reference forgery" issue discussed in the paper, if I am understanding the specific scenario they are talking about, I think their addendum about user space is a little weaker than I would agree with. They make the mistake I think of looking at the special C code written for the ServiceManager. Formally, I would consider the C++ user space code (consisting in particular of Parcel) as being part of the Binder architecture. This code in particular makes sure to deal with such attempts at spoofing when you call its readBinder() and related methods.
I don't agree with the statement that it is a flaw that the kernel is not completely ensuring integrity of the data. The only way I could imagine for it to do that would be to defined a standard typed data structure for binder transactions, so that it could read and verify the contents of the parcel. This puts too much knowledge in the kernel in my opinion, and for no real benefit. No matter how much you put there, user space will need to do some kind of validation of the incoming transaction to ensure it matches its expectations. Today this is done at the level of validating that primitive data read operations on Parcel (readBinder(), readString16(), readInt(), etc) are written to avoid attacks. Pushing more validation to the kernel will still require validation in user space that data types are correct, and now you have actually moved some opportunities for attacks (due to bugs in this code) from user space to the kernel.
One final thing about binder security is that it is important to realize that at the platform level there is another important security model implemented on top of the binder infrastructure. This is the permission/uid-based system, where services can check the uid of incoming calls to verify them against their allowed permissions.
This security model has another spoofing vulnerability that it must deal with. A typical scenario would be an application receiving the IBinder for the Activity Manager Service (since everyone can get that). The API of the Activity Manager Service is deeply based on checking the uid of incoming calls to determine what is allowed -- for example if a call to bindService() is made, it will check to see if that uid has permission to bind to the given service. A malicious app could try to play games here by handing the activity manager IBinder to another system service, for example as an IWindow to the window manager. If it knows the transactions that the second system service will make, it could set things up so that it makes a call that it thinks is say resizeWindow() but actually ends up becoming a call to bindService() when it comes put in the activity manager (if those two calls are mapped to the same transaction ID).
This vulnerability exists because the binder system is not typed in any way, "method" calls are simply transactions being sent with an integer transaction code and data buffer.
To protect against this, the user space typed interfaces generated by aidl always put at the start of their transaction buffer the name of the interface they are intending to call, and the receiving code of the transaction checks the interface name at the front of the buffer to ensure that it matches its own interace. This way the spoofer in the scenario above will be caught when the activity manager sees that it has an incoming call whose interface was for a window.
Anyway, for most practical use by Android developers, uid-based security is just as relevant as the core binder capability model. In some cases you will enforce security by restricting which processes get access to a binder. An example for this would be how there is an IBinder representing each activity, which only the system process and the process running the activity share.
In other cases and IBinder object will be shared with any interested processes, but enforce security at point of call based on uid. If you are using aidl to supply your standard implementation of such interfaces, your own implementation of such security can be done based on what meaning you want to apply to uids. For example, you could use the standard facility to associated permissions with uids and ask the package manager if the incoming uid has a permission.
The Binder has one identified security flaw which may make it susceptible to a MITM attack: http://crypto.hyperlink.cz/files/xbinder.pdf . To quote TFA:
the attacker can manage the target to further pass on or call its “protected” binder (that the attacker is not invited to call directly). We call this a cross-binder reference forgery (XBRF)
The author goes on to say that there are defenses in Android against this attack, but that
in some situations, a careful manipulation with the transaction data prepared by an attacking process may still lead to a successful XBRF exploit
One gets the impression that Binder seems to be relatively secure for carefully-written code, but there is some risk.
I would like to re-design my application into components, so it is more modular and easier to re-use in the future, but I've never really designed applications, so I don't really know how I should do this.
Here is a brief description of the application:
The purpose of the Application is to allow the User to create "Events" that are going to be stored locally on the Device and sent over the network.
The User can interact with the application through 2 Activities: A "NewEventActivity" that allows him to create the new Events and a "LogbookActivity" that allows him to browse previously created Events.
The local storage should be handled by a SQLite Database
The Event should be sent in a specific Binary format.
Other applications should be able to Use the Sending component to Format and send other type of messages in the same format.
This drawing represents how I was thinking of organizing the components. Boxes represent components, and arrows represent interactions without those components.
Here are my questions:
Does this model look OK? Can you see something that could be improved?
Should my SQLiteHelper be a ContentProvider or a ContentResolver?
Should I create one BroadcastReceiver class per type of Signal, or should I create one big BroadcastReceiver that handles all the kind of Signals my application can handle?
Thank you!
A few suggestions to simplify the design:
If EventWriter and EventReader only interact with the activity due to direct user interaction, they don't need to be BroadcastReceivers. In fact, they could just be methods in the activities.
Depending on how you choose when to send Events, you could also refactor MessageFormatter and Sender into an IntentService which will periodically poll the content provider and choose which pieces of data to send. You can schedule the IntentService via alarms.
Should my SQLiteHelper be a
ContentProvider or a ContentResolver?
It should implement ContentProvider (since it provides access to data).
Should I create one BroadcastReceiver
class per type of Signal, or should I
create one big BroadcastReceiver that
handles all the kind of Signals my
application can handle?
I lean towards one receiver per signal type, but that's really just a preference.