I've googled enough, but couldn't find this case. I want to write a custom Content Provider that is shared/accessible to only specific apps.
I've this scenario:
Have multiple apps on Google Play. Say A, B and C.
Want to write a Content Provider, say Z that could only be accessed by A, B and C. I'm thinking to publish Content Provider 'Z' as its own apk.
When Z is installed on device; A, B and C can access Z. If Z is not installed, then first app will direct to Google Play to install Z.
Now my question is:
Is it possible at all to write such Content Provider at all, which is only shared among specific apps? android:exported="false" makes it inaccessible by any other external app. android:grantUriPermissions="true" doesn't work when android:exported is set to false, and setting android:exported to true makes it public accessible.
Please feel free to share other solutions too, if they seem more appropriate to my requirements of sharing info among multiple apps.
android:grantUriPermissions="true" doesn't work when android:exported is set to false
Yes, it does.
However, android:grantUriPermissions may not be relevant for your use case, particularly if Z is its own standalone app. Z would have to be the one calling into A/B/C using an Intent with the FLAG_GRANT* flag, and I am guessing that this would not fit your plan.
If, as I suspect, A/B/C need to access Z independently of Z telling them that it can be accessed and granting the Uri-specific permissions, the standard approach would be to use a custom signature-level <permission>. You would then defend export the provider and defend it with that permission using android:permission in the <provider>. The theory is that only your app suite can hold that permission, because only your app suite will be signed by that signing key and therefore have a signature match.
(I say "in theory" because there are issues with this approach)
Related
I am writing an application where, after successfull login and based on the user profile, the user can only see certain activities. For instance, if user has profilA, he can only see Activities A, B, C. If he has profilB, he can only sees Activities D,F,G.
Note that I could write 2 applications and my problem is solved easily but the requirements are the app should manage profileA and profileB.
I was thinking about custom permissions to implement this. Where each activity will be restricted with a custom permissions. For instance, Activities A,B and C would be restricted with com.myapp.permissions.profilA. And Activities D,F and G would be restricted with com.myapp.permissions.profilB.
While searching again, I have found the permission-tree element and the PackageManager.addPermission(PermissionInfo info).
The javadoc of addPermissionsays :
Add a new dynamic permission to the system. For this to work, your package must have defined a permission tree through the tag in its manifest. A package can only add permissions to trees that were defined by either its own package or another with the same user id; a permission is in a tree if it matches the name of the permission tree + ".": for example, "com.foo.bar" is a member of the permission tree "com.foo".
The idea that I have is, define a permission-tree, after successfull login, based on the user profile, "sets the custom permissions" of the application. I don't know if it's possible.
It's a similar feature when certain apps hide some admins features to their users. I am thinking of similar functionality.
Is it possible to achieve this functionality? Or do I need to think for another solution?
I am open to all propositions.
There is an easier way to go about about. In your API, create a user_code for each user so that after a successful login, you can get the user_code for the currently logged in user. Once you get the code say in the Home/Dashboard Activity, you can check if the user is allowed to access a certain activity and if they are not allowed, you can probably return an alert dialog telling them that they don't have the rights.
It seems that defining custom permissions to restrict access to certain activities is not exactly what you need. Seems to me that you're going on the wrong direction...as the documentation states...creating custom permissions is relatively uncommon...I mean permissions were designed to reduce security issues and sandbox applications from each other....the latter doesn't seem to be your case.
Anyway, it is extremely uncommon...IMHO, to create custom permissions for the mere purpose to restrict access to certain activities. Especially, because the same way you login a user and the same way you determine what a specific user is allowed to do...it's exactly the same way you can determine when to restrict access to a specific part of your app
Not really sure why you would need to rely on the permission system to do this. What I'm thinking is that you can just create logic to disable whatever features that would lead to those Activities from being launched based on the logged in profile.
If your activities don't have any filters that would allow them to be launched implicitly by another intent, then that means your app complete control over when they're launched.
Use the login result to control what you display to the user. If you wanted to, you could create two separate XML layout files. One that has buttons for A, B, and C, and the other that has buttons for D, E, and F.
Just because an Activity exists doesn't mean it's automatically displayed to the user as an "entry point". You're doing that through what you display in other activities.
I tried to search for this particular case but didn't find anything yet. Sharing data between two applications is possible with ContentProvider and you can set protectionLevel to signature, so applications with that signature can access the data (same publisher).
But what if the scenario is following:
Developer A and B publishes application.
Me, A and B decide to do some co-work together. I am to provide my own application, but I need to access both A and B private information.
Is this possible? A and B would need to grant my application to access their let's say ContentProvider
Thanks.
Setting protectionLevel to signature will only allow to access data between applications signed with the same key (in this case A, B and you should agree on using the same key to sign your published applications).
If this is not the case, then A and B should export their ContentProvider and (optionally) provide permissions to read/write data. If they define permissions, then your client application should specify this permission in the manifest.
References:
http://developer.android.com/guide/topics/manifest/provider-element.html
http://developer.android.com/training/articles/security-tips.html
I have multiple apps that have some sort of in-app currency (i.e gold).
The gold (Integer value) should be accessable through all of my apps. All of my own apps should be able to read/write the value.
It is important that only my apps are able to write the value, it doesn't matter if anyone else can read it.
It's also important that I do not know which of my apps is installed. There is no 'main'-app at all. It should be irrelevant which of my apps is installed and in which order.
The value does not have to be shared between the apps during runtime, I rather thought of something like sharedPreferences or an SQL database.
Where/How should I store this value?
Which is the preferred solution to this problem (if there is any)?
If you need to share data between two (or more) apps, you can set to them the same android:sharedUserId (in AndroidManifest.xml) so the other app can read/write in the private data of the other app.
android:sharedUserId
The name of a Linux user ID that will be shared
with other applications. By default, Android assigns each application
its own unique user ID. However, if this attribute is set to the same
value for two or more applications, they will all share the same ID —
provided that they are also signed by the same certificate.
Application with the same user ID can access each other's data and, if
desired, run in the same process.
Doc here.
The following link gives a brief description about package installation process in android.
http://java.dzone.com/articles/depth-android-package-manager
I'm curious to know how the UID of an app is determined during its installation based on set the permissions present in its manifest file.
Also there is the platform.xml (in /frameworks/base/data/etc directory for 4.0 ICS Source code)file which contains list of permissions with gid associated with them. The description says
The following tags are associating low-level group IDs with
permission names. By specifying such a mapping, you are saying
that any application process granted the given permission will
also be running with the given group ID attached to its process,
so it can perform any filesystem (read, write, execute) operations
allowed for that group.
In a similar way there is a list of high level permissions assigned to specific uid's as well.
My question is when an app is installed with permissions X,Y, Z how does its access specified is it from the mapping from this platform.xml
Also everytime the app is run does the mapping take place at every instant (that doesn't seem right from the initial design of android where the app permissions cannot be changed unless there is an update). So if that is the case where does it store saying this app should run with such and such access or such and such uid.
I hope I made my question clear, let me know if you need more information. I'm just trying to learn more on how the internals of the Android OS work.
Thanks
The UID of an application does not depend on the set of the requested permissions. In general case, during the installation PackageManager assigns a unique UID to an application from a set [FIRST_APPLICATION_UID; LAST_APPLICATION_UID] (actually, this process has slightly changed with the introduction of multi-user support):
The Android system assigns a unique user ID (UID) to each Android application and runs it as that user in a separate process.
What you are talking about is a limited set of GIDs (group ids) that is assigned to an application based on the permissions. For instance, to limit access of applications to the network interface a special patch has been added to Linux kernel, which allows a process to create net sockets only if this process has a special hardcoded GID. Thus, during the installation of an application if a user accepts the permission "android.permission.INTERNET", PackageManager assigns a special GID to this application (based on the values in platform.xml file). During the launch of this application, a process of this app is setgid'ed with the value. Thus, the process of application obtains a right to create sockets.
Other permissions are enforced on Android Framework level.
The permission requested by app only impact the GID but no the UID of the application.You may interested in check this article for all the uid and gid stuff.
For instance, let's take android.permission.GET_PACKAGE_SIZE.
Searching for this string in Android 1.6 *.xml source files only points to a single application that uses it, frameworks\base\tests\AndroidTests.
So the next step is to search through the .java files in a hope that I'll eventually find the code that might look like it queries for package size.
Is this the supposed way of discovering permission use?
The Manage Applications UI uses the API protected by this permission. It probably doesn't request the permission in its manifest because it runs as the system user ID so is implicitly getting the permission.
For applications in general, yes you can look at their AndroidManifest.xml to find the permissions. This is complicated by shared user IDs, which allow multiple applications to run as the same uid, and thus share permissions; any such app requesting a permission grants that permission to all such apps. The settings app, which has the Manage Applications UI, uses the "system" shared user ID so gets all such permissions available to the system.
Generally speaking, you find out what permissions you need because they are referenced from APIs you want to use, normally in the docs, occasionally by exceptions.
Conversely, if a given permission is not cited in the docs, except where it is named (e.g., on Manifest.permission), then it is probably a system permission that you are ineligible to hold unless you are working on alternative firmware.
And, if you are working on alternative firmware, you'd be well-versed in searching the source code. I use Google Code Search, personally, such as this search for your desired permission.
So, in the case of GET_PACKAGE_SIZE, the only place you find it in the docs is in Manifest.permission, and the only place the source code requires it is in a non-SDK method, so I suspect you cannot hold it.
Just check the docs.
GET_PACKAGE_SIZE : Allows an
application to find out the space used
by any package.
http://developer.android.com/reference/android/Manifest.permission.html
EDIT
I may have mis-understood the question. If you want to know what code is using a permission value. Then you will in fact have to dig through the source yourself.