permission.android.MANAGE_USB works in Jellybean but not in Lollipop OS
Asked Answered
M

1

6

I'm developing an application that need this permission: android.permission.MANAGE_USB.


I know that this permission is given only at System Application.

If I install the application as a system application in android 4.1.2 the application works fine.

But if I try to install it in android 5.1 as a system app then the debug log prints out that I don't have the permission:

error:

W/System.err: java.lang.SecurityException: 
Neither user 10074 nor current process has android.permission.MANAGE_USB.

Is anybody know why it keeps giving me this error in android 5.1?

Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app">

<uses-permission android:name="android.permission.MANAGE_USB"
    android:protectionLevel="signature" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.GET_TASKS"/>
<permission android:name="android.permission.SET_TIME"
android:protectionLevel="signatureOrSystem"
    />
<uses-feature android:name="android.hardware.usb.host"
    android:required="true"/>


<application
    android:name=".services.AppContext"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:largeHeap="true"
    android:supportsRtl="true"
    android:hardwareAccelerated="false"
    android:theme="@style/AppTheme">
    <service android:name=".services.KioskService" android:exported="false"/>
    <activity
        android:name=".MainActivity"
        android:launchMode="singleInstance"
        android:stateNotNeeded="true"
        android:screenOrientation="sensorLandscape">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.HOME" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <service
        android:name="com.example.app.services.UsbService"
        android:enabled="true">
    </service>

    <receiver android:name=".services.PowerDisconnectReceiver">
        <intent-filter>
            <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
        </intent-filter>
    </receiver>

    <receiver android:name=".services.UsbPermissionReceiver">
        <intent-filter>
            <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/>
        </intent-filter>
    </receiver>

</application>

</manifest>
Merrick answered 25/10, 2017 at 13:28 Comment(6)
Can you post your AndroidManifest.xml ?Eachern
Are both devices rooted? Also, it's important to show the manifest, or we will only be able to speculate.Trigonous
ok, i've added the manifest. yes both devices are rooted. i have installed the application in system/app folder with 644 permissions.Merrick
@Merrick see my answer below.Prurient
i will try it right now!Merrick
honestly i think that the manifest is all right, cause the application works fine in jellybean 4.1.2.Merrick
P
5

I would try to change android:protectionLevel to signatureOrSystem:

A permission that the system grants only to applications that are in the Android system image or that are signed with the same certificate as the application that declared the permission. Please avoid using this option, as the signature protection level should be sufficient for most needs and works regardless of exactly where applications are installed. The "signatureOrSystem" permission is used for certain special situations where multiple vendors have applications built into a system image and need to share specific features explicitly because they are being built together.

For signature:

A permission that the system grants only if the requesting application is signed with the same certificate as the application that declared the permission. If the certificates match, the system automatically grants the permission without notifying the user or asking for the user's explicit approval.

I understand that you have no access to the signing key used by whoever compiled the Android OS image you're using in your devices, so signature protectionLevel will not match and not grant you the permission.

See https://developer.android.com/guide/topics/manifest/permission-element.html

Update: For completeness, I'm adding @carlo.S comments to the answer:

In Lollipop, an app to be considered as a system application needs to be installed under the system/priv-app folder and not system/app folder like in Android 4.2.2! Also, app needs to have 644 permissions.

Of course, the device needs to be rooted.

Prurient answered 25/10, 2017 at 14:0 Comment(7)
what do u mean with "you have to access to the same signing key as Android OS developers" ?Merrick
I mean the key used to sign the APK. This is a public/private key used by whoever compiled the Android image you're using. I've added a clarification to my answer.Prurient
without the protection level the app used to work in older versions of android, and i'm not understanding why in lollipop it stops working...Merrick
Every version apps have increased restrictions in order to increase the security. And I can imagine this is even more strict in system applications. Have you tried to change android:protectionLevel="signatureOrSystem"?Prurient
yes, i have tried to build a signed apk, but the problem is that i used mine signing key cause i don't have the "system signing key".Do you know if there is a way to retrive the signing key of the android OS image i'm using?Merrick
There is no way, unless you're a three letter governmental agency. So, that's a no, you should use your own signature key. That being said, notice that the protection level I'm suggesting is signatureOrSystem, and documentation says "A permission that the system grants only to applications that are in the Android system image...". As you're installing the application as a system one in a rooted device (you said "i have installed the application in system/app folder with 644 permissions", this should work regardless of the signature not matching.Prurient
the android:protectionLevel="signatureOrSystem" solution works like a charm!! at first it wasn't working, but then i found out that in lollipop, an app to be considered as a system application it need to be installed under the "system/priv-app" folder and not "system/app" folder like i used to do in android 4.2.2!!Merrick

© 2022 - 2024 — McMap. All rights reserved.