How to find origin of permission in merged manifest? - android

I added some libraries to an Android app and after upload to the Google Play Store I got this warning:
The main manifest file does not declare this permission, so I assume it comes from a library.
I then check out the source code of the previous version, which did not use this permission.
Looking at the merged manifest file in Android Studio, I still see the permission:
When I click on "Go to declaration" for this permission, it takes me to the main manifest file, which does not declare this permission.
I tried to clean and rebuild the project and restart Android Studio but the permission still shows in the merged manifest tab in Android Studio. It shows in the debug and release build variant.
Why is that?

After building your app you should be able to find a manifest merger report under app/build/outputs/logs. Among other things, this file lists the origin of every permission that has been added to the merged manifest.

Related

Android studio - how to find which library is using dangerous permission?

I am trying to upload a apk to the google play store but its saying to my surprise that i am using the following permission:
Your APK is using permissions that require a privacy policy: (android.permission.RECORD_AUDIO).
so i searched the entire IDE for "android.permission.RECORD_AUDIO" but i cant find it. How can i find out which 3rd party is requesting this ? There should be a way to view in the manifest merger process all the manifest but when i hit shift twice and search manifest only the local manifest are showing up. The other is bit code and i cant view it.
In project build directory, there is a manifest merger report.
In my case, it is located under [ProjectRoot]/app/build/outputs/logs/manifest-merger-debug-report.txt
From this file, your can find where the permission is added. For example:
uses-permission#android.permission.RECORD_AUDIO
ADDED from /home/jack/AndroidProject/ApiDemos/app/src/main/AndroidManifest.xml:45:5-71
android:name
ADDED from /home/jack/AndroidProject/ApiDemos/app/src/main/AndroidManifest.xml:45:22-68
uses-permission#android.permission.CAMERA
ADDED from /home/jack/AndroidProject/ApiDemos/app/src/main/AndroidManifest.xml:49:5-65
android:name
ADDED from /home/jack/AndroidProject/ApiDemos/app/src/main/AndroidManifest.xml:49:22-62
You can use Merged Manifest[About] feature
Open AndroidManifest.xml -> Merged Manifest
If the library is open source you can check their source code for the permissions they have used.
They usually list the permission on their Read.me files.
Even if they are proprietary libs they will list the permissions they will be using otherwise their security is questionable.

What permissions does my android app request?

I know(am I wrong?) that an Android app may request more permissions than specified in manifest file.
E.g. compiling with google play services, or some other third party libraries include permissions I am not aware of.
Is there a way to list all required permissions after building APK file?
I want to know of all requested permissions before publishing the app.
an Android app may request more permissions than specified in manifest file
on the manifest that the developer wrote him/herself yes, but on the manifest actually inside the .apk all the permissions are there
on android studio you can go to the manifest file and on the bottom left there's a little tab that says "merged manifest" that shows what your manifest will be on the final .apk.

Firebase working without permission.INTERNET... How?

My firebase application is running perfectly on my android device without having added the permission.INTERNET flag. I installed Firebase directly from gradle. I am aware that adding Firebase through the project structure window in android studio will add the permissions.INTERNET for you. But this is not the case, my Android manifest has nothing in regards to permission.INTERNET yet is still fully functional...
I havent been able to find any info on this... Is this because its now run by Google?
The documentation for manifest merging states:
During the build process, the manifest merge process stores a record
of each merge transaction in the
manifest-merger-{productFlavor}-report.txt file in the module
build/outputs/logs folder. A different log file is generated for each
of the module's build variants.
You can look there for a detailed explanation of which library is providing the permission.
Or since you are using Android Studio, you can use Ctrl-Shift-N and type "AndroidManifest.xml" to see a dropdown menu of all the manifests in your build and open them to see what they contain.
A feature was added to Android Studio 2.2 to show the results of manifest merging. When viewing the manifest in an Editor window, select the Merged Manifest tab at the bottom of the window to see the contributors to the manifest.
In my build, which includes a number of Firebase libraries, the manifest that adds the INTERNET permission appears to be:
com.google.firebase\firebase-analytics\9.4.0\AndroidManifest.xml
I was manually managing my Mobile Data's permissions and I discover that, if I block mobile data on "Google Backup Transport", I cannot connect to Firebase.
I really think this is the reason You can use Your app even without INTERNET permissions.

Failed to upload new APK to Google Play

Building the release version of my application produces a manifest with a duplicate permission. The build completes successfully, but when I go to upload the new APK to production, I get the following error:
"Upload failed
Duplicate declarations of permission android.permission.READ_EXTERNAL_STORAGE with different maxSdkVersions"
In the intermediate manifests, the release AndroidManifest has the permission in question, but it only occurs once with maxSdkVersion (see below).
myapp/build/intermediates/manifests/release/AndroidManifest.xml
...
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<android:uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
...
Note that READ_EXTERNAL_STORAGE is generated twice, once with the tag uses-permission and once with android:uses-permission.
This error has only occurred today; the last APK I successfully uploaded was about a week ago; no dependencies or permissions have changed in my project since that time.
What I would do:
Clean project and rebuild project (I guess you did).
Delete manually all generated files in folder "build", and rebuild the project.
Check if your different gradle files have different maxSDKVersion, and make them consistent.
Maybe this permission is included in any third library (I know you wrote you haven't, but you should have GooglePlayServices at least, and a SDK update maybe made the conflict) and you only have to remove it.
Nevertheless, I would only specify the android.permission.WRITE_EXTERNAL_STORAGE permission because it should also contains the READ_EXTERNAL_STORAGE one. If it works, maybe is not an explanation of what is happening to you but it's maybe enough.
I just ran into this issue as well. It turns out that one of the libraries that my project depends on includes the READ_EXTERNAL_STORAGE permission, but my actual project does not. Simply adding this permission to my project's manifest fixed the issue.
Cleaned and closed Android studio 10 times, maxSdkVersion is not set in my gradle files, set minSdkVersion consistently in all gradle files and nothing. The only thing that made the trick was manually deleting everything inside the Build folder and built again........problem vanished

AndroidManifest in androidTest directory being ignored

I'm trying to test using the following directory structure (which was setup by Android Studio):
I can run some tests just fine, and even the AllTests.java runs fine without the AndroidManifest.xml file even being there. The thing is, for one of my new tests, I need the android.permission.INTERNET permission. So, I added the following to the AndroidManifest.xml file located within the androidTest directory:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.core"
android:versionCode="2"
android:versionName="2.0" >
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
Unfortunately, this doesn't work. I'm still getting the following error when I run one of my tests:
E/RestAPIRequestTest﹕ Permission denied (missing INTERNET permission?)
I've tried setting the package to be com.example.core.test in my AndroidManifest.xml file (since that is what it shows up as in my Settings->Apps list), but with no joy.
I'm thinking it's not even recognizing the AndroidManifest.xml file, since the version number doesn't show in the Settings for the test app, either.
How can I inject the correct permissions for my test project?
I needed to do something similar. I created a folder named "debug" next to androidTest, which corresponds to the debug variant of the app, and put an AndroidManifest.xml with the permission in that folder. Then the permission works under test since the test app uses the debug variant. It's not ideal because it blurs the line between test and debug, which aren't quite the same thing.
I think what's happening is that the permissions in androidTest/AndroidManifest.xml are going to the test app, not the target app, although it's not 100% clear to me if there are actually two different APKs or what.
In older versions of Android Studio and the Android Gradle plugin the androidTest/AndroidManifest.xml file was ignored. This was documented at the tools.android.com site at the time.
With the Android Studio 1.0+ and Android Gradle 1.0+ plugin launch in December 2014 the AndroidManifest.xml file should now be merged with the normal main/AndroidManifest.xml files (in addition to the debug and release manifest files if they exist). More details regarding the manifest merging rules are here.
If you still run into issues or are just debugging manifest related testing issues try this
(Adapt this slightly for Windows):
Drop to a terminal
change to to your project directory
cd MyApplication
Build your project, assuming 'debug' is the build type you want to test with, but you could also be testing with 'release' or a build script defined one.
./gradlew assembleDebugTest
Then inspect your test APK manifest:
ls app/build/intermediates/manifests/test/debug/AndroidManifest.xml
View your application APK manifest:
ls app/build/intermediates/manifests/full/debug/AndroidManifest.xml
A merge output log can be found detailing the manifest merging process:
ls app/build/outputs/apk/manifest-merger-debug-report.txt
A couple of extra notes:
An instrumentation element is automatically added to your test APK's AndroidManifest.xml so you should only be adding extra activities, permissions, etc that your test APK needs.
If testing with mock locations your application APK will need the ACCESS_MOCK_LOCATION permission. You can add the permission to your debug/AndroidManifest.xml file or you can define that the test APK and the application APK should use the same userId when deployed (sharedUserId attribute in your AndroidManifest.xml).
This is a known problem.
Currently (AGP <= 3.4.X) is not supporting AndroidManifest test merging.
This is reported here: https://issuetracker.google.com/issues/127986458
and here there is the issue created by one of the Roboelectric maintainers.
The workaround as described here its near the same proposed by user3286293 and currently is the only way to have the manifest merged for testing purposes.
Hope to see a fix for AGP 3.5 or 3.6
As specified here, during instrumented tests, there are generated two .apk files. If you take a look, the smaller one it's most probably the one named app-debug-androidTest-unaligned.apk and it actually does include the provided permissions.
Inspecting the file with aapt d permissions <apk_file_path>.apk can be useful to see a list of all of them.
Now, there might be an issue with the context itself where the permission is requested. I had a similar problem, trying to write some screenshots on SD card (thus needing the WRITE_EXTERNAL_STORAGE permission).
This answer helped me to fix the problem, although I cannot fully understand why it's necessary.
In few words, you'll need to declare the same android:sharedUserId in both manifests, in order to merge the permissions when both apks are installed on the same device - that happens when tests are running.
This helped me to separate permissions needed just for testing from the one in production.
You need to define that in build.gradle file:
android {
sourceSets {
androidTest.manifest.srcFile "src/androidTest/AndroidManifest.xml"
}
}
One solution would be like build main apk and test apk in single run.
Example: ./gradlew clean :main:assembleDebug :main:assembleDebugAndroidTest.
This will create a new instrumented main application which has all extra permissions required for test application.

Categories

Resources