Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use reflection to change backup service?

I posted a question about a new behavior of Android 5.1 that disables the Backup Service when setting up a device-owner on a device here...

A possible solution could be (I guess) to use reflection to fix the issue: I could find some reflection examples using a particular method in a hidden class, but this case looks more complicated, with a constructor that uses another hidden class (ServiceManager) etc. and I dunno how to do this...

The code that is annoying me is located in DevicePolicyManagerService.java (can be found here) on lines 3739 to 3749:

long ident = Binder.clearCallingIdentity();
try {
    IBackupManager ibm = IBackupManager.Stub.asInterface(
        ServiceManager.getService(Context.BACKUP_SERVICE));
    ibm.setBackupServiceActive(UserHandle.USER_OWNER, false);
} catch (RemoteException e) {
    throw new IllegalStateException("Failed deactivating backup service.", e);
} finally {
    Binder.restoreCallingIdentity(ident);
}

And my goal would be to re-enable the Backup Service, ideally this would call something like:

ibm.setBackupServiceActive(UserHandle.USER_OWNER, false);

Could you help me to do this ?

like image 991
JBA Avatar asked May 20 '15 09:05

JBA


1 Answers

try this code:

    try {
        Class<?> iBackupManagerClass = Class.forName("android.app.backup.IBackupManager");
        Class<?> serviceManagerClass = Class.forName("android.os.ServiceManager");
        Class<?>[] classes = iBackupManagerClass.getDeclaredClasses();
        Class<?> stubClass = null;
        for (Class clazz : classes) {
            if (clazz.getSimpleName().equals("Stub")) {
                stubClass = clazz;
            }
        }

        Method setBackupServiceActiveMethod = iBackupManagerClass.getMethod("setBackupServiceActive", int.class, boolean.class);
        Method asInterfaceMethod = stubClass.getMethod("asInterface", IBinder.class);
        Method getServiceMethod = serviceManagerClass.getMethod("getService", String.class);

        Object ibm = asInterfaceMethod.invoke(null, getServiceMethod.invoke(null, "backup"));
        setBackupServiceActiveMethod.invoke(ibm, 0, false);

    } catch (ClassNotFoundException e) {
        Log.e("TEST", e.getMessage(), e);
    } catch (NoSuchMethodException e) {
        Log.e("TEST", e.getMessage(), e);
    } catch (InvocationTargetException e) {
        Log.e("TEST", e.getMessage(), e);
    } catch (IllegalAccessException e) {
        Log.e("TEST", e.getMessage(), e);
    }

It will need some refactoring for error catching...

like image 136
Médéric Avatar answered Sep 27 '22 18:09

Médéric