Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backup work profile (Shelter) #77

Closed
ypid opened this issue Mar 9, 2020 · 25 comments
Closed

Backup work profile (Shelter) #77

ypid opened this issue Mar 9, 2020 · 25 comments
Labels

Comments

@ypid
Copy link
Contributor

ypid commented Mar 9, 2020

Hi,

I have setup a Android work profile so when I open System -> Backup, the settings app asks in which profile the Seedvault should be opened. Personal profile works as intended. But when I select "Work", it says "Disabled by admin". I am the admin and I did not disable it :) I did a quick grep over frameworks/base, Internet search and logcat. No obvious setting. Do you see a trick to patch Android so that backing up the work profile works?

Keep up the good work!

@stevesoltys
Copy link
Member

Hey!

I'm thinking this is what you may be looking for: https://github.com/aosp-mirror/platform_packages_apps_settings/blob/master/src/com/android/settings/backup/BackupSettingsHelper.java#L216

Untested, but looks right to me. Let me know if changing that works for you. If it's not there, I would guess it's somewhere around there.

@ypid
Copy link
Contributor Author

ypid commented Mar 13, 2020

Looks promising. I will patch this function to always return true and enable logging in my next build for the 2020-04-05 security patch. For reference, logcat shows getIntentForBackupSettings() of that file is being called when I try to open Seedvault for the work profile:

$ adb logcat -v year,uid,color -s BackupSettingsHelper
--------- beginning of system
--------- beginning of crash
--------- beginning of main
2020-03-13 22:15:18.781 1101000  7049  7049 E BackupSettingsHelper: Backup transport has not provided an intent or the component for the intent is not found!

I will report back.

@stevesoltys
Copy link
Member

Will close this for now, if you find a good solution I can add it to the documentation so those interested can consider applying the patch.

Thanks for bringing this to our attention.

@ypid
Copy link
Contributor Author

ypid commented Apr 12, 2020

The patch:

project packages/apps/Settings/
diff --git a/packages/apps/Settings/src/com/android/settings/backup/BackupSettingsHelper.java b/packages/apps/Settings/src/com/android/     settings/backup/BackupSettingsHelper.java
index 1d3455b149..52b0d143a0 100644
--- a/packages/apps/Settings/src/com/android/settings/backup/BackupSettingsHelper.java
+++ b/packages/apps/Settings/src/com/android/settings/backup/BackupSettingsHelper.java
@@ -211,15 +211,8 @@ public class BackupSettingsHelper {

     /** Checks if backup service is enabled for this user. */
     public boolean isBackupServiceActive() {
-        boolean backupOkay;
-        try {
-            backupOkay = mBackupManager.isBackupServiceActive(UserHandle.myUserId());
-        } catch (Exception e) {
-            // things go wrong talking to the backup system => ignore and
-            // pass the default 'false' as the "backup is a thing?" state.
-            backupOkay = false;
-        }
-        return backupOkay;
+        Log.d(TAG, "return true without condition checking in isBackupServiceActive");
+        return true;
     }   

     @VisibleForTesting

Does not fully work unfortunately. I don’t get "Disabled by admin" anymore, but a blank screen with only the title "Backup". As if Seedvault was not installed. But I checked, it is installed for the work profile. Note that the blank screen is the same behavior of AOSP without Google stuff when no Seedvault is integrated into the built. So it seems Android does not quite get that Seedvault should also be responsible for the work profile.

From the debug log, we see that isBackupServiceActive() was called three times.

2020-04-12 15:55:45.239  1000 11285 11285 W InputEventReceiver: Attempted to finish an input event but the input event receiver has already 
been disposed.                                                                                                                              
2020-04-12 15:55:45.243 1101000 11656 11656 W ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@b0cce9   
2020-04-12 15:55:45.251 1101000 11656 11656 E BackupSettingsHelper: Backup transport has not provided an intent or the component for the in$ent is not found!
2020-04-12 15:55:45.252  1000  1366 11521 I ActivityTaskManager: START u11 {cmp=com.android.settings/.Settings$PrivacySettingsActivity} fro$ uid 1101000                                                                                                                                
2020-04-12 15:55:45.254  root   832   832 D android.hardware.power@1.3-service.pixel-libperfmgr: LAUNCH: 1
2020-04-12 15:55:45.268 1101000 11656 11656 W ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@65c56d2  
2020-04-12 15:55:45.275 1101000 11656 11656 D SettingsActivity: Starting onCreate
2020-04-12 15:55:45.281 1101000 11656 11656 D SettingsActivity: Starting to set activity title            
2020-04-12 15:55:45.281 1101000 11656 11656 D SettingsActivity: Done setting title                                                          
2020-04-12 15:55:45.281 1101000 11656 11656 D SettingsActivity: Switching to fragment com.android.settings.backup.PrivacySettings
2020-04-12 15:55:45.282 1101000 11656 11656 D PrefCtrlListHelper: Could not find Context-only controller for pref: com.android.settings.bac$up.BackupDataPreferenceController
2020-04-12 15:55:45.283 1101000 11656 11656 D PrefCtrlListHelper: Could not find Context-only controller for pref: com.android.settings.bac$up.ConfigureAccountPreferenceController                                                                                                     
2020-04-12 15:55:45.283 1101000 11656 11656 D PrefCtrlListHelper: Could not find Context-only controller for pref: com.android.settings.bac$up.DataManagementPreferenceController                                                                                                       
2020-04-12 15:55:45.283 1101000 11656 11656 D PrefCtrlListHelper: Could not find Context-only controller for pref: com.android.settings.bac$up.AutoRestorePreferenceController                                                                     
2020-04-12 15:55:45.283 1101000 11656 11656 D PrefCtrlListHelper: Could not find Context-only controller for pref: com.android.settings.bac$up.BackupInactivePreferenceController
2020-04-12 15:55:45.285 1101000 11656 11656 D BackupSettingsHelper: return true without condition checking in isBackupServiceActive
2020-04-12 15:55:45.287 1101000 11656 11656 D BackupSettingsHelper: return true without condition checking in isBackupServiceActive         
2020-04-12 15:55:45.289 1101000 11656 11656 D PrivacySettings: NO dashboard tiles for PrivacySettings
2020-04-12 15:55:45.289 1101000 11656 11656 D PrivacySettings: All preferences added, reporting fully drawn                              
2020-04-12 15:55:45.290  1000  1366  1463 I ActivityTaskManager: Fully drawn com.android.settings/.Settings$PrivacySettingsActivity: +62ms  
2020-04-12 15:55:45.290 1101000 11656 11656 D SettingsActivity: Executed frag manager pendingTransactions
2020-04-12 15:55:45.301 1101000 11656 11656 D BackupSettingsHelper: return true without condition checking in isBackupServiceActive         
2020-04-12 15:55:45.302 1101000 11656 11683 W TileUtils: Found com.android.settings.Settings$DataUsageSummaryActivity for intent Intent { a$t=com.android.settings.action.SETTINGS pkg=com.android.settings } missing metadata com.android.settings.category
2020-04-12 15:55:45.309 1101000 11656 11972 D SettingsActivity: No enabled state changed, skipping updateCategory call                    
2020-04-12 15:55:45.331  1000  1366  1463 E system_server: Dex checksum does not match for dex: /product/priv-app/Settings/Settings.apk.Exp$cted: 2833457125, actual: 1132749477

@stevesoltys
Copy link
Member

I'll re-open this in case anyone else is having this issue and wants to contribute.

It sounds to me like the backup transport is not set for that user. However, I'm not sure if the backup transport setting is per user. There could be other code affecting the backup transport settings for non-admin profiles somewhere else as well.

@stevesoltys stevesoltys reopened this Apr 13, 2020
@grote
Copy link
Collaborator

grote commented Sep 21, 2020

I don’t get "Disabled by admin" anymore, but a blank screen with only the title "Backup". As if Seedvault was not installed.

You might need to set the backup transport for the current user. This sounds like it is set to LocalTransport.

@grote
Copy link
Collaborator

grote commented Sep 21, 2020

Check the adb shell bmgr --user option.

@chirayudesai is there maybe a way to set the transport automatically for all users, so they don't end up in that empty activity?

@chirayudesai
Copy link
Member

@grote probably, need to check.

Will it work with other users though? We should test that before we enable it.

@grote
Copy link
Collaborator

grote commented Sep 21, 2020

It should work™, but yeah we should do our own tests before enabling this in production. If it works, that's probably something for an OEM documentation.

@chirayudesai
Copy link
Member

Oh you know, this could also be useful for testing on the same device. I can add the restore activity to the per-user setupwizard.

Then you can just create a new user, and then restore a backup made on the main/other user.

@grote
Copy link
Collaborator

grote commented Sep 22, 2020

What I've tried:

  • Turn on multiple users in Settings -> System -> Advanced -> Multiple users
  • Add new user
  • Switch to new user, including Set up now
  • Settings -> System -> Backup is Not available
  • Get current user ID with adb shell am get-current-user
  • adb shell bmgr --user [ID] list transports returns Error: Backup Manager is not activated for user [ID]
  • to activate adb shell bmgr --user [ID] activate true (no OS patch needed)
  • Settings -> System -> Backup is now empty like for op
  • adb shell bmgr --user [ID] list transports now returns our transport
  • adb shell bmgr --user [ID] transport com.stevesoltys.seedvault.transport.ConfigurableBackupTransport to activate it
  • try a backup and see things working on a first glance

There even seems to be a different view on internal storage, so if you back up to that, the files don't conflict between users.

@ypid can you confirm that this work for you? Please let us know if there's other issues with Seedvault in different user-profiles!

@grote
Copy link
Collaborator

grote commented Sep 22, 2020

I now also tried the Shelter app (which is pretty sweet btw.). There am get-current-user doesn't help you. You need adb shell pm list users which really lists all users. You'll find your work profile there and then can do bmgr activate true like above.

@chirayudesai the activate and transport set steps ideally are something that we can automatically to on a ROM level for all current and future users maybe?

@chirayudesai
Copy link
Member

@chirayudesai the activate and transport set steps ideally are something that we can automatically to on a ROM level for all current and future users maybe?

Yes now that you've confirmed it works we should do that. Did you try restoring?

I think we could do it for 11, and just document the steps you did for 10 if that's fine.

@grote
Copy link
Collaborator

grote commented Sep 22, 2020

A full restore works, but I couldn't get Auto-Restore to work. There's not really any clues in the log, just that the system tries all(?) users for a backup agent of the package I am restoring, but then doing nothing. This might be unrelated as I couldn't get it to work in the personal/main profile.

@grote
Copy link
Collaborator

grote commented Sep 22, 2020

So that's strange: Auto-Restore for the owner profile only started to work again after I deleted the users manually with pm remove-user (Shelter doesn't seem to have an option to remove the work profile again). Then after adding one user and installing the same app there, it still worked. App auto restore for the user did not work tough and afterwards also stopped working for the owner.

Might be an AOSP bug since backup multi-user support was only introduced in Android 10 with a few commits and not touched since. Also, this is all system APIs, Seedvault isn't even called at that point.

@ypid
Copy link
Contributor Author

ypid commented Sep 22, 2020

@ypid can you confirm that this work for you? Please let us know if there's other issues with Seedvault in different user-profiles!

@grote With your help, I managed to enable Seedvault for a new user. But not for my work profile. Testing was done on AOSP 10.

$ adb shell pm list users
Users:
        UserInfo{0:Owner:13} running
        UserInfo{10:New user:10} running
        UserInfo{11:Work profile:30} running
$ adb shell bmgr --user 0 list transports

    com.android.localtransport/.LocalTransport
  * com.stevesoltys.seedvault.transport.ConfigurableBackupTransport
$ for i in 10 11; do adb shell bmgr --user $i enabled; done
Error: Could not access the Backup Manager.  Is the system running?
Error: Could not access the Backup Manager.  Is the system running?
$ for i in 10 11; do adb shell bmgr --user $i actived; done
Error: Could not access the Backup Manager.  Is the system running?
Error: Could not access the Backup Manager.  Is the system running?
$ for i in 10 11; do adb shell bmgr --user $i enable true; done
Error: Could not access the Backup Manager.  Is the system running?
Error: Could not access the Backup Manager.  Is the system running?
$ for i in 10 11; do adb shell bmgr --user $i activate true; done
Backup service now activated for user 10
Exception caught:
java.lang.SecurityException: No permission to configure backup activity
        at android.os.Parcel.createException(Parcel.java:2071)
        at android.os.Parcel.readException(Parcel.java:2039)
        at android.os.Parcel.readException(Parcel.java:1987)
        at android.app.backup.IBackupManager$Stub$Proxy.setBackupServiceActive(IBackupManager.java:3317)
        at com.android.commands.bmgr.Bmgr.doActivateService(Bmgr.java:882)
        at com.android.commands.bmgr.Bmgr.run(Bmgr.java:111)
        at com.android.commands.bmgr.Bmgr.main(Bmgr.java:86)
        at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
        at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:338)
Caused by: android.os.RemoteException: Remote stack trace:
        at com.android.server.backup.Trampoline.enforcePermissionsOnUser(Trampoline.java:309)
        at com.android.server.backup.Trampoline.setBackupServiceActive(Trampoline.java:326)
        at android.app.backup.IBackupManager$Stub.onTransact(IBackupManager.java:1667)
        at android.os.Binder.execTransactInternal(Binder.java:1021)
        at android.os.Binder.execTransact(Binder.java:994)

$ adb shell bmgr --user 10 list transports
    com.android.localtransport/.LocalTransport
  * com.stevesoltys.seedvault.transport.ConfigurableBackupTranspor

I could imaging that the issue I cannot activate the Backup service for my work profile is because I installed Seedvault after setting up the work profile. I will test this when I will start working on Android 11.

@grote
Copy link
Collaborator

grote commented Sep 23, 2020

Error: Could not access the Backup Manager. Is the system running? sounds strange, I've never seen this. Might be worth checking the logs for something related.

The No permission to configure backup activity seems to throw here: http://aosp.opersys.com/xref/android-10.0.0_r46/xref/frameworks/base/services/backup/java/com/android/server/backup/Trampoline.java#313

I tested this on a userdebug build and might have done adb root before.

@tve
Copy link

tve commented Sep 25, 2020

I have the exact same No permission to configure backup activity:

~/M/o/Pixel3a> adb shell pm list users
Users:
        UserInfo{0:Owner:13} running
        UserInfo{10:Work profile:30} running
~/M/o/Pixel3a> adb shell bmgr --user 10 activate true
Exception caught:
java.lang.SecurityException: No permission to configure backup activity

Pixel3a running CalyxOS. Is there any info I can collect to troubleshoot?

@ypid
Copy link
Contributor Author

ypid commented Sep 25, 2020

Checking the logs makes sense of course :)

I disabled the second user again:

adb shell pm list users                
Users:
        UserInfo{0:Owner:13} running
        UserInfo{11:Work profile:30} running

adb shell bmgr --user 10 enable true

# Output: Error: Could not access the Backup Manager.  Is the system running?
2020-09-25 09:56:35.320 shell 20527 20527 D AndroidRuntime: >>>>>> START com.android.internal.os.RuntimeInit uid 2000 <<<<<<               
2020-09-25 09:56:35.356 shell 20527 20527 W app_process: type=1400 audit(0.0:15256): avc: denied { read } for name="u:object_r:device_config_runtime_native_boot_prop:s0" dev="tmpfs" ino=21722 scontext=u:r:shell:s0 tcontext=u:object_r:device_config_runtime_native_boot_prop:s0 tclass=file permissive=0
2020-09-25 09:56:35.360 shell 20527 20527 E libc    : Access denied finding property "persist.device_config.runtime_native_boot.enable_apex_image"
2020-09-25 09:56:35.360 shell 20527 20527 I AndroidRuntime: Using default boot image                                                       
2020-09-25 09:56:35.361 shell 20527 20527 E libc    : Access denied finding property "persist.device_config.runtime_native_boot.disable_lock_profiling"
2020-09-25 09:56:35.361 shell 20527 20527 I AndroidRuntime: Leaving lock profiling enabled                                                 
2020-09-25 09:56:35.361 shell 20527 20527 E libc    : Access denied finding property "persist.device_config.runtime_native_boot.enable_generational_cc"
2020-09-25 09:56:35.356 shell 20527 20527 W app_process: type=1400 audit(0.0:15257): avc: denied { read } for name="u:object_r:device_config_runtime_native_boot_prop:s0" dev="tmpfs" ino=21722 scontext=u:r:shell:s0 tcontext=u:object_r:device_config_runtime_native_boot_prop:s0 tclass=file permissive=0
2020-09-25 09:56:35.815 shell 20527 20527 D ICU     : Time zone APEX file found: /apex/com.android.tzdata/etc/icu/icu_tzdata.dat
2020-09-25 09:56:35.892 shell 20527 20527 I app_process: The ClassLoaderContext is a special shared library.
2020-09-25 09:56:35.933 shell 20527 20527 W app_process: JNI RegisterNativeMethods: attempt to register 0 native methods for android.media.AudioAttributes
2020-09-25 09:56:35.950 shell 20527 20527 D AndroidRuntime: Calling main entry com.android.commands.bmgr.Bmgr
2020-09-25 09:56:35.953 shell 20527 20527 V Bmgr    : Running enable for user:10
2020-09-25 09:56:35.957 shell 20527 20527 D AndroidRuntime: Shutting down VM
  • E libc : Access denied finding property "persist.device_config.runtime_native_boot.enable_apex_image"
    You find some error reports online where this log line is also part of for example can't change ringtone on Pixel 3XL GrapheneOS/os-issue-tracker#147
    So I stop my research about this log line for now.

  • W app_process: type=1400 audit(0.0:15267): avc: denied { read } for name="u:object_r:device_config_runtime_native_boot_prop:s0" dev="tmpfs" ino=21722 scontext=u:r:shell:s0 tcontext=u:object_r:device_config_runtime_native_boot_prop:s0 tclass=file permissive=0

    Looks to me like a SELinux deny. I have no deep knowledge of SELinux yet unfortunate and cannot find any results for this exact warning.

  • W app_process: JNI RegisterNativeMethods: attempt to register 0 native methods for android.media.AudioAttributes
    Some media audio warning which I can probably ignore. For reference, I found reports including this line about something not working when the screen was off (which is the case). So I unlocked and put an work space app in the foreground. Does not change.

adb shell bmgr --user 10 activate true

Output: Exception caught:
Output: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.content.pm.UserInfo.isManagedProfile()' on a null object reference

[Logcat output is very similar. I diffed it.

 D AndroidRuntime: >>>>>> START com.android.internal.os.RuntimeInit uid 2000 <<<<<<
+W app_process: type=1400 audit(0.0:15256): avc: denied { read } for name="u:object_r:device_config_runtime_native_boot_prop:s0" dev="tmpfs" ino=21722 scontext=u:r:shell:s0 tcontext=u:object_r:device_config_runtime_native_boot_prop:s0 tclass=file permissive=0
 E libc    : Access denied finding property "persist.device_config.runtime_native_boot.enable_apex_image"
 I AndroidRuntime: Using default boot image
 E libc    : Access denied finding property "persist.device_config.runtime_native_boot.disable_lock_profiling"
 I AndroidRuntime: Leaving lock profiling enabled
 E libc    : Access denied finding property "persist.device_config.runtime_native_boot.enable_generational_cc"
-W app_process: type=1400 audit(0.0:15267): avc: denied { read } for name="u:object_r:device_config_runtime_native_boot_prop:s0" dev="tmpfs" ino=21722 scontext=u:r:shell:s0 tcontext=u:object_r:device_config_runtime_native_boot_prop:s0 tclass=file permissive=0
+W app_process: type=1400 audit(0.0:15257): avc: denied { read } for name="u:object_r:device_config_runtime_native_boot_prop:s0" dev="tmpfs" ino=21722 scontext=u:r:shell:s0 tcontext=u:object_r:device_config_runtime_native_boot_prop:s0 tclass=file permissive=0
 D ICU     : Time zone APEX file found: /apex/com.android.tzdata/etc/icu/icu_tzdata.dat
 I app_process: The ClassLoaderContext is a special shared library.
 W app_process: JNI RegisterNativeMethods: attempt to register 0 native methods for android.media.AudioAttributes
 D AndroidRuntime: Calling main entry com.android.commands.bmgr.Bmgr
-V Bmgr    : Running activate for user:10
+V Bmgr    : Running enable for user:10
 D AndroidRuntime: Shutting down VM

I am still running on the same exact build and only removed the user, but I now get java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.content.pm.UserInfo.isManagedProfile()' on a null object reference which is something to work with I guess. Out of interest, I added a second user and still get the exception in android.content.pm.UserInfo.isManagedProfile()'. I have not looked into this function. I might do that in a few weeks.

I tested this on a userdebug build and might have done adb root before.

That is what I had in mind. I will probably test with a userdebug build when I get into Android 11 migration work. So you might have cheated :)

@dznsm
Copy link

dznsm commented Sep 25, 2020

Had a chat with the Shelter dev. The problem is probably https://developer.android.com/reference/android/app/admin/DevicePolicyManager#setBackupServiceEnabled(android.content.ComponentName,%20boolean)
They should have a new release in the next few days with support for Android 11. Said that after that they are happy to add a setting to allow backups to be enabled.

@grote
Copy link
Collaborator

grote commented Sep 25, 2020

Yeah, if Shelter could add an option to enable backups (or just do it unconditionally) that would be best I guess.

@ypid thanks for the logs and research. That sounds like something @chirayudesai might want to look into.

@grote
Copy link
Collaborator

grote commented Nov 19, 2020

I guess we could close this, right?

@neurodiverseEsoteric
Copy link

Hi, this was the first search result for "backup work profile" in duckduckgo-privacybrowser...does that mean it's currently impossible to back up a work profile, making impossible to try other sandboxing apps (for example, switching from shelter to insular to see if insular supports updating apps that are frozen but aren't cloned), without loosing every app, file, etc, in ones work profile?

@Uldiniad
Copy link
Contributor

Uldiniad commented May 15, 2021

https://review.calyxos.org/c/CalyxOS/platform_packages_apps_Settings/+/3478

I successfully backed up a work profile to internal storage using the patch above. Now the question is about restoring it.

Additionally I noticed that backing up to USB was not available on the work profile

chirayudesai pushed a commit that referenced this issue Apr 29, 2022
By default, Android exposes USB devices only to the main user.
In order to query, read and write to it, the signature permission INTERACT_ACROSS_USERS_FULL (optional) is granted to create Seedvault's context as the system user.

Issue: calyxos#437
Issue: #77
Change-Id: I0b1b4c8c5aeeb226419ff94e15f631ebe1db66df
AndreiFlorea04 added a commit to AndreiFlorea04/seedvault that referenced this issue Dec 19, 2023
By default, Android exposes USB devices only to the main user.
In order to query, read and write to it, the signature permission INTERACT_ACROSS_USERS_FULL (optional) is granted to create Seedvault's context as the system user.

Issue: calyxos#437
Issue: seedvault-app/seedvault#77
Change-Id: I0b1b4c8c5aeeb226419ff94e15f631ebe1db66df
@grote
Copy link
Collaborator

grote commented May 31, 2024

closing as per #77 (comment)

work profile support for seedvault in calyxos has improved a lot since then

@grote grote closed this as completed May 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants