How Do we find what level of Android protection is required for a specific permission.
Lets say we have android.permission.SET_ACTIVITY_WATCHER(docs)
What protection level does it fall into?(docs)
Regular
Dangerous
System or Signed
Signed
You can find some permission with there levels here:
https://github.com/android/platform_frameworks_base/blob/master/core/res/AndroidManifest.xml
and an other solution is the following code sample:
getPackageManager().getPermissionInfo(name, 0).protectionLevel
in you're case is this the infos:
<!-- Allows an application to watch and control how activities are
started globally in the system. Only for is in debugging
(usually the monkey command).
<p>Not for use by third-party applications. -->
<permission android:name="android.permission.SET_ACTIVITY_WATCHER"
android:label="#string/permlab_runSetActivityWatcher"
android:description="#string/permdesc_runSetActivityWatcher"
android:protectionLevel="signature" />
Usually Creators of respective API sets the permission depending who are the recipients of this API.
Best way is to grep the source code for the respective API permission.
Android document fairly states what is intended for 3rd party and what not. Permission is usually "Normal" for all things intended for Normal.
http://developer.android.com/reference/android/Manifest.permission.html#SET_ACTIVITY_WATCHER
To answer your permission question
https://android.googlesource.com/platform/frameworks/base/+/master/core/res/AndroidManifest.xml
Look at fragment .. it is signature permission.
Allows an application to watch and control how activities are
started globally in the system. Only for is in debugging
(usually the monkey command).
Not for use by third-party applications
permission android:name="android.permission.SET_ACTIVITY_WATCHER"
android:label="#string/permlab_runSetActivityWatcher"
android:description="#string/permdesc_runSetActivityWatcher"
android:protectionLevel="signature"
Related
I have main application A that uses other apps as plugins, lets say B, C and D. I have no control over what app will be installed first.
How do I define signature level permission so only main app A can start plugin apps B, C and D?
Plugins don't have UI so user can't start them manually but I need to make sure only my main app can launch them. I tried defining the permission in plugins like so:
<permission
android:name="my.custom.permission.START_PLUGIN"
android:protectionLevel="signature"/>
And then in my main app:
<uses-permission android:name="my.custom.permission.START_PLUGIN" />
This doesn't seem to be correct approach. Can anyone tell me the correct way to achieve what I described above? Thanks.
EDIT: My plugins are implemented as bound services with AIDL interface.
To answer my original question, to make my example work, all you have to do is add permission attribute to your application components you want to protect. This is done in Manifest.xml file.
Let's say you have activity called MyActivity that you want only your apps with START_PLUGIN permission to be able to launch. So in your plugin, you do:
<permission
android:name="my.custom.permission.START_PLUGIN"
android:protectionLevel="signature"/>
and:
<activity
android:name=".MyActivity"
android:permission="my.custom.permission.START_PLUGIN"/>
The last one will ensure that only apps with START_PLUGIN permission can access that activity. So all you need to do is in app that should start this plugin use the permission like so:
<uses-permission android:name="my.custom.permission.START_PLUGIN" />
To decide if you want to use permission with signature level protection, or sharedUserId as suggested by #pskink in comments, consider following:
sharedUserId tightly couples both (or more) apps, enables them to access not only specific activities but their files (even SharedPreferences) and views and basically removes any level of separation
custom permission enables to to specify which parts of your app are to be protected, leaving you with more control but also with the need for IPC like AIDL
Links:
sharedUserId Android Reference
How to access data of app with sharedUserId
AIDL Reference
Android permission protection levels
<uses-permission android:name="android.permission.CALL_PRIVILEGED"/>
I cannot grant this permission in the android manifest file as it shows the following
error:
Permissions with the protection level signature or signatureOrSystem are only granted to system apps. If an app is a regular non-system app, it will never be able to use these permissions.
So,what should i do now?
Permissions with the protection level signature or signatureOrSystem
are only granted to system apps. If an app is a regular non-system
app, it will never be able to use these permissions.
So,what should i do now?
If your app is expected to run on non-rooted devices, then you're simply doomed - you can do nothing, unless you have platform keys to sign your app with it.
Alternatively, you may narrow your audience to rooted devices only but that would allow you to do what you want incl. using features usually reserved for the platform or system apps ony.
Finally you may rethink your approach. Perhaps what you want to do can be achieved other way, w/o need of elevating app privileges.
For this "CALL_PRIVILEGED" permission , you will need a rooted device and the app must be installed as a system app only.
From the documentation (https://developer.android.com/reference/android/Manifest.permission.html#CALL_PRIVILEGED):
String CALL_PRIVILEGED
Allows an application to call any phone number, including emergency numbers,
without going through the Dialer user interface for the user to confirm the
call being placed.
Not for use by third-party applications.
So, the short answer is that you can't use it. What are you trying to accomplish?
I have an app that plays audio. I recently added the permission:
android.permission.READ_PHONE_STATE
so I could tell when a call was coming in so I could mute the audio during the call. I also added the permission:
android.permission.CALL_PHONE
So the user could press a icon to call a phone number. These were minor changes and really don't affect how most people use the app. After I published it I now have users who have tablets that don't have phone capability that they can not download the update and new users who have tablets do not see it in the play store anymore.
I read several posts about using this in the manifest instead of the permissions:
<uses-feature android:name="android.hardware.telephony" android:required="false">
But when I try to test the app on the device I get this error:
Caused by: java.lang.SecurityException: Neither user 10022 nor current process has android.permission.READ_PHONE_STATE.
Does anyone have any suggestions on how I can add these minor features to the app without alienating all of the non-phone users?
I read several posts about using this in the manifest instead of the permissions
You use <uses-feature> in addition to the permissions, not instead of the permissions.
Quoting the documentation:
For any of the permissions below, you can disable filtering based on the implied feature by explicitly declaring the implied feature explicitly, in a element, with an android:required="false" attribute.
So, add back your permissions. Then, use PackageManager and hasSystemFeature() at runtime, to see whether the device has android.hardware.telephony, so you can react as needed.
As #CommonsWare suggested use the following code to check if the device has telephony features available using the PackageManager
PackageManager pm = getBaseContext().getPackageManager();
pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
My application needs that GPS is active at startup as for it to proceed.
Iam testing the app, so I'm mocking the GPS by adding <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" /> to my AndroidManisfest.xml file.
This works ok. But I want to keep things separate. Is it possible to add a permission at runtime when we are testing?
EDIT:
I know from the docs that:
Android has no mechanism for granting permissions dynamically (at run-time) because it complicates the user experience to the detriment of security.
But as a matter of testing the application, is there an alternative?
Thanks
There is no way to add Android permissions at run-time. They must be specified in your manifest.
If you have a separate test application, I believe you only need to put this permission on your test application.
EDIT A test application is really no different to Android than a regular one in terms of permissions. I would just put the permission in your test application's manifest and not worry about it.
I want to define a permission in my Android app, and let other third-party apps to use. This permission is used to restrict calling of my modules. That is, third-party apps must request the right permission to call my module, just like using system permissions defined by Android system, android.permission.INTERNET or so.
In my test, I defined the permission in my app, say "my.apps.permission.my_permission", and then install it on emulator. In some of my Activities, android:permission="my.apps.permission.my_permission" property is added. This property forces the apps calling my activities must have the right permission "my.apps.permission.my_permission". Then in a test app, request the permission in AndroidManifest.xml, <uses-permission android:name="my.apps.permission.my_permission" />
The problem is, in the test app, which will call my permission-required activities, when I call startActivity(), I got a SecurityException : Permission Denied. But, if I defined a permission with the same name in the test app, everything works fine.
And, the followings are my conclusions:
1) It seems that, the permission defined in my app, "my.apps.permission.my_permission", is not visible to other third-party apps. How to make it visible, so that other apps can use my permission just like the ones defined in Android system?
2) Even is visible, Android won't check user-defined permissions with name conflicting.(I test this by define a permission with name "android.permission.INTERNET" in test app and overrides the system-defined one, and require "android.permission.INTERNET" in my app, and still, everything works fine.) If so, every other apps can define a permission with the same name that my module requires, and cheat my app. Is that right?
Anyone can help?
Thanks a lot!
I got the answer.
My own app, which defined the permission for other apps to use, must be installed before other apps who want to use my permissions. Otherwise, those apps must be re-installed, to use my permissions. No other operations or codes are needed, just <uses-permission android:name="my.apps.permission.my_permission" />, the same as other system defined permissions.
And, several apps may define permissions with the same name, conflicting with each other. The first installed app occupies the conflicting permission name, others won't overwrite or change the original permission.