Getting all Permissions from APK, Android 6 - android

With Android 6's dynamic permissions, is it possible to get all the permissions an APK requires from a compiled apk?
The problem is that in our project, we sometimes add third party libraries to our project, and sometimes they require more permissions than our app initially required. I would like to be able to detect such situations at the CI build stage.

"Dynamic permissions" (a.k.a., runtime permissions) do not change anything. They all still have <uses-permission> elements in the manifest. aapt dump permissions, or reading in the merged manifest, will tell you what is requested by your current manifest.
This does not help with libraries that do not publish a manifest in their AARs that contain the <uses-permission> elements required by the library. Hopefully, the authors of such a library document what they are expecting and you are adding the <uses-permission> elements to your own manifest.

Related

Prefix permission name dynamically in AndroidManifest to avoid duplicate conflicts

I have an Android Library, in its manifest there are a set of permissions declared and used. This library needs to be bundled with different apps. When installing, it says duplicate permission declared across apps. The apps would be of different signature.
In order to use the same permission across apps, can we prefix the permission name in the library with packageName (like ${applicationId})?
When I try to prefix permissions with ${applicationId}, it gets substituted with the library's packageName. Is there a way to replace it in the top level apk or any other way out?

What permissions are needed by each Google Play Services component?

As I found out in Why are permissions being automatically added to my AndroidManifest when including Google Play Services library, various Google Play Services components implicitly add permissions to your app starting in Google Play Services 7.5. But obviously not all components require the same permissions - for instance, play-services-games:7.8.0 doesn't require any.
Is there an easy way to tell what permissions will be added by a particular Google Play Services component?
Visit $ANDROID_SDK/extras/google/m2repository/com/google/gms. In there, choose your desired artifact (e.g., play-services-maps) and version (e.g., 8.1.0). Open up the AAR in your favorite ZIP utility, and look at the AndroidManifest.xml file published in there, to see if there are <uses-permission> elements. Then, open up the POM file, see what dependencies there are, and repeat the process for the AARs for those dependencies.
As described in this excellent article, you can see the final manifest file created during the build process here;
app/build/intermediates/manifests/full/debug/AndroidManifest.xml
You can also see a report that shows where every permission comes from;
app/build/outputs/logs/manifest-merger-debug-report.txt
You can use a line like this in your manifest to remove any extra permissions you want (but be careful! you might break functionality);
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="remove"/>

Android manifestmerger.enabled does not work for sharedUserId

In my Android library manifest file I have set sharedUserId property.
I have referenced to this lib project in my app1 and app2.
I have added manifestmerger.enabled=true to project.properties files of both apps.
However sharedUserId does not work (note: it works ok if I set thisproperty to app manifest file directly).
While looking app/bin/AndroidManifest I dont see this property - so looks like merge didn't happen.
I am using Eclipse ADT build22.3.0
Any idea what is the problem?
Basically what I want is to have ability to expose propery from my jar library.
This is not intended to work.
From the inline documentation of the ManifestMerger class
- root manifest: attributes ignored, warn if defined.
The Android Manifest documentation lists android:sharedUserId under the root element of the Manifest file, so it will be in the group of things which cannot be merged in from a library.
You may of course have additional issues preventing merging from working in general but even after those are corrected it should not work for sharedUserId (and other root level attributes) in specific.

Android Library Manifest vs. App Manifest

I've read similar questions here, but am still not clear on a couple of things. Using a Library Project means that my overall project will have two manifests -- one for the library and the other for the "main" app project -- and I'm not clear what goes in which or if there is some redundancy.
I'm developing an app widget with "lite" and "paid" versions, so will have almost all code in a library project. Being a widget, the library will have at least a receiver, a service, a configuration activity, plus a couple of other activities. So where should the full declarations of these components -- including intents, filters, etc. -- be declared? Do they go in the manifest for the library, or in the manifest for the application package itself, referencing the classes in the library (e.g. android:name="com.foo.mylibrary.MyService")?
Some examples I've looked at seem to declare them in both manifests, but I suspect that putting these in one or the other is a no-op.
Using a Library Project means that my overall project will have two manifests -- one for the library and the other for the "main" app project -- and I'm not clear what goes in which or if there is some redundancy.
The library project manifest is not presently used.
Gradle for Android, and therefore Android Studio, support library projects and AARs publishing a manifest. This can include things like activity declarations, required permissions or features, or minimum supported Android SDK levels.
The rules for how library manifests are merged with the app's own manifest -- particularly when you take build types and product flavors into account -- is a bit complex.
So where should the full declarations of these components -- including intents, filters, etc. -- be declared?
In the host project.
The library could publish those components, and the Android Studio host project can then remove them if needed.
Do they go in the manifest for the library, or in the manifest for the application package itself, referencing the classes in the library (e.g. android:name="com.foo.mylibrary.MyService")?
The latter.
In either (with Gradle for Android and Android Studio). In theory, it is easier for the library to publish the components, so the app author does not have to. Personally, I am not a huge fan of this, as too many developers will wind up shipping unnecessary manifest entries.
As of ADT r20 Preview 3 it is now possible to merge manifests. So common configuration can now be put into the library manifest. See https://stackoverflow.com/a/10400355/262789 for more information.
Version 13 of Intellij IDEA is necessary for manifest merging support (manifestmerger.enabled=true). Also the Grade based build system appears to be necessary for Android Studio support.
Any referenced android elements like activities, receivers, services, etc. MUST go into your Application manifest or they won't be recognized by the OS. As you guessed, the Library manifest file is pretty much an empty implementation
UPDATE
As CommonsWare points out above, the Android build tools will now attempt to merge the various manifests on your behalf. Leaving up the original answer for posterity

For android library projects, is <uses-sdk> meaningful in manifest?

It's all pretty much in the title. Although I see <uses-sdk> specified in all the example library project's AndroidManifest.xml I've seen, I have a feeling it's irrelevant.
In fact, I suspect that <uses-permission> is also irrelevant, as are all of the attributes of <manifest>, other than package.
Can anyone confirm?
As of ADT r20 preview 3
Library manifests can be merged with the main application manifest. This is enabled in an ant build by specifying the property
manifestmerger.enabled=true
[I'm not sure how to enable it in other (e.g. maven) builds; please comment here if you figure it out. I'm guessing it translates into an aapt command line argument.]
A variety of rules govern conflicts and overriding behavior.
Relative to the specific questions raised here (merging of <uses-sdk> and <uses-permission>), the rules for <uses-sdk> are:
minSdkVersion: error if destination manifest contains a value less than the lib value; leave destination value it is same or greater than lib value, store lib value in destination only if none was specified there (defaulting to 1 if not specified in either).
targetSdkVersion: warning if destination manifest contains a value less than the lib value; leave destination value it is same or greater than lib value, store lib value in destination only if none was specified there (defaulting to merged minSdkVersion value if not specified in either).
The rule for <uses-permission> is: add library permissions to destination if they are not already present there. It's OK if the same permission is in both.
If you are using ADT r20 preview 2 or earlier, the following applies:
I created a little test library project and a test app that uses it, in order to get to the bottom of this myself. I provided a <uses-sdk> and a <uses-permission> in the library project's manifest, and omitted both of them from the application's manifest.
The result was that the library project's <uses-sdk> and <uses-permission> values were NOT merged into the application at build time, as evidenced by examining the installed app on my device using the AppXplore tool.
My test code is available at https://github.com/adennie/android-library-project-manifest-test.
My conclusion is that specifying <uses-sdk> and <uses-permission> in an Android Library Project's manifest has no effect on the merged manifest of the consuming application.
possible uses of the manifest in library projects:
have you tried lint? it can warn you if your project is using too-new classes/methods which cannot work on the min-sdk that you've set on the manifest.
wanna check it out? just press the V-checkbox button near the sdk manager , as shown here:
http://tools.android.com/tips/lint/lint-toolbar.png?attredirects=0
the manifest could give a clue for other people of what is required for the project to be used.
you can also add some test activities inside which could allow you to quickly toggle the project from library project to normal project , and do some testing on it.
as google has suggested in the past , library projects might have some use of the manifest in the future by being merged with all of those that use the library project.
in short , the manifest is not meaningless . it can help you a lot .
If your library project doesn't depend on Specific android version then you can omit this tag.
Because uses-sdk will define the sdk version etc..
As per the documentation, It says for <uses-sdk>
The attribute android:minSdkVersion is surely required and if you don't pass any then it will take 1 meaning - App will support all api versions of android and then you will have to make your app support all of them if you dont pass any statically.
Caution: If you do not declare this attribute, the system assumes a
default value of "1", which indicates that your application is
compatible with all versions of Android. If your application is not
compatible with all versions (for instance, it uses APIs introduced in
API Level 3) and you have not declared the proper minSdkVersion, then
when installed on a system with an API Level less than 3, the
application will crash during runtime when attempting to access the
unavailable APIs. For this reason, be certain to declare the
appropriate API Level in the minSdkVersion attribute.
The attribute android:maxSdkVersion is little bit tricky to understand..doc says,
Warning: Declaring this attribute is not recommended. First, there is
no need to set the attribute as means of blocking deployment of your
application onto new versions of the Android platform as they are
released. By design, new versions of the platform are fully
backward-compatible. Your application should work properly on new
versions, provided it uses only standard APIs and follows development
best practices. Second, note that in some cases, declaring the
attribute can result in your application being removed from users'
devices after a system update to a higher API Level. Most devices on
which your application is likely to be installed will receive periodic
system updates over the air, so you should consider their effect on
your application before setting this attribute.
And,
Future versions of Android (beyond Android 2.0.1) will no longer check
or enforce the maxSdkVersion attribute during installation or
re-validation. Google Play will continue to use the attribute as a
filter, however, when presenting users with applications available for
download.
That warning is to indicate Negative points that can happen if you declare that attributes But as you look into other side If you are developing anything that supports some specific Android Version then The ATTRIBUTE is most useful to you.
The step taken to remove that attribute is to encourage developer to make their app supportive to all different(newer) version.
Only if you developing with the version 2.0.1^ then you can say Its not needed to write that but If you write that Google paly will use that as filter for presenting user
So My Conclusion and Advice
use the element <uses-sdk> with atleast one attribute android:minSdkVersion

Categories

Resources