bypass android usb host permission confirmation dialog
Asked Answered
M

13

39

I want to use android in industry,

I can connect to Profilic and Ftdi USB to Serial chips with slickdevlabs.com library without any problem.

The application has a service and it starts on boot,connect to the usb serial port and do the other things.

my problem is that the host device does not have any interaction with user,

so when the android asks

Allow the app "MyAPP" to access the USB device ?
[checkmark]Use by default for this USB device
Cancel            OK

there is no person to click on ok.

even when I check the use by default... checkbox,If I reinsert the USB ,or reboot the host device, it asks again on next boot.

I ran the service and app with SuperUser mode,but no difference,it asks again.

I added intent filter but no difference,it asks me every time.

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

        <meta-data
            android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
            android:resource="@xml/device_filter" />
        <meta-data
            android:name="android.hardware.usb.action.USB_DEVICE_DETACHED"
            android:resource="@xml/device_filter" />

Any opinion how to bypass or disable it ?

I have root and SU access.

Marquise answered 5/12, 2012 at 15:25 Comment(2)
Is this possible solution? – https://mcmap.net/q/333441/-usb-device-access-pop-up-suppressionDoradorado
No this does not work.Stromberg
C
29

I know it's a bit late, but still...

I had the same kind of problem and I think I've managed to solve it. There's a service that Android uses internally that allows to manage USB devices and accessories. This service is hidden from thrid party developers and is not documented. If you check the source code for UsbPermissionActivity you'll be able to figure out how that service is called. In order to call the service IUsbManager interface and ServiceManager class are employed. These are both hidden too, so you can't use them directly. But what you can do is to create their stubs with exactly the same names and in corresponding namespaces (packages). Then you'll be able to compile that code, while the runtime environment will use the real things.

The only requirement is that your application has to be a system one - that is it has to be located in /system/app/ directory. Since your device is rooted that shouldn't be a problem.

So you will have to add a package to your project: "android.hardware.usb" and put a file in it named "IUsbManager.java" with the following content:

package android.hardware.usb;

public interface IUsbManager extends android.os.IInterface
{
    /** Local-side IPC implementation stub class. */
    public static abstract class Stub extends android.os.Binder implements android.hardware.usb.IUsbManager
    {
        /** Construct the stub at attach it to the interface. */
        public Stub()
        {
            throw new RuntimeException( "Stub!" );
        }
        /**
         * Cast an IBinder object into an android.hardware.usb.IUsbManager interface,
         * generating a proxy if needed.
         */
        public static android.hardware.usb.IUsbManager asInterface( android.os.IBinder obj )
        {
            throw new RuntimeException( "Stub!" );
        }

        public android.os.IBinder asBinder()
        {
            throw new RuntimeException( "Stub!" );
        }

        public boolean onTransact( int code, android.os.Parcel data, android.os.Parcel reply, int flags ) throws android.os.RemoteException
        {
            throw new RuntimeException( "Stub!" );
        }

        static final int TRANSACTION_getDeviceList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
        static final int TRANSACTION_openDevice = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
        static final int TRANSACTION_getCurrentAccessory = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
        static final int TRANSACTION_openAccessory = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
        static final int TRANSACTION_setDevicePackage = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
        static final int TRANSACTION_setAccessoryPackage = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5);
        static final int TRANSACTION_hasDevicePermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 6);
        static final int TRANSACTION_hasAccessoryPermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 7);
        static final int TRANSACTION_requestDevicePermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 8);
        static final int TRANSACTION_requestAccessoryPermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 9);
        static final int TRANSACTION_grantDevicePermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 10);
        static final int TRANSACTION_grantAccessoryPermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 11);
        static final int TRANSACTION_hasDefaults = (android.os.IBinder.FIRST_CALL_TRANSACTION + 12);
        static final int TRANSACTION_clearDefaults = (android.os.IBinder.FIRST_CALL_TRANSACTION + 13);
        static final int TRANSACTION_setCurrentFunction = (android.os.IBinder.FIRST_CALL_TRANSACTION + 14);
        static final int TRANSACTION_setMassStorageBackingFile = (android.os.IBinder.FIRST_CALL_TRANSACTION + 15);
    }

    /* Returns a list of all currently attached USB devices */
    public void getDeviceList( android.os.Bundle devices ) throws android.os.RemoteException;
    /* Returns a file descriptor for communicating with the USB device.
         * The native fd can be passed to usb_device_new() in libusbhost.
         */
    public android.os.ParcelFileDescriptor openDevice( java.lang.String deviceName ) throws android.os.RemoteException;
    /* Returns the currently attached USB accessory */
    public android.hardware.usb.UsbAccessory getCurrentAccessory() throws android.os.RemoteException;
    /* Returns a file descriptor for communicating with the USB accessory.
         * This file descriptor can be used with standard Java file operations.
         */
    public android.os.ParcelFileDescriptor openAccessory( android.hardware.usb.UsbAccessory accessory ) throws android.os.RemoteException;
    /* Sets the default package for a USB device
         * (or clears it if the package name is null)
         */
    public void setDevicePackage( android.hardware.usb.UsbDevice device, java.lang.String packageName ) throws android.os.RemoteException;
    /* Sets the default package for a USB accessory
         * (or clears it if the package name is null)
         */
    public void setAccessoryPackage( android.hardware.usb.UsbAccessory accessory, java.lang.String packageName ) throws android.os.RemoteException;
    /* Returns true if the caller has permission to access the device. */
    public boolean hasDevicePermission(android.hardware.usb.UsbDevice device) throws android.os.RemoteException;
    /* Returns true if the caller has permission to access the accessory. */
    public boolean hasAccessoryPermission( android.hardware.usb.UsbAccessory accessory ) throws android.os.RemoteException;
    /* Requests permission for the given package to access the device.
         * Will display a system dialog to query the user if permission
         * had not already been given.
         */
    public void requestDevicePermission( android.hardware.usb.UsbDevice device, java.lang.String packageName, android.app.PendingIntent pi ) throws android.os.RemoteException;
    /* Requests permission for the given package to access the accessory.
         * Will display a system dialog to query the user if permission
         * had not already been given. Result is returned via pi.
         */
    public void requestAccessoryPermission( android.hardware.usb.UsbAccessory accessory, java.lang.String packageName, android.app.PendingIntent pi ) throws android.os.RemoteException;
    /* Grants permission for the given UID to access the device */
    public void grantDevicePermission( android.hardware.usb.UsbDevice device, int uid ) throws android.os.RemoteException;
    /* Grants permission for the given UID to access the accessory */
    public void grantAccessoryPermission( android.hardware.usb.UsbAccessory accessory, int uid ) throws android.os.RemoteException;
    /* Returns true if the USB manager has default preferences or permissions for the package */
    public boolean hasDefaults( java.lang.String packageName ) throws android.os.RemoteException;
    /* Clears default preferences and permissions for the package */
    public void clearDefaults( java.lang.String packageName ) throws android.os.RemoteException;
    /* Sets the current USB function. */
    public void setCurrentFunction( java.lang.String function, boolean makeDefault ) throws android.os.RemoteException;
    /* Sets the file path for USB mass storage backing file. */
    public void setMassStorageBackingFile( java.lang.String path ) throws android.os.RemoteException;
}

Then another package: "android.os" with "ServiceManager.java":

package android.os;

import java.util.Map;

public final class ServiceManager
{
    public static IBinder getService( String name )
    {
        throw new RuntimeException( "Stub!" );
    }

    /**
     * Place a new @a service called @a name into the service
     * manager.
     * 
     * @param name the name of the new service
     * @param service the service object
     */
    public static void addService( String name, IBinder service )
    {
        throw new RuntimeException( "Stub!" );
    }

    /**
     * Retrieve an existing service called @a name from the
     * service manager.  Non-blocking.
     */
    public static IBinder checkService( String name )
    {
        throw new RuntimeException( "Stub!" );
    }

    public static String[] listServices() throws RemoteException
    {
        throw new RuntimeException( "Stub!" );
    }

    /**
     * This is only intended to be called when the process is first being brought
     * up and bound by the activity manager. There is only one thread in the process
     * at that time, so no locking is done.
     * 
     * @param cache the cache of service references
     * @hide
     */
    public static void initServiceCache( Map<String, IBinder> cache )
    {
        throw new RuntimeException( "Stub!" );
    }
}

Note that interfaces of these classes may change depending on the version of Android. In my case the version is 4.0.3. So if you have another version of Android and this code doesn't work you will have to check the source code for your particular version of OS.

Here's an example of using the service to grant permissions to all FTDI devices:

import java.util.HashMap;
import java.util.Iterator;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.hardware.usb.IUsbManager;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.IBinder;
import android.os.ServiceManager;

public class LaunchReceiver extends BroadcastReceiver
{
    public void onReceive( Context context, Intent intent )
    {
        String action = intent.getAction();
        if( action != null && action.equals( Intent.ACTION_BOOT_COMPLETED ) )
        {
            try
            {
                PackageManager pm = context.getPackageManager();
                ApplicationInfo ai = pm.getApplicationInfo( YOUR_APP_PACKAGE_NAMESPACE, 0 );
                if( ai != null )
                {
                    UsbManager manager = (UsbManager) context.getSystemService( Context.USB_SERVICE );
                    IBinder b = ServiceManager.getService( Context.USB_SERVICE );
                    IUsbManager service = IUsbManager.Stub.asInterface( b );

                    HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
                    Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
                    while( deviceIterator.hasNext() )
                    {
                            UsbDevice device = deviceIterator.next();
                            if( device.getVendorId() == 0x0403 )
                            {
                                service.grantDevicePermission( device, ai.uid );
                                service.setDevicePackage( device, YOUR_APP_PACKAGE_NAMESPACE );
                            }
                    }
                }
            }
            catch( Exception e )
            {
                trace( e.toString() );
            }
        }
    }
}

One more thing - you will have to add the following permission to your manifest (Lint might not like it but you can always change severity level in your project's properties):

<uses-permission android:name="android.permission.MANAGE_USB" />
Cini answered 13/3, 2013 at 6:0 Comment(10)
On 4.2.2 it doesn't work because setDevicePackage() has changed. Check my answer for the code.Paramedical
How can I use it for usb accessory?Chasten
It work on boot. But if I replug the FTDI devices, the dialog still be shown(although I click "cancel", it still work). I am using FDTI's d2xx library. Is the library somewhere called mUsbManager.requestPermission(device, mPermissionIntent);? Then I have nothing to do with it.Freehanded
Oh, with this intent-filter method. It works if I declare an the invisible activity on the Manifest(Don't know why Receiver and Service not work).Re-Plug the device, the dialog won't be shown.Freehanded
I'm trying to find the code suitable for 5.1 for 5 days but i failed please can you help me and post the codes for android 5.1 ?Bahr
#37048954Bahr
I am getting following issue ..... "Neither user XXXXX nor current process has android.permission.MANAGE_USB.". I have already given manage usb permission in android manifest file as follows........ <uses-permission android:name="android.Manifest.permission.MANAGE_USB" /> This exception comes at service.grantDevicePermission( device, ai.uid ); this lineCribb
for newer Android we have to use /system/priv-app/ instead of /system/app/ directory to get system permissionsExtraversion
it works, but after device restart's, dialog steel showsAlliterate
On some Android 9 devices it fails with: java.lang.NoSuchMethodError: No interface method grantDevicePermission(Landroid/hardware/usb/UsbDevice;I)V in class Landroid/hardware/usb/IUsbManager; or its super classes (declaration of 'android.hardware.usb.IUsbManager' appears in /system/framework/framework.jar)Klina
P
13

@d_d_t aswer is great, but it dosen't work on Android > 4.2.2. Use this interface:

public interface IUsbManager extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements android.hardware.usb.IUsbManager {
    private static final java.lang.String DESCRIPTOR = "android.hardware.usb.IUsbManager";

    /** Construct the stub at attach it to the interface. */
    public Stub()         {
        throw new RuntimeException( "Stub!" );
    }

    /**
     * Cast an IBinder object into an android.hardware.usb.IUsbManager
     * interface, generating a proxy if needed.
     */
    public static android.hardware.usb.IUsbManager asInterface( android.os.IBinder obj) {
        throw new RuntimeException( "Stub!" );
    }

    @Override
    public android.os.IBinder asBinder() {
        throw new RuntimeException( "Stub!" );
    }

    @Override
    public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
        throw new RuntimeException( "Stub!" );
    }

    static final int TRANSACTION_getDeviceList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
    static final int TRANSACTION_openDevice = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
    static final int TRANSACTION_getCurrentAccessory = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
    static final int TRANSACTION_openAccessory = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
    static final int TRANSACTION_setDevicePackage = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
    static final int TRANSACTION_setAccessoryPackage = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5);
    static final int TRANSACTION_hasDevicePermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 6);
    static final int TRANSACTION_hasAccessoryPermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 7);
    static final int TRANSACTION_requestDevicePermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 8);
    static final int TRANSACTION_requestAccessoryPermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 9);
    static final int TRANSACTION_grantDevicePermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 10);
    static final int TRANSACTION_grantAccessoryPermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 11);
    static final int TRANSACTION_hasDefaults = (android.os.IBinder.FIRST_CALL_TRANSACTION + 12);
    static final int TRANSACTION_clearDefaults = (android.os.IBinder.FIRST_CALL_TRANSACTION + 13);
    static final int TRANSACTION_setCurrentFunction = (android.os.IBinder.FIRST_CALL_TRANSACTION + 14);
    static final int TRANSACTION_setMassStorageBackingFile = (android.os.IBinder.FIRST_CALL_TRANSACTION + 15);
    static final int TRANSACTION_allowUsbDebugging = (android.os.IBinder.FIRST_CALL_TRANSACTION + 16);
    static final int TRANSACTION_denyUsbDebugging = (android.os.IBinder.FIRST_CALL_TRANSACTION + 17);
}

/* Returns a list of all currently attached USB devices */
public void getDeviceList(android.os.Bundle devices)
        throws android.os.RemoteException;

/*
 * Returns a file descriptor for communicating with the USB device. The
 * native fd can be passed to usb_device_new() in libusbhost.
 */
public android.os.ParcelFileDescriptor openDevice(
        java.lang.String deviceName) throws android.os.RemoteException;

/* Returns the currently attached USB accessory */
public android.hardware.usb.UsbAccessory getCurrentAccessory()
        throws android.os.RemoteException;

/*
 * Returns a file descriptor for communicating with the USB accessory. This
 * file descriptor can be used with standard Java file operations.
 */
public android.os.ParcelFileDescriptor openAccessory(
        android.hardware.usb.UsbAccessory accessory)
        throws android.os.RemoteException;

/*
 * Sets the default package for a USB device (or clears it if the package
 * name is null)
 */
public void setDevicePackage(android.hardware.usb.UsbDevice device,
        java.lang.String packageName, int userId)
        throws android.os.RemoteException;

/*
 * Sets the default package for a USB accessory (or clears it if the package
 * name is null)
 */
public void setAccessoryPackage(
        android.hardware.usb.UsbAccessory accessory,
        java.lang.String packageName, int userId)
        throws android.os.RemoteException;

/* Returns true if the caller has permission to access the device. */
public boolean hasDevicePermission(android.hardware.usb.UsbDevice device)
        throws android.os.RemoteException;

/* Returns true if the caller has permission to access the accessory. */
public boolean hasAccessoryPermission(
        android.hardware.usb.UsbAccessory accessory)
        throws android.os.RemoteException;

/*
 * Requests permission for the given package to access the device. Will
 * display a system dialog to query the user if permission had not already
 * been given.
 */
public void requestDevicePermission(android.hardware.usb.UsbDevice device,
        java.lang.String packageName, android.app.PendingIntent pi)
        throws android.os.RemoteException;

/*
 * Requests permission for the given package to access the accessory. Will
 * display a system dialog to query the user if permission had not already
 * been given. Result is returned via pi.
 */
public void requestAccessoryPermission(
        android.hardware.usb.UsbAccessory accessory,
        java.lang.String packageName, android.app.PendingIntent pi)
        throws android.os.RemoteException;

/* Grants permission for the given UID to access the device */
public void grantDevicePermission(android.hardware.usb.UsbDevice device,
        int uid) throws android.os.RemoteException;

/* Grants permission for the given UID to access the accessory */
public void grantAccessoryPermission(
        android.hardware.usb.UsbAccessory accessory, int uid)
        throws android.os.RemoteException;

/*
 * Returns true if the USB manager has default preferences or permissions
 * for the package
 */
public boolean hasDefaults(java.lang.String packageName, int userId)
        throws android.os.RemoteException;

/* Clears default preferences and permissions for the package */
public void clearDefaults(java.lang.String packageName, int userId)
        throws android.os.RemoteException;

/* Sets the current USB function. */
public void setCurrentFunction(java.lang.String function,
        boolean makeDefault) throws android.os.RemoteException;

/* Sets the file path for USB mass storage backing file. */
public void setMassStorageBackingFile(java.lang.String path)
        throws android.os.RemoteException;

/*
 * Allow USB debugging from the attached host. If alwaysAllow is true, add
 * the the public key to list of host keys that the user has approved.
 */
public void allowUsbDebugging(boolean alwaysAllow,
        java.lang.String publicKey) throws android.os.RemoteException;

/* Deny USB debugging from the attached host */
public void denyUsbDebugging() throws android.os.RemoteException;
}

And modify the code adding user id:

...
service.setDevicePackage( usbDevice, YOUR_APP_PACKAGE_NAMESPACE, ai.uid ); 
....
Paramedical answered 30/10, 2013 at 12:9 Comment(4)
Thanks for the info.I see you have shared IUsbManager.java interface code.What about the code for ServiceManager.java.Is it also different for 4.2.2? Also, will the usb permission popup not come even when the device is rebooted/app is upgraded?Accroach
On some Android 9 devices (e.g. Xiaomi MI A2 Lite) it fails with: java.lang.NoSuchMethodError: No interface method grantDevicePermission(Landroid/hardware/usb/UsbDevice;I)V in class Landroid/hardware/usb/IUsbManager; or its super classes (declaration of 'android.hardware.usb.IUsbManager' appears in /system/framework/framework.jar)Klina
It seems it doesn't work on Android 9 at all, not just some devicesExtraversion
found solution for Android 9 https://mcmap.net/q/340966/-bypass-android-usb-host-permission-confirmation-dialog-on-android-9Extraversion
L
9

i had the same problem with the popup window and nobody to click on it. But i found a different solution (for rooted devices). The popup gets generated by android in the class UsbPermissionActivity (and that UsbPermissionActivity is started by the UsbSettingsManager). Look at the Android Sourcecode to see whats going on. The good thing here is, we can manipulate the bytecode of the UsbPermissionActivity to accept all UsbDevices. You need the tool Smali/Baksmali to do so. https://code.google.com/p/smali/

  1. Locate the file SystemUI.apk on your device
  2. Copy it to your computer with adb pull path/to/SystemUI.apk
  3. Unzip the apk
  4. Disassemble the classes.dex file with java -jar baksmali.jar classes.dex
  5. Find the file UsbPermissionActivity and inside of it find the line that says

    invoke-virtual {p0}, Lcom/android/systemui/usb/UsbPermissionActivity;->setupAlert()V

  6. Change this by commenting it out and adding two new lines

#invoke-virtual {p0}, Lcom/android/systemui/usb/UsbPermissionActivity;->setupAlert()V const/4 v0, 0x1 iput-boolean v0, p0, Lcom/android/systemui/usb/UsbPermissionActivity;->mPermissionGranted:Z invoke-virtual {p0}, Lcom/android/systemui/usb/UsbPermissionActivity;->finish()V

  1. Assemble it with java -jar smali.jar -o classes.dex out
  2. Replace the original classes.dex and zip everything again to SystemUI.apk
  3. Replace the original SystemUI.apk on your device with adb push services.jar path/to/SystemUI.apk or if that doesnt work with a filemanager ap
Lurie answered 31/5, 2015 at 22:10 Comment(4)
I just now tried this out, and it also seemed to corrupt some other things on the device. SystemUI was under /system/priv-app. This is with Android 4.4.2 .Tarrel
It works for an FTDI permission, One other missing step is to do a chmod on the SystemUI,apk when reinstalling it.Tarrel
Thats worked great! The Smali/Baksmali moved to github.com/JesusFreke/smali and in Smali/Baksmali 2.2 the commands has changed to java -jar baksmali.jar d classes.dex and java -jar smali.jar a -o classes.dex outMeiosis
found solution for Android 9 https://mcmap.net/q/340966/-bypass-android-usb-host-permission-confirmation-dialog-on-android-9Extraversion
S
8

The solution is to use intent filters and add the android:directBootAware="true" attribute to the associated activity so that the USB_DEVICE_ATTACHED event is correctly received after boot / reboot. It is important not to ask for the USB device permission in code, only using intent filters, like this:

<manifest>
    <uses-feature android:name="android.hardware.usb.host" />
    <activity
        ...
        android:directBootAware="true">

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

        <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
        android:resource="@xml/device_filter" />

    </activity>
</manifest>

With a device_filter XML resource file similar to this:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <usb-device vendor-id="1234" product-id="5678" />
</resources>
Sackman answered 19/3, 2020 at 22:31 Comment(2)
Thanks! This is by far the simplest and fastest solution as of 2020. One issue I still see is that the device is not available after unplugging/replugging, although that is not so significant for my project.Genitive
its not worked, I'm using sdk 21.Perfectly
M
4

Android is really not designed to support this kind of usage out of the box. Personally, for non-interactive usage, I'd be tempted to consider using the USB serial driver in the linux kernel and skipping the android USB apis. But you'd have to be in a position to seriously modify the android installation - change the kernel configuration and/or load a module, create device files and set their permissions or owners, possibly add a unix group and android permission for apps allowed to access it.

Or you can look through the android source and disable the user confirmation; but if you do not have a from-source android build for the device, this may be trickier than the linux-level idea, since adapting open source android to run on a vendor device can be non-trivial (unless someone already offers a from-source build that is sufficiently functional for the device in question)

Indicentally, root/su access does not apply to applications themselves - it only means that an application which knowns how to run whatever tool your root hack left behind, can start up a helper program that runs as root, but the application itself does not and cannot. Using root to install the app on the system partition might get you some atypical android permissions, but you'd have to check if there are any which would help you with the usb.

Mansur answered 5/12, 2012 at 15:56 Comment(1)
just a theory answerExtraversion
B
4

If you have the option to compile the android system, then there's nothing you cannot do.

You can add

public void onStart() {
    super.onStart();
    mPermissionGranted = true;

    finish();
}

to frameworks/base/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java

to bypass the the permission confirmation popup.

Broomrape answered 17/11, 2014 at 8:9 Comment(7)
Thanks for this, pointed me on the right direction. Reading the source then found out that there is a config for this named config_disableUsbPermissionDialogs in frameworks/base/core/res/res/values/config.xmlNicolella
@RickSanchez - how do you update the config.xml file to use the new value?Sherburn
Modified it in the AOSP tree, and compiled again / flashed the image.Nicolella
@RickSanchez well you can't install that AOSP compiled image to any phone (like the latest samsung)Extraversion
@RickSanchez flashed the whole system image OMG. Why cannot it be automatic. After all GOOGLE ANDROID I PAY FOR HAVING YOUR SECURITY CONCERNED DEVICE!Sackman
@Lewis Z that mean do not need permission to access usb or just made dialog permission do not popupIchor
@Ichor That can bypass the permission check completely.Broomrape
O
3

I think white-listing the accessory you are using in advance will be the best solution. To do this you need to add the file usb_device_manager.xml at this location /data/system/users/0
// Note that 0 is user ID, it will probably be 0 if you didn't add more users in Android but if you did change this ID accordingly

This is how file should look:

<settings>
<preference package="<PACKAGE NAME OF APP YOU WANT TO START ON CONNECTIONCTION>">
    <usb-accessory manufacturer="<NAME OF MANUFECTURER LIKE ONE REGISTERED IN meta-data in the manifest>" model="<MODEL NAME LIKE ONE REGISTERED IN meta-data in the manifest>" version="<VERSION LIKE ONE REGISTERED IN meta-data in the manifest>" />
</preference>

For a board like this http://www.embeddedartists.com/products/app/aoa_kit.php it is:

 <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<settings>
<preference package="com.embeddedartists.aoa">
    <usb-accessory manufacturer="Embedded Artists AB" model="AOA Board - Basic" version="1.0" />
</preference>

Ophidian answered 30/7, 2015 at 10:11 Comment(6)
It is actually cleared on restart too. You would need to setup something that copies the xml file over to the correct directory on boot.Sherburn
model? What is that? UsbDevice class can give us productName, deviceName, manufacturerName and others. Does "productName" equal "model"?Extraversion
NAME LIKE ONE REGISTERED IN meta-data in the manifest and what is that? What are you talking about? Registered where? Which manifest?Extraversion
and why do you open <settings> tag but don't close it?Extraversion
@Extraversion It was just missing in the answer, it should be closed. It is not to be copy pasted anyway because of placeholders. Unfortunately I can not fix this since code editor on stackoverflow does not render it but when I try to edit it is there..Mikkanen
well system automatically add devices to that file and connects them to your app but it doesn't mean that your app has permission for devices included in that fileExtraversion
B
2

According to the documentation on Android Developers you already have permission to the attached USB device when your app gets started trough your manifest intent filter. Perhaps you should try this approach and write a filter to exact match the device you want to use, to prevent that other apps also want to communicate with the device.

See the "Note" on http://developer.android.com/guide/topics/connectivity/usb/host.html#permission-d

Bertabertasi answered 5/3, 2013 at 8:43 Comment(6)
it doesn't work, I've add all this intent-filter to my activity, but it still doesn't have permissionExtraversion
it's only for filtering devices (by vendor, product id). it has nothing to do with device permissions!Extraversion
@Extraversion "Note: If your application uses an intent filter to discover USB devices as they're connected, it automatically receives permission if the user allows your application to handle the intent. If not, you must request permission explicitly in your application before connecting to the device."Bertabertasi
In all cases a dialog with request permission pops up, just try it yourself (I had all intent-filters, device/vendor ids, my receivers detect that device is connected or disconnect but still requires permission). Anyway I found a way to avoid it using Root and system appExtraversion
Basically when you delete your app and install it again it will 100% require a permissionExtraversion
And that solution doesn't work after rebooting. So yes you can plug/unplug device and it will automatically grant permission but once you reboot the device you need to request or unplug/plug device manually again. Useless!Extraversion
L
0

One way to achieve this, note that this does not actually get rid of the confirmation, would be to pinpoint the location of the checkbox and use the Android equivalent of the Robot class to select it and then select OK. You could write a application that runs in the background, it could even be called by that startup service that you mentioned, specifically for this purpose.

Lagomorph answered 20/1, 2013 at 22:45 Comment(2)
I did the same thing,but the background service can not access the dialog-box all the time,and it had error.Marquise
this is stupid and I want to control a device without activity but from serviceExtraversion
D
0

If you have access to the Android source code, here is the code you need to disable the permission dialog

https://gitlab.tubit.tu-berlin.de/justus.beyer/streamagame_platform_frameworks_base/commit/e97b62ed0d4050acacbf54781435686ea28edd73

The code update above creates a config option you can use, or instead you can hardcode it using the value true in-place of mDisablePermissionDialogs to disable the permission dialog.

In services/usb/java/com/android/server/usb/UsbSettingsManager.java

Displacement answered 11/4, 2019 at 4:53 Comment(2)
No one have access to Xiaomi or Samsung firmware source codeExtraversion
I suppose not however, they aren't the only ones that use the Open Source Android OSDisplacement
O
-1

At the first time, when it needs confirm, you can select "always", then even if the Android device is powered down, and powered up, your app still has permission to access the USB2Serial. Just to say, only one time confirm!

Oldenburg answered 25/1, 2017 at 10:52 Comment(1)
this is a low quality answerKela
M
-1

I had the same problem, the permission popup appear everytime i plug the USB cable, to solve it i just added the filter in the manifest and the xml file for VID and PID, just make sure you've setup USB device filtering as suggested in the SO link above or as documented here, and you put the good VID and PID. It was my problem, i didn't put the VID and PID that match to my device

Millesimal answered 30/1, 2018 at 18:48 Comment(1)
after rebooting you still need to request it again, intent filters help only for the current boot sessionExtraversion
G
-2

I think we can do this by making some modifications in /etc/udev. We could add the vendor id and device id into the 51-android.rules file.

Griffith answered 15/1, 2013 at 8:19 Comment(3)
This has nothing to do with it. The point isn't to be able to connect to the device, which he/she is already able to do, its to prevent the dialog confirmation from appearing.Lagomorph
Android doesn't have such file /etc/udev. It's not Ubuntu!Extraversion
and this file is used for detecting devices on Ubuntu. You posted a totally random thing hereExtraversion

© 2022 - 2024 — McMap. All rights reserved.