CVE-2026-28581 AI-generated analysis
platform/packages/services/Telecomm, CallIntentProcessor (outgoing call intent handling for managed profiles)
Telecom's CallIntentProcessor.fixInitiatingUserIfNecessary now decides whether a managed (work) profile has a dialer by asking RoleManager for a ROLE_DIALER holder in that user and verifying with PackageManager that the holder package exists and is enabled, instead of checking whether any activity in the profile resolves ACTION_DIAL via DefaultDialerManager.getInstalledDialerApplications.
Root cause
fixInitiatingUserIfNecessary(Context, Intent) in src/com/android/server/telecom/CallIntentProcessor.java is meant to re-attribute a call initiated from a managed profile to the parent user when the work profile has no dialer. It decided "no dialer" with DefaultDialerManager.getInstalledDialerApplications(context, userId).size() == 0, i.e. by whether anything in the work profile resolves the ACTION_DIAL intent. Per the commit message, a PackageManager#queryIntentActivitiesAsUser regression reported the "android" package (system server) as an ACTION_DIAL handler in the work profile even when nothing there handles it. The check therefore wrongly concluded that a work dialer existed, and the call was not trampolined to the personal profile. The first fix replaced this with a count of RoleManager.getRoleHolders(ROLE_DIALER). Per the second commit message, on Android 14 getQualifiedDefaultHolderPackageName from Role used the system user and could falsely report the default system dialer role as active for the work profile. So a role holder listed for the profile still did not guarantee an actual enabled dialer there.
How the fix works
- Commit 13272bca51ee (android-security-14.0.0_r28), src/com/android/server/telecom/CallIntentProcessor.java: adds private static doesUserHaveDialerRoleHolder(Context, UserHandle). It creates a user context via context.createContextAsUser(user, 0), gets RoleManager from that context and returns getRoleHolders(RoleManager.ROLE_DIALER).size() > 0.
- Same commit, CallIntentProcessor.fixInitiatingUserIfNecessary: replaces 'noDialerInstalled = DefaultDialerManager.getInstalledDialerApplications(context, initiatingUser.getIdentifier()).size() == 0' with 'noDialerInstalled = !doesUserHaveDialerRoleHolder(context, initiatingUser)'. The following logic, which swaps the initiating user to the profile parent when noDialerInstalled is true, is unchanged.
- Commit 48d04bd33441 (android-security-14.0.0_r29), CallIntentProcessor.doesUserHaveDialerRoleHolder: hardens the check. It now fetches the List<String> of ROLE_DIALER holders and returns false if the list is null or empty. It then takes roleHolders.get(0), looks it up with userContext.getPackageManager().getApplicationInfo(dialerPackage, 0) and returns ApplicationInfo.enabled. A PackageManager.NameNotFoundException returns false.
- Imports added: android.app.role.RoleManager (commit 1); android.content.pm.ApplicationInfo, android.content.pm.PackageManager and java.util.List (commit 2).
Completeness
- Covers the single decision point in fixInitiatingUserIfNecessary for calls whose KEY_INITIATING_USER is a managed profile; no other call paths are changed.
- Only the first entry of the ROLE_DIALER holder list (roleHolders.get(0)) is validated; any other entries are not checked. ROLE_DIALER is an exclusive role, so it normally has at most one holder (general platform knowledge).
- The PackageManager cross-check verifies only ApplicationInfo.enabled at the package level. It does not verify that the holder package still has an enabled ACTION_DIAL activity or otherwise still qualifies as a dialer.
- The causes described in the commit messages (PackageManager queryIntentActivitiesAsUser reporting the 'android' package, and Role default-holder resolution against the system user) are worked around in Telecom rather than fixed in the framework. The material contains no framework-side change.
- The import of android.telecom.DefaultDialerManager is still in the file at android-security-14.0.0_r29. The material does not show whether getInstalledDialerApplications is still used elsewhere in CallIntentProcessor.
Behavior changes
- Calls from a work profile that has no ROLE_DIALER holder, or whose role holder package is missing or disabled, are now re-attributed to the parent (personal) user and handled by the personal dialer. Previously such calls could stay attributed to the work profile.
- Calls from a work profile with an installed, enabled dialer role holder still launch the work profile dialer (per the commit tests).
- The decision now depends on RoleManager and PackageManager queries made under a user-specific context (createContextAsUser), not on ACTION_DIAL intent resolution.
Per major
- Android 14: Same fix, in two commits: 13272bca51ee (RoleManager check) in android-security-14.0.0_r28, then 48d04bd33441 (PackageManager enabled cross-check) in android-security-14.0.0_r29. The patched region is present at r29 (8/8 lines).
- Android 15: Adapted fix: commit 34079b659664 in android-security-15.0.0_r16 applies the RoleManager check. On 15, fixInitiatingUserIfNecessary takes a FeatureFlags parameter and uses UserUtil.isManagedProfile(context, initiatingUser, featureFlags) and context.getSystemService(UserManager.class). The material does not show the second (ApplicationInfo.enabled) commit for 15. Region 8/8 present at r17.
- Android 16: Adapted fix: commit 510bcce16c24 in android-security-16.0.0_r7, with the same FeatureFlags-based shape as 15. The material does not show the second commit for 16. Region 8/8 present at r8.
- Android 17: Commit c1104b6c1bbe in android-security-17.0.0_r1 adds the PackageManager enabled cross-check. Its diff context shows the RoleManager-based doesUserHaveDialerRoleHolder already present. Region 8/8 present at r1.
Unknowns
- What information is disclosed, and to whom, when a work profile call is not re-attributed to the parent user; the bulletin only classifies it as ID/High.
- Whether the second commit (PackageManager enabled cross-check) was applied to the Android 15 and 16 security branches; the material shows only the first commit there.
- Whether the underlying PackageManager and RoleManager behaviors described in the commit messages were fixed separately in frameworks/base.
- Whether DefaultDialerManager.getInstalledDialerApplications is still used elsewhere in Telecom for similar decisions.
- Which entry points call fixInitiatingUserIfNecessary; the index search found no callers.