Earlier this year, I was part of a systematic study of the security of Android’s multi-user features, done by the Smartphone Security Research Group at Syracuse University. The recent release of Android L Developer Preview mentioned a new enterprise feature called managed provisioning that sounded like it might be related to the earlier multi-user features. My curiosity got the best of me, and although it was after midnight last night (this morning), I decided to do a short “quick look” at the Managed Profile feature of Android L. I installed the Android L Preview on a Nexus 7 and then rooted it with SuperSU so that I could poke around the file system. Next I imported the BasicManagedProfile sample app into Android Studio and ran it on the Nexus. Here’s what I found:
The goal of Managed Provisioning/Profiles is to allow managed apps alongside personal apps in the same launcher and account. This is graphically shown by having the managed apps’ icons overlaid with a small red suitcase badge. In other words, in the same launcher, I can have my own Gmail for a personal account, and another Gmail for a managed, company account. Both in the same launcher without having to switch users and they can be running at the same time. They run as separate apps, so they can have separate configurations, providers, etc. Here’s screenshots of the launcher and app drawer from my tests showing the mix of unmanaged and managed apps (note red badges and duplicates):
Google has most definitely used the same multi-user framework that we previously studied to implement this. When I created a Managed Profile using their sample app (see below), it set up a userId 10 just like as if I had created a secondary user or restricted profile. All of the files and folders are pretty much the same as before:
- /data/user/<userId>: contains the data directories for all of the installed apps (same as multi-user).
- /data/system/users/<userId>.xml: describes the user, restricted profile or managed profile (same as multi-user). For a managed profile, is linked to the owning user with a (new?) tag, profileGroupId, that seems to be set to the userId of the owning user.
- /data/system/users/userlist.xml: keeps track of the assigned userIds, next available ID and some other things (same as multi-user).
- /data/system/users/<userId>: contains SQLite databases for that userId‘s accounts, personal settings, and wallpaper. Also has a few XML files: device_policies.xml, appwidgets.xml, and package-restrictions.xml. While this is also stuff we saw in multi-user, there seem to be some additional interesting tags in a couple of these files. For example, the restrictions file for the managed profile I created has what appears to be provisions to block apps and control the destination userId for certain intents. In other words, it seems to specify which intents that originate in the managed profile can go to unmanaged apps of the owning user.
Furthermore, I confirmed that things are very similar to multi-user by launching both Calendar apps, unmanaged and managed, and then checking ps:
$ ps | grep calendar
u0_a29 7009 224 1389256 50788 ffffffff 00000000 S com.google.android.calendar
u0_a1 7041 224 1361328 34904 ffffffff 00000000 S com.android.providers.calendar
u10_a29 7112 224 1389640 50868 ffffffff 00000000 S com.google.android.calendar
u10_a1 7140 224 1361328 34920 ffffffff 00000000 S com.android.providers.calendar
As you can see, the unmanaged Calendar and its provider are running as the Owner (userId 0), and the managed pair is running as userId 10. They are in fact the same app (appId 10029), just like different users or restricted profiles share the same app installation, but run them as different UIDs.
As far as I can tell, there’s no setup for this in the Settings menus at this time. The Users menu only has what we saw before (Add User/Add Restricted Profile for the Owner), although once the managed profile was created, the Users menu listed it and included the capability to delete it. The lack of an add capability may be either a facet of the L Preview being incomplete or because of the fact that the feature is managed by a Device Administrator via API and therefore should not be a part of Settings. We’ll have to wait and see.
To play with it on the device, I had to get the sample app, BasicManagedProfile, from the L Preview SDK and import it into Android Studio. The source code contains this information:
This sample demonstrates how to create a managed profile. You can also learn how to enable or disable other apps and how to set restrictions to them. Intents can be configured to be forwarded between primary account and managed profile. Finally, you can wipe all the data associated with the profile. Note that there can only be one managed profile on a device.
This app lets users set up a managed profile, and do some sample operations: 1) add Calculator and/or Chrome to the set of managed apps that it sets up by default (Calendar, Google Search, etc.); 2) set restrictions on Chrome; 3) enable/disable Intent forwarding; and 4) wipe the profile. It has android.permission.BIND_DEVICE_ADMIN. Here’s a screenshot of the app running in the managed profile, and the window that comes up when you hit the “Set Chrome Restrictions” button:
So after my quick look, I’m pretty confident that Managed Profiles are basically the same thing as Restricted Profiles except that the apps of the different profiles can coexist on the same launcher so you don’t need to switch users to use them all. Also, there are new rules having to do with Intents between unmanaged and managed apps that are tied to the same user group. The userIdDest and Intent filter parts of package-restrictions.xml, as well as the “Share Intent” buttons of the sample app are evidence of this. This aspect could be very interesting to learn more about. Finally, there are some more fine-grained restrictions that can be applied to apps in the managed profile.