Note: This question is specific to Unity3D
I have a very clean android manifest file in Unity project under Plugins/Android/
folder with no <uses-permissions/>
tag at all. I believe that some permissions in final APK comes from Android Player Settings for-example READ_EXTERNAL_STORAGE
. In my Gear VR project I see following lines added in final manifest which can be accessed in Temp/StagingArea/
:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-feature android:name="android.hardware.microphone" android:required="false" />
Now this is definitely coming from one of the plugins that I have in my project (I have many plugins).
My app is getting rejected from Oculus saying
Your app is asking for excessive user permissions for using user permissions inappropriately.
I found a workaround here, but I dont want to do such a thing as this may result in app rejection once again.
So
Is there a way I can find out that where this permission is coming from?
How to find out if there is some code in my scripts which causes unity to include this permission?
Thanks
Unity will add permissions for you on the fly during build time as mentioned by eriQue of Unity Technologies this is to prevent malfunction of code, and unexpected behaviours.
You could use a tool such as this Apk-decompiler to take a look at your new manifest, and which permissions this uses. Based on that you may look for certain functions that could trigger these permissions.
Certain functions such as
isGeniune
will require several permissions as it will use verification against an external server.Alternatively you can also replace your manifest in the decompiled APK, manually change out the manifest with the one intended, and resign it. This is some more grunt work, but if proper error logging is in place it might speed up the process of tracking down the problematic functions.
Update
As I mentioned in the comments below as well. There is no real way to pinpoint functions. But a quick check list can not hurt, but will require some work
A lot of external services, think of google, twitter, facebook api's and tools require additional permissions. Usually these are storage/network related, but depending on the goals of the tool / api, it could be many more.
Try building your APK with and without the tools/apis to see if there are any differences.
Unity ads makes use of 3 permissions by itself, and older versions might still even make use of 5. If you are using their ads, then you will have to take these for granted.
Ever looked at those fancy stats Unity seems to be able to provide? Well, unless you disabled this, you are most likely participating in this as well.
These stats require several permissions, as the phone will be analysed on a hardware level as well as seen in the provided stats.
You might have included some api's, tools or just about any dll from an external party that may or may not include code that requires dependencies. Just as often those are not 100% sanitized, and might include permission requirements not relevant to their functionality, or to the functionality that you require.
Say, some ad service might want to access a users microphone. But as you are not using their "OMG vocal response analyses" functions, this permission is not required for you.
These permissions can either be removed manually, as I earlier described in my answer. Or through some form of automation such as the post build marked editor script.
QUESTION SPECIFIC:
RECORD_AUDIO
permission makes its way into android manifest file if there is a call to Microphone library in any of script in project. It doesn't matter if the script exists in scene or not. In this specific case, if Oculus Platform SDK is imported in project (which is a store requirement) there are few scripts which usesMicrophone
library. So if you don't use any audio recording feature e.g voice input, just remove the following files underOculusPlatform/Scripts
: MicrophoneInput.cs, IMicrophone.cs, MicrophoneInputNative.cs@mx-d is right. I just want to add another way of fixing this: in build settings you can tick the
Google Android Project
which will generate an Android Studio project. From there you can use Android Studio's manifest merger tool to override the permissions.Question #1: the only way to find which library is throwing in the extra permission is to remove libraries one by one, building the project and checking the .apk manifest. Unfortunately unity is not as flexible as Android Studio production-wise.
Question #2: You can not add permissions in Unity through code (unless it's a custom editor script specifically designed for stitching up manifest files)
Easy Way
I think this easier approach applies if your Unity project is being built with
gradle
. If it isn't, here is one more reason to upgrade.Also, a big shout-out to an article called, Hey, Where Did These Permissions Come From?)
Profit!Here is part of the file, where I'm looking for the WRITE_EXTERNAL_STORAGE permission.
Hard Way
There are three ways permissions get added to your project.
My examples use command-line tools on a Mac. I don't know Windows equivalents, but it is possible to find and run unix tools there (using the linux subsystem for windows 10, cygwin, custom binaries, etc.)
1. Find all permissions used in (uncompressed) Android Manifests.
This will find all files named AndroidManifest in the current folder (
.
) or any of its subfolders (-r
tells it to search recursively) and spit out any line with the words 'uses-permission'.In my current project, I get output something like this:
2. Find the permissions required in Android Libraries
Your project likely contains android libraries (.aar files) and java archives (.jar files). Some android libraries contain an android manifest and specify permissions needed to use the library. (I don't think .jar files actually do this, but .aar files absolutely do). Both .aar and .jar files are .zip files, with a different extension and with specific metadata in specific places.
Find them by running:
Here's what this does. It finds any file (in the current folder (
.
) and its subfolders) has an extension of (something) a r, thus .jar, or .aar (-name "*.?ar"
). It outputs the archive's file name (-print
). It then runszipgrep
(-exec
). Zipgrep is told to search through any files in the archive ({}
) named "AndroidManifest.xml", and output any line with the words "uses-permission". We then pipe the errors to the bit bucket (2> /dev/null
) so we don't see lots of errors about archives that don't have android manifests in them.An example output looks like this:
The filenames all start with periods. I can thus see, for example, that the onesignal-unity.aar sets several permissions, several .jar files were searched with no permissions inside them, and some of the play services libraries specify permissions.
If I needed to change a library, I could rename the .aar to .zip, extract it, edit it, compress it, and rename it back. (It isn't necessarily wise to change the permissions inside a library, but possible.)
3. Unity Adds the Permission
I didn't have anything to add on this; as said above, if you use the Microphone API, Unity will add a permission for you so your app will work.
However, I've since realized that you can do the following: