I have a OnePlus 5 on which I installed LineageOS 18.1 with Google Apps.
My intention is for this to be my child's phone, who is underage and whose account is limited by Google Family Link. (I'm not particularly in love with Family Link; it just comes automatically with honesty when registering the kid's Google account, i.e. not lying about their age. The screen time limitation is the only feature I actually find useful.)
I also installed Magisk v23 to root the phone. I realize that with enough determination my kid could potentially circumvent Family Link using root and e.g. adb, and don't mind.
I used my own Google account for the initial setup, but eventually I'd like to transfer my kid's apps and data from a previous device.
My first thought was to use the "multiple users" feature. I created an account for the child on the phone, and was going to use Titanium Backup to restore the backups of apps and data from the previous phone.
However, I'm beginning to have second thoughts. Is this a good way of approaching this? For example, if I continue as the "device owner", won't this device pollute my location sharing/location history?
Do I understand correctly that there is no way to change who the owner is (i.e. promote the child from "user" to "owner" and simultaneously demote myself from "owner" to "user")?
Would it be a better idea to instead, in the device owner environment, remove my Google Account and add the child's?
I would like to avoid lengthy experiments if possible, but will answer my own question if it comes to that.
My principal specific question is: what would be the consequences of these two approaches?
- kid continues as user; I am owner
- add kid's google account to device owner profile; remove mine
Update: adding kid as user is not straightforward; apparently (and logically) there is a whole new mount namespace so the TitaniumBackup directory I copied to the /sdcard directory of the primary account isn't visible, and even an elevated adb shell doesn't have access to /storage/emulated/10
(which I gather is where the new storage space lives). I couldn't be bothered to workaround this, so I removed the kid's user.
I then tried adding the kid's account alongside mine, but that doesn't work because it's managed by family link; I have to remove my account first. Did that, and when trying to add the kid's account I get into an endless loop where it says it'll install family link manager, I click next, and it informs me that this step is necessary; repeat ad nauseam. I think the issue may be that it doesn't pass the SafetyNet check, because logcat
has lines like
06-16 15:49:05.915 11187 11187 I BaseTask: ScheduleSafetyNetJobTask started. [CONTEXT service_id=42 ]
06-16 15:49:05.916 11187 12931 I KidsJobScheduler: schedule job DEVICE_SETUP_SAFETY_NET [CONTEXT service_id=42 ]
06-16 15:49:05.918 1444 3734 E EdXposed-Bridge: java.lang.ClassCastException: java.lang.String cannot be cast to android.content.Intent
06-16 15:49:05.918 1444 3734 E EdXposed-Bridge: at com.aviraxp.adblocker.continued.hook.h$a.beforeHookedMethod(ShortcutHook.java:2)
06-16 15:49:05.918 1444 3734 E EdXposed-Bridge: at de.robv.android.xposed.MethodHooker.handleHookedMethod(MethodHooker.java:61)
06-16 15:49:05.918 1444 3734 E EdXposed-Bridge: at EdHooker_d6cb3615b07510db932c119335b0668763709397.hook(Unknown Source:171)
06-16 15:49:05.918 1444 3734 E EdXposed-Bridge: at com.android.server.am.ActivityManagerService.broadcastIntentWithFeature(ActivityManagerService.java:16728)
06-16 15:49:05.918 1444 3734 E EdXposed-Bridge: at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:2283)
06-16 15:49:05.918 1444 3734 E EdXposed-Bridge: at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2867)
06-16 15:49:05.918 1444 3734 E EdXposed-Bridge: at android.os.Binder.execTransactInternal(Binder.java:1154)
06-16 15:49:05.918 1444 3734 E EdXposed-Bridge: at android.os.Binder.execTransact(Binder.java:1123)
06-16 15:49:05.919 1444 3734 E EdXposed-Bridge: java.lang.ClassCastException: java.lang.String cannot be cast to android.content.Intent
06-16 15:49:05.919 1444 3734 E EdXposed-Bridge: at com.aviraxp.adblocker.continued.hook.h$a.beforeHookedMethod(ShortcutHook.java:2)
06-16 15:49:05.919 1444 3734 E EdXposed-Bridge: at de.robv.android.xposed.MethodHooker.handleHookedMethod(MethodHooker.java:61)
06-16 15:49:05.919 1444 3734 E EdXposed-Bridge: at EdHooker_1d32fd428893610d3914110116abed3745926464.hook(Unknown Source:185)
06-16 15:49:05.919 1444 3734 E EdXposed-Bridge: at com.android.server.am.ActivityManagerService.broadcastIntentLocked(ActivityManagerService.java:15914)
06-16 15:49:05.919 1444 3734 E EdXposed-Bridge: at java.lang.reflect.Method.invoke(Native Method)
06-16 15:49:05.919 1444 3734 E EdXposed-Bridge: at de.robv.android.xposed.MethodHooker.handleHookedMethod(MethodHooker.java:81)
06-16 15:49:05.919 1444 3734 E EdXposed-Bridge: at EdHooker_d6cb3615b07510db932c119335b0668763709397.hook(Unknown Source:171)
06-16 15:49:05.919 1444 3734 E EdXposed-Bridge: at com.android.server.am.ActivityManagerService.broadcastIntentWithFeature(ActivityManagerService.java:16728)
06-16 15:49:05.919 1444 3734 E EdXposed-Bridge: at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:2283)
06-16 15:49:05.919 1444 3734 E EdXposed-Bridge: at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2867)
06-16 15:49:05.919 1444 3734 E EdXposed-Bridge: at android.os.Binder.execTransactInternal(Binder.java:1154)
06-16 15:49:05.919 1444 3734 E EdXposed-Bridge: at android.os.Binder.execTransact(Binder.java:1123)
06-16 15:49:05.921 11187 12930 I BaseTask: ScheduleSafetyNetJobTask finished (5 ms). [CONTEXT service_id=42 ]
06-16 15:49:05.928 1444 3734 W ActivityTaskManager: Tried to set launchTime (0) < mLastActivityLaunchTime (1954917)
06-16 15:49:05.938 10959 10959 W DeviceAdminAdd: Unable to set profile owner post-setup, no default supervisorprofile owner defined
06-16 15:49:05.993 11187 11187 I BaseTask: ScheduleSafetyNetJobTask started. [CONTEXT service_id=42 ]
06-16 15:49:05.994 11187 12931 I KidsJobScheduler: schedule job DEVICE_SETUP_SAFETY_NET [CONTEXT service_id=42 ]
06-16 15:49:05.996 11187 11187 W System.err: java.lang.Exception: Result is true
06-16 15:49:05.996 11187 11187 W System.err: at m.cqr.c(:com.google.android.gms.policy_kids@[email protected]:6)
06-16 15:49:05.996 11187 11187 W System.err: at m.cqv.j(:com.google.android.gms.policy_kids@[email protected]:0)
06-16 15:49:05.996 11187 11187 W System.err: at com.google.android.gms.kids.setup.fragment.KidSetupFragment.cm(:com.google.android.gms.policy_kids@[email protected]:0)
06-16 15:49:05.996 11187 11187 W System.err: at com.google.android.gms.kids.setup.fragment.ActivateProfileOwnerFragment.onActivityResult(:com.google.android.gms.policy_kids@[email protected]:6)
06-16 15:49:05.996 11187 11187 W System.err: at com.google.android.chimera.FragmentProxy.onActivityResult(:com.google.android.gms@[email protected] (150400-378233385):0)
06-16 15:49:05.996 11187 11187 W System.err: at fd.ht(:com.google.android.gms@[email protected] (150400-378233385):6)
06-16 15:49:05.996 11187 11187 W System.err: at aes.g(:com.google.android.gms@[email protected] (150400-378233385):6)
06-16 15:49:05.996 11187 11187 W System.err: at eic.onActivityResult(:com.google.android.gms@[email protected] (150400-378233385):0)
06-16 15:49:05.996 11187 11187 W System.err: at eih.onActivityResult(:com.google.android.gms@[email protected] (150400-378233385):0)
06-16 15:49:05.996 11187 11187 W System.err: at edb.support_onActivityResult(:com.google.android.gms@[email protected] (150400-378233385):0)
06-16 15:49:05.996 11187 11187 W System.err: at edg.onActivityResult(:com.google.android.gms@[email protected] (150400-378233385):0)
06-16 15:49:05.996 11187 11187 W System.err: at edg.public_onActivityResult(:com.google.android.gms@[email protected] (150400-378233385):0)
06-16 15:49:05.997 11187 11187 W System.err: at rie.onActivityResult(:com.google.android.gms@[email protected] (150400-378233385):4)
06-16 15:49:05.997 11187 11187 W System.err: at android.app.Activity.dispatchActivityResult(Activity.java:8310)
06-16 15:49:05.997 11187 11187 W System.err: at android.app.ActivityThread.deliverResults(ActivityThread.java:5002)
06-16 15:49:05.997 11187 11187 W System.err: at android.app.ActivityThread.handleSendResult(ActivityThread.java:5050)
06-16 15:49:05.997 11187 11187 W System.err: at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
06-16 15:49:05.997 11187 11187 W System.err: at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
06-16 15:49:05.997 11187 11187 W System.err: at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
06-16 15:49:05.997 11187 11187 W System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
06-16 15:49:05.997 11187 11187 W System.err: at android.os.Handler.dispatchMessage(Handler.java:106)
06-16 15:49:05.997 11187 11187 W System.err: at android.os.Looper.loop(Looper.java:223)
06-16 15:49:05.997 11187 11187 W System.err: at android.app.ActivityThread.main(ActivityThread.java:7660)
06-16 15:49:05.997 11187 11187 W System.err: at java.lang.reflect.Method.invoke(Native Method)
06-16 15:49:05.997 11187 11187 W System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
06-16 15:49:05.997 11187 11187 W System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
06-16 15:49:05.999 1444 4198 E EdXposed-Bridge: java.lang.ClassCastException: java.lang.String cannot be cast to android.content.Intent
06-16 15:49:05.999 1444 4198 E EdXposed-Bridge: at com.aviraxp.adblocker.continued.hook.h$a.beforeHookedMethod(ShortcutHook.java:2)
06-16 15:49:05.999 1444 4198 E EdXposed-Bridge: at de.robv.android.xposed.MethodHooker.handleHookedMethod(MethodHooker.java:61)
06-16 15:49:05.999 1444 4198 E EdXposed-Bridge: at EdHooker_d6cb3615b07510db932c119335b0668763709397.hook(Unknown Source:171)
06-16 15:49:05.999 1444 4198 E EdXposed-Bridge: at com.android.server.am.ActivityManagerService.broadcastIntentWithFeature(ActivityManagerService.java:16728)
06-16 15:49:05.999 1444 4198 E EdXposed-Bridge: at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:2283)
06-16 15:49:05.999 1444 4198 E EdXposed-Bridge: at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2867)
06-16 15:49:05.999 1444 4198 E EdXposed-Bridge: at android.os.Binder.execTransactInternal(Binder.java:1154)
06-16 15:49:05.999 1444 4198 E EdXposed-Bridge: at android.os.Binder.execTransact(Binder.java:1123)
06-16 15:49:05.999 1444 4198 E EdXposed-Bridge: java.lang.ClassCastException: java.lang.String cannot be cast to android.content.Intent
06-16 15:49:05.999 1444 4198 E EdXposed-Bridge: at com.aviraxp.adblocker.continued.hook.h$a.beforeHookedMethod(ShortcutHook.java:2)
06-16 15:49:05.999 1444 4198 E EdXposed-Bridge: at de.robv.android.xposed.MethodHooker.handleHookedMethod(MethodHooker.java:61)
06-16 15:49:05.999 1444 4198 E EdXposed-Bridge: at EdHooker_1d32fd428893610d3914110116abed3745926464.hook(Unknown Source:185)
06-16 15:49:05.999 1444 4198 E EdXposed-Bridge: at com.android.server.am.ActivityManagerService.broadcastIntentLocked(ActivityManagerService.java:15914)
06-16 15:49:05.999 1444 4198 E EdXposed-Bridge: at java.lang.reflect.Method.invoke(Native Method)
06-16 15:49:05.999 1444 4198 E EdXposed-Bridge: at de.robv.android.xposed.MethodHooker.handleHookedMethod(MethodHooker.java:81)
06-16 15:49:05.999 1444 4198 E EdXposed-Bridge: at EdHooker_d6cb3615b07510db932c119335b0668763709397.hook(Unknown Source:171)
06-16 15:49:05.999 1444 4198 E EdXposed-Bridge: at com.android.server.am.ActivityManagerService.broadcastIntentWithFeature(ActivityManagerService.java:16728)
06-16 15:49:05.999 1444 4198 E EdXposed-Bridge: at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:2283)
06-16 15:49:05.999 1444 4198 E EdXposed-Bridge: at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2867)
06-16 15:49:05.999 1444 4198 E EdXposed-Bridge: at android.os.Binder.execTransactInternal(Binder.java:1154)
06-16 15:49:05.999 1444 4198 E EdXposed-Bridge: at android.os.Binder.execTransact(Binder.java:1123)
06-16 15:49:06.003 11187 12930 I BaseTask: ScheduleSafetyNetJobTask finished (9 ms). [CONTEXT service_id=42 ]
I disabled EdXposed, leaving me with
06-16 15:58:55.797 6486 6486 W DeviceAdminAdd: Unable to set profile owner post-setup, no default supervisorprofile owner defined
06-16 15:58:55.852 6269 6269 I BaseTask: ScheduleSafetyNetJobTask started. [CONTEXT service_id=42 ]
06-16 15:58:55.853 6269 6634 I KidsJobScheduler: schedule job DEVICE_SETUP_SAFETY_NET [CONTEXT service_id=42 ]
06-16 15:58:55.855 6269 6269 W System.err: java.lang.Exception: Result is true
06-16 15:58:55.855 6269 6269 W System.err: at m.cqr.c(:com.google.android.gms.policy_kids@[email protected]:6)
06-16 15:58:55.855 6269 6269 W System.err: at m.cqv.j(:com.google.android.gms.policy_kids@[email protected]:0)
06-16 15:58:55.855 6269 6269 W System.err: at com.google.android.gms.kids.setup.fragment.KidSetupFragment.cm(:com.google.android.gms.policy_kids@[email protected]:0)
06-16 15:58:55.855 6269 6269 W System.err: at com.google.android.gms.kids.setup.fragment.ActivateProfileOwnerFragment.onActivityResult(:com.google.android.gms.policy_kids@[email protected]:6)
06-16 15:58:55.855 6269 6269 W System.err: at com.google.android.chimera.FragmentProxy.onActivityResult(:com.google.android.gms@[email protected] (150400-378233385):0)
06-16 15:58:55.855 6269 6269 W System.err: at fd.ht(:com.google.android.gms@[email protected] (150400-378233385):6)
06-16 15:58:55.855 6269 6269 W System.err: at aes.g(:com.google.android.gms@[email protected] (150400-378233385):6)
06-16 15:58:55.855 6269 6269 W System.err: at eic.onActivityResult(:com.google.android.gms@[email protected] (150400-378233385):0)
06-16 15:58:55.855 6269 6269 W System.err: at eih.onActivityResult(:com.google.android.gms@[email protected] (150400-378233385):0)
06-16 15:58:55.855 6269 6269 W System.err: at edb.support_onActivityResult(:com.google.android.gms@[email protected] (150400-378233385):0)
06-16 15:58:55.855 6269 6269 W System.err: at edg.onActivityResult(:com.google.android.gms@[email protected] (150400-378233385):0)
06-16 15:58:55.856 6269 6269 W System.err: at edg.public_onActivityResult(:com.google.android.gms@[email protected] (150400-378233385):0)
06-16 15:58:55.856 6269 6269 W System.err: at rie.onActivityResult(:com.google.android.gms@[email protected] (150400-378233385):4)
06-16 15:58:55.856 6269 6269 W System.err: at android.app.Activity.dispatchActivityResult(Activity.java:8310)
06-16 15:58:55.856 6269 6269 W System.err: at android.app.ActivityThread.deliverResults(ActivityThread.java:5002)
06-16 15:58:55.856 6269 6269 W System.err: at android.app.ActivityThread.handleSendResult(ActivityThread.java:5050)
06-16 15:58:55.856 6269 6269 W System.err: at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
06-16 15:58:55.856 6269 6269 W System.err: at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
06-16 15:58:55.856 6269 6269 W System.err: at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
06-16 15:58:55.856 6269 6269 W System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
06-16 15:58:55.856 6269 6269 W System.err: at android.os.Handler.dispatchMessage(Handler.java:106)
06-16 15:58:55.856 6269 6269 W System.err: at android.os.Looper.loop(Looper.java:223)
06-16 15:58:55.856 6269 6269 W System.err: at android.app.ActivityThread.main(ActivityThread.java:7660)
06-16 15:58:55.856 6269 6269 W System.err: at java.lang.reflect.Method.invoke(Native Method)
06-16 15:58:55.856 6269 6269 W System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
06-16 15:58:55.856 6269 6269 W System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
06-16 15:58:55.858 6269 6618 I BaseTask: ScheduleSafetyNetJobTask finished (6 ms). [CONTEXT service_id=42 ]
06-16 15:58:55.952 1395 2506 I system_server: oneway function results will be dropped but finished with status OK and parcel size 4
I will now disable all Magisk modules one by one to see if I can get past this step eventually.
Update 2: the "activate family link manager" loop issue might not be related to Magisk at all. It's been reported to Google at e.g. https://support.google.com/googleplay/thread/15850322/activation-family-link-manager-error-message-loop?hl=en and https://support.google.com/googleplay/forum/AAAA8CVOtD88XvbDIUaPF0/?hl=en&gpf=%23!topic%2Fplay%2F8XvbDIUaPF0. For at least one person, hacks like manually making the family link app a device admin in " Settings -> Security -> Device administrator" as well as "Settings -> Application manager -> Reset app preferences" helped, but "it looks like the Family Link Manager expects to be able to open the settings app on a specific page, which doesn't look to exist on all devices. This also happens on the Xiaomi MiPad as well... https://xiaomi.eu/community/threads/first-xiaomi-eu-rom-released-for-mipad-4.46337/
Manually settings the App as a device admin does not get you past this check.", which I can confirm.
Update 3: I got past the "Next, you'll activate Family Link" loop by manually converting com.google.android.apps.kids.familylinkhelper
and com.google.android.apps.kids.familylinkmanager
into system apps. With Magisk, /system/app
is a writable tmpfs (i.e. not persisent); I remounted / (which the real /system/app
is on) rw
using mount -n / -o rw,remount
, then bind mounted it under a directory: mkdir /mnt/root; mount --bind / /mnt/root
. I copied the two APKs from my Titanium Backups to /mnt/root/system/app
, then rebooted and Family Link setup was able to complete.
Now let's see about restoring all the apps from backup.
com.aviraxp.adblocker.continued
has a bug. You should file an issue on it's Github project.