Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 709a63d9 authored by Nicolas Prevot's avatar Nicolas Prevot
Browse files

Show policy transparency screen if adding an account is not allowed.

If DISALLOW_MODIFY_ACCOUNTS has been set by a profile/device owner,
or account management is disabled:
When an app tries to add an account, show the policy transparency screen.

BUG:26762383
Change-Id: I721220c37c74493020f5a1be1f15731e9863a1de
parent e9670614
Loading
Loading
Loading
Loading
+17 −7
Original line number Diff line number Diff line
@@ -80,15 +80,25 @@ public abstract class DevicePolicyManagerInternal {
    public abstract boolean isActiveAdminWithPolicy(int uid, int reqPolicy);

    /**
     * Creates an intent to show the admin support dialog to let the user know that the package is
     * suspended by the admin. This assumes that {@param packageName} is suspended by the
     * device/profile owner. The caller should check if the package is suspended or not.
     * Creates an intent to show the admin support dialog to say that an action is disallowed by
     * the device/profile owner.
     *
     * <p>This method does not take the DPMS lock.  Safe to be called from anywhere.
     *
     * @param packageName The package that is suspended
     * @param userId The user having the suspended package.
     * @param userId The user where the action is disallowed.
     * @param useDefaultIfNoAdmin If true, a non-null intent will be returned, even if we couldn't
     * find a profile/device owner.
     * @return The intent to trigger the admin support dialog.
     */
    public abstract Intent createPackageSuspendedDialogIntent(String packageName, int userId);
    public abstract Intent createShowAdminSupportIntent(int userId, boolean useDefaultIfNoAdmin);

    /**
     * Creates an intent to show the admin support dialog showing the admin who has set a user
     * restriction.
     *
     * <p>This method does not take the DPMS lock. Safe to be called from anywhere.
     * @param userId The user where the user restriction is set.
     * @return The intent to trigger the admin support dialog, or null if the user restriction is
     * not enforced by the profile/device owner.
     */
    public abstract Intent createUserRestrictionSupportIntent(int userId, String userRestriction);
}
+2 −2
Original line number Diff line number Diff line
@@ -590,8 +590,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
            if (provider.maskedBySuspendedPackage) {
                UserInfo userInfo = mUserManager.getUserInfo(providerUserId);
                showBadge = userInfo.isManagedProfile();
                onClickIntent = mDevicePolicyManagerInternal.createPackageSuspendedDialogIntent(
                        providerPackage, providerUserId);
                onClickIntent = mDevicePolicyManagerInternal.createShowAdminSupportIntent(
                        providerUserId, true);
            } else if (provider.maskedByQuietProfile) {
                showBadge = true;
                onClickIntent = UnlaunchableAppActivity.createInQuietModeDialogIntent(
+23 −4
Original line number Diff line number Diff line
@@ -2954,17 +2954,36 @@ public class AccountManagerService
    }

    private void showCantAddAccount(int errorCode, int userId) {
        Intent cantAddAccount = new Intent(mContext, CantAddAccountActivity.class);
        cantAddAccount.putExtra(CantAddAccountActivity.EXTRA_ERROR_CODE, errorCode);
        cantAddAccount.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        final DevicePolicyManagerInternal dpmi =
                LocalServices.getService(DevicePolicyManagerInternal.class);
        Intent intent = null;
        if (errorCode == AccountManager.ERROR_CODE_USER_RESTRICTED) {
            intent = dpmi.createUserRestrictionSupportIntent(userId,
                    UserManager.DISALLOW_MODIFY_ACCOUNTS);
        } else if (errorCode == AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE) {
            intent = dpmi.createShowAdminSupportIntent(userId, false);
        }
        if (intent == null) {
            intent = getDefaultCantAddAccountIntent(errorCode);
        }
        long identityToken = clearCallingIdentity();
        try {
            mContext.startActivityAsUser(cantAddAccount, new UserHandle(userId));
            mContext.startActivityAsUser(intent, new UserHandle(userId));
        } finally {
            restoreCallingIdentity(identityToken);
        }
    }

    /**
     * Called when we don't know precisely who is preventing us from adding an account.
     */
    private Intent getDefaultCantAddAccountIntent(int errorCode) {
        Intent cantAddAccount = new Intent(mContext, CantAddAccountActivity.class);
        cantAddAccount.putExtra(CantAddAccountActivity.EXTRA_ERROR_CODE, errorCode);
        cantAddAccount.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        return cantAddAccount;
    }

    @Override
    public void confirmCredentialsAsUser(
            IAccountManagerResponse response,
+1 −2
Original line number Diff line number Diff line
@@ -150,8 +150,7 @@ class ActivityStartInterceptor {
        if (devicePolicyManager == null) {
            return false;
        }
        mIntent = devicePolicyManager.createPackageSuspendedDialogIntent(
                mAInfo.packageName, mUserId);
        mIntent = devicePolicyManager.createShowAdminSupportIntent(mUserId, true);
        mCallingPid = mRealCallingPid;
        mCallingUid = mRealCallingUid;
        mResolvedType = null;
+60 −9
Original line number Diff line number Diff line
@@ -8135,28 +8135,79 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        }

        @Override
        public Intent createPackageSuspendedDialogIntent(String packageName, int userId) {
            Intent intent = new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS);
            intent.putExtra(Intent.EXTRA_USER_ID, userId);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        public Intent createShowAdminSupportIntent(int userId, boolean useDefaultIfNoAdmin) {
            // This method is called from AM with its lock held, so don't take the DPMS lock.
            // b/29242568

            ComponentName profileOwner = mOwners.getProfileOwnerComponent(userId);
            if (profileOwner != null) {
                intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, profileOwner);
                return intent;
                return createShowAdminSupportIntent(profileOwner, userId);
            }

            final Pair<Integer, ComponentName> deviceOwner =
                    mOwners.getDeviceOwnerUserIdAndComponent();
            if (deviceOwner != null && deviceOwner.first == userId) {
                intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, deviceOwner.second);
                return intent;
                return createShowAdminSupportIntent(deviceOwner.second, userId);
            }

            // We're not specifying the device admin because there isn't one.
            if (useDefaultIfNoAdmin) {
                return createShowAdminSupportIntent(null, userId);
            }
            return null;
        }

        @Override
        public Intent createUserRestrictionSupportIntent(int userId, String userRestriction) {
            int source;
            long ident = mInjector.binderClearCallingIdentity();
            try {
                source = mUserManager.getUserRestrictionSource(userRestriction,
                        UserHandle.of(userId));
            } finally {
                mInjector.binderRestoreCallingIdentity(ident);
            }
            if ((source & UserManager.RESTRICTION_SOURCE_SYSTEM) != 0) {
                /*
                 * In this case, the user restriction is enforced by the system.
                 * So we won't show an admin support intent, even if it is also
                 * enforced by a profile/device owner.
                 */
                return null;
            }
            boolean enforcedByDo = (source & UserManager.RESTRICTION_SOURCE_DEVICE_OWNER) != 0;
            boolean enforcedByPo = (source & UserManager.RESTRICTION_SOURCE_PROFILE_OWNER) != 0;
            if (enforcedByDo && enforcedByPo) {
                // In this case, we'll show an admin support dialog that does not
                // specify the admin.
                return createShowAdminSupportIntent(null, userId);
            } else if (enforcedByPo) {
                final ComponentName profileOwner = mOwners.getProfileOwnerComponent(userId);
                if (profileOwner != null) {
                    return createShowAdminSupportIntent(profileOwner, userId);
                }
                // This could happen if another thread has changed the profile owner since we called
                // getUserRestrictionSource
                return null;
            } else if (enforcedByDo) {
                final Pair<Integer, ComponentName> deviceOwner
                        = mOwners.getDeviceOwnerUserIdAndComponent();
                if (deviceOwner != null) {
                    return createShowAdminSupportIntent(deviceOwner.second, deviceOwner.first);
                }
                // This could happen if another thread has changed the device owner since we called
                // getUserRestrictionSource
                return null;
            }
            return null;
        }

        private Intent createShowAdminSupportIntent(ComponentName admin, int userId) {
            // This method is called with AMS lock held, so don't take DPMS lock
            final Intent intent = new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS);
            intent.putExtra(Intent.EXTRA_USER_ID, userId);
            intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, admin);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            return intent;
        }
    }