Skip to content

add automatic installation of play apps into work profile#147

Open
mkg20001 wants to merge 389 commits into
GrapheneOS:16-qpr2from
mkg20001:gapps-work-profile-new
Open

add automatic installation of play apps into work profile#147
mkg20001 wants to merge 389 commits into
GrapheneOS:16-qpr2from
mkg20001:gapps-work-profile-new

Conversation

@mkg20001

@mkg20001 mkg20001 commented Mar 21, 2025

Copy link
Copy Markdown

Currently when creating a work profile with a DPC app that requires play services, the DPC app expects play services to also exist on the work profile

Since play services aren't global on GOS, this patch automatically installs them into the work profile

Whether an app requires play services is automatically detected

Because this needs to happen before the DPC app is triggered in any way in the work profile, this needs to be part of the profile creation itself.

@mkg20001

mkg20001 commented Mar 21, 2025

Copy link
Copy Markdown
Author

New, simpler approach. No custom permissions, no custom apis

In InstallStart when installing apps it checks if play store is genuine google play store and the user is a work profile and skips the DISALLOW_UNKNOWN_SOURCES restriction

DevicePolicyGmsHooks runs after device policy manager creates the profile and installs store + services and gives the store permission to install packages (REQUEST_INSTALL_PACKAGES) (only if the managing app requires play services)

@mkg20001 mkg20001 force-pushed the gapps-work-profile-new branch 2 times, most recently from 65c24ec to 6090d44 Compare March 22, 2025 00:13
@mkg20001

mkg20001 commented Mar 24, 2025

Copy link
Copy Markdown
Author

I remember last time I was told the play store installation shouldn't happen in DevicePolicyManagerService as it has too many permissions

I need the installation to happen just before the device policy app is installed and gets any intent, as it may crash due to lack of play services.

I'm none the wiser on how to do that securely and I'd appreciate some guidence if possible

@xxxsskxxx

Copy link
Copy Markdown

Absolute legend mate, thank you so much for continuing to develop and push this!

@mkg20001 mkg20001 force-pushed the gapps-work-profile-new branch from 6090d44 to b7c9a88 Compare April 5, 2025 23:10
@thestinger thestinger force-pushed the 15-qpr2 branch 5 times, most recently from 5f3142f to 8edf282 Compare April 10, 2025 20:49
@thestinger thestinger force-pushed the 15-qpr2 branch 10 times, most recently from 3ec1472 to ccaf1e6 Compare April 28, 2025 03:31
@kazenshi

kazenshi commented May 2, 2025

Copy link
Copy Markdown

New, simpler approach. No custom permissions, no custom apis

In InstallStart when installing apps it checks if play store is genuine google play store and the user is a work profile and skips the DISALLOW_UNKNOWN_SOURCES restriction

DevicePolicyGmsHooks runs after device policy manager creates the profile and installs store + services and gives the store permission to install packages (REQUEST_INSTALL_PACKAGES) (only if the managing app requires play services)

How do we know the managing app requires play services? For example, Microsoft Company Portal requires it to set up the work profile. Will this change support that use case?

@mkg20001

mkg20001 commented May 2, 2025

Copy link
Copy Markdown
Author

New, simpler approach. No custom permissions, no custom apis
In InstallStart when installing apps it checks if play store is genuine google play store and the user is a work profile and skips the DISALLOW_UNKNOWN_SOURCES restriction
DevicePolicyGmsHooks runs after device policy manager creates the profile and installs store + services and gives the store permission to install packages (REQUEST_INSTALL_PACKAGES) (only if the managing app requires play services)

How do we know the managing app requires play services? For example, Microsoft Company Portal requires it to set up the work profile. Will this change support that use case?

See 437b272#diff-d0c4fee5a9bb21d19df9696c4428b8053d7842e0e3fde3356fd4bdc335666548R33

@thestinger thestinger force-pushed the 15-qpr2 branch 3 times, most recently from 44f6627 to c0c2721 Compare May 6, 2025 22:55
@mkg20001 mkg20001 force-pushed the gapps-work-profile-new branch from b7c9a88 to bdfe2c2 Compare May 14, 2025 14:19
@thestinger thestinger force-pushed the 15-qpr2 branch 2 times, most recently from 1e77b17 to acd9811 Compare May 17, 2025 00:40
muhomorr and others added 20 commits December 6, 2025 00:19
This allows to add OS-version-specific packages to the GrapheneOS App Store.
… is on"

This reverts commit e3089ad9f217f948bbf95a5eb37cf66c82e659c2.
When setting up a google-managed work profile, GmsCore tries to install the Android Device Policy app

For this to work REQUEST_INSTALL_PACKAGES permission needs to be in it's manifest
…nto work profile

Currently when creating a work profile with a DPC app that requires play
services,
the DPC app expects play services to also exist on the work profile

Since play services aren't global on GOS, this patch automatically
installs them
into the work profile

Whether an app requires play services is automatically detected

Because this needs to happen before the DPC app is triggered in any way
in the work
profile, this needs to be part of the profile creation itself.
When a work profile with play services gets created Play Store can't 
install any apps
as the work profile may have a policy active to forbid unknown sources 
as it is not
aware that play store is not a system app and gets blocked by that 
policy.

Here we detect if the play store is genuine and is trying to install an 
app
in a work profile. If that is the case we allow it to proceed, despite 
not being a
@mkg20001 mkg20001 force-pushed the gapps-work-profile-new branch from 19dcbdc to 4279d22 Compare December 6, 2025 13:38
@mkg20001 mkg20001 changed the base branch from 16-qpr1 to 16-qpr2 December 6, 2025 13:40
@mkg20001

mkg20001 commented Dec 6, 2025

Copy link
Copy Markdown
Author

I am happy to help if you catch me up a little bit. This would solve the only reason i still have a stock android device - for a work profile

The issue is essentially I'm cloning an instance of something by passing it as a parameter which should not be cloned here https://github.com/GrapheneOS/platform_frameworks_base/pull/147/files#diff-d46ea51799b3e1771bedb5697d2aecdbac71731196b92aafb056154cda6b3927R22120

The other issue is that there are review comments on the old PR about security and how this should be improved that I just don't have the time/energy to look into as android development isn't so big that there would be exact solutions to the comments. You can view the old PR here: GrapheneOS-Archive/platform_frameworks_base-old#559

tl;dr security wise we should not touch devicepolicymanagerservice directly as this service has way too much access, meaning bugs can be catastrophic

@mkg20001

mkg20001 commented Dec 6, 2025

Copy link
Copy Markdown
Author

@AtlasPilotPuppy as for how it works

  • detect if the app that is managing work profile is using play services (manifest metadata tells us that)
  • if so, check if the genuine play store is installed and use installExisting to copy it over to work profile

also there's an exception in installstart so genuine play store can always install packages in work profiles with unknown sources disabled

@mkg20001

mkg20001 commented Dec 6, 2025

Copy link
Copy Markdown
Author

Feel free to make a new pr. I can give you access to a work profile account if you need one for testing

Edit: you can msg me at https://t.me/mkg20001

@xxxsskxxx

Copy link
Copy Markdown

@AtlasPilotPuppy / @mkg20001 , just checking if this has moved on? Many thanks for your time again

@VisceralAsonia

Copy link
Copy Markdown

Will this PR be merged anytime soon? It'd fix pretty much the only issue I currently have with grapheneos in regards to using it at work

@deekej

deekej commented Jun 3, 2026

Copy link
Copy Markdown

@VisceralAsonia, the guides I have found didn't work for me well. I threw Gemini on it to do a deep research, updated the proposed fix by it and was able to successfully install Work Profile on my GrapheneOS (v16)...

In case anybody needs a workaround before there's an official support for Work Profiles by GrapheneOS, you can try following my footsteps here:
https://gist.github.com/deekej/160685c16c578fe53b25bd1f39443667

@xxxsskxxx

xxxsskxxx commented Jun 4, 2026

Copy link
Copy Markdown

@deekej this is fantastic!! So my work profile is up and running.

But, the work play store doesn't let me install any of my work apps, I get a blocked by admin policy error when it attempts to install outlook, as an example. Is there anyway around this?

From using a bit of ai to help diagnose, it doesn't see the plat store as a trusted source.

I will try to amend the script so it also pushes the apks I need in the profile, so when the profile is created, like vending is pushed, it also pushes my apks which I should hopefully be able to just launch.

By the way, I used Microsoft intune and it installed and recognized everything as compliant.


Issue: Work Profile + Microsoft Intune on GrapheneOS – “Blocked by work policy” when installing M365 apps

Device / Setup

  • Pixel 10 Pro 1 TB running GrapheneOS (Android 16)
  • Work Profile created via the GmsCompat injection workaround (see https://gist.github.com/deekej/160685c16c578fe53b25bd1f39443667) because native Intune provisioning crashes (SecurityException:DISPATCH_PROVISIONING_MESSAGE).
  • MDM: Microsoft Intune (Company Portal as Profile Owner).

Symptom
After successful Work Profile creation, any attempt to install Microsoft 365 apps (Excel, Word, Outlook, Teams, etc.) from the managed Play Store inside the Work Profile shows:

🔒 Blocked by work policy
For more info, contact your IT admin.

The Play Store starts the download, then fails with:

Title=Can't install Microsoft Excel: Spreadsheets
returnCode=4, status_code=6002

What the logs show

  1. Device Policy restrictions (user 10)
adb shell dumpsys device_policy --user 10

Relevant excerpt:

UserRestrictionPolicyKey userRestriction_no_install_unknown_sources
    Per-admin Policy:
      EnforcingAdmin { … com.microsoft.windowsintune.companyportal … }
        BooleanPolicyValue { mValue= true }
    Resolved Policy (MostRestrictive): true
  1. Shell access blocked after profile creation
adb shell pm install-existing --user 10 com.microsoft.office.excel

Exception occurred while executing 'install-existing':
java.lang.SecurityException: Shell does not have permission to access user 10
    at com.android.server.pm.PackageManagerShellCommand.translateUserId

Same error appears forpm list packages --user 10,adb install --user 10, etc.

  1. Play Store failure (Finsky logcat)
Finsky  : [22] AU2: Failure History … status_code 6002
Showing notification: Can't install Microsoft Excel … channelId=security-and-errors

Why this happens

  • Intune pushes the classicno_install_unknown_sources restriction to the Work Profile.
  • On stock Android the managed Play Store is a trusted installer, so the restriction is bypassed.
  • On GrapheneOS the sandboxed Play Store is not recognised as a trusted enterprise installer after the injection workaround, so the user restriction is enforced.
  • Once the profile is fully created, GrapheneOS (via the profile owner) denies shell (pm /adb) access to user 10 entirely — the same behaviour seen with Samsung Secure Folder.

Workarounds tried (unsuccessful)

-appops set --user 10 com.android.vending REQUEST_INSTALL_PACKAGES allow
-adb install --user 10 …
-pm install-existing --user 10 …

  • Re-running the injection script after the profile already exists

Question for the community

Is there a way on GrapheneOS to either:

  1. Mark the managed Play Store (com.android.vending) as a trusted installer for a Work Profile managed by Intune, or
  2. Temporarily grant the shell the ability to access user 10 so we can runpm install-existing --user 10 oradb install --user 10?

Any suggestions on how to make the managed Play Store trusted (or bypass theno_install_unknown_sources restriction for the Play Store specifically) would be greatly appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.