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

Commit 14b47294 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Defined workflow to notify new users when the device is managed."

parents 9c21de18 0916cee3
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -2729,6 +2729,17 @@ public class DevicePolicyManager {
        return DebugUtils.constantToString(DevicePolicyManager.class, PREFIX_OPERATION, operation);
    }
    /** @hide */
    public void resetNewUserDisclaimer() {
        if (mService != null) {
            try {
                mService.resetNewUserDisclaimer();
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
    }
    /**
     * Return true if the given administrator component is currently active (enabled) in the system.
     *
@@ -5205,6 +5216,16 @@ public class DevicePolicyManager {
    public static final String ACTION_MANAGED_USER_CREATED =
            "android.app.action.MANAGED_USER_CREATED";
    /**
     * Broadcast action: notify system that a new (Android) user was added when the device is
     * managed by a device owner, so receivers can show the proper disclaimer to the (human) user.
     *
     * @hide
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_SHOW_NEW_USER_DISCLAIMER =
            "android.app.action.ACTION_SHOW_NEW_USER_DISCLAIMER";
    /**
     * Widgets are enabled in keyguard
     */
+1 −0
Original line number Diff line number Diff line
@@ -252,6 +252,7 @@ interface IDevicePolicyManager {
    int stopUser(in ComponentName who, in UserHandle userHandle);
    int logoutUser(in ComponentName who);
    List<UserHandle> getSecondaryUsers(in ComponentName who);
    void resetNewUserDisclaimer();

    void enableSystemApp(in ComponentName admin, in String callerPackage, in String packageName);
    int enableSystemAppWithIntent(in ComponentName admin, in String callerPackage, in Intent intent);
+6 −0
Original line number Diff line number Diff line
@@ -54,6 +54,12 @@ abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub {
     * @see {@link SystemService#onUserUnlocking}
     */
    abstract void handleUnlockUser(int userId);
    /**
     * To be called by {@link DevicePolicyManagerService#Lifecycle} after a user is being unlocked.
     *
     * @see {@link SystemService#onUserUnlocked}
     */
    abstract void handleOnUserUnlocked(int userId);
    /**
     * To be called by {@link DevicePolicyManagerService#Lifecycle} when a user is being stopped.
     *
+15 −0
Original line number Diff line number Diff line
@@ -78,6 +78,12 @@ class DevicePolicyData {
    private static final String ATTR_DEVICE_PROVISIONING_CONFIG_APPLIED =
            "device-provisioning-config-applied";
    private static final String ATTR_DEVICE_PAIRED = "device-paired";
    private static final String ATTR_NEW_USER_DISCLAIMER = "new-user-disclaimer";

    // Values of ATTR_NEW_USER_DISCLAIMER
    static final String NEW_USER_DISCLAIMER_SHOWN = "shown";
    static final String NEW_USER_DISCLAIMER_NOT_NEEDED = "not_needed";
    static final String NEW_USER_DISCLAIMER_NEEDED = "needed";

    private static final String TAG = DevicePolicyManagerService.LOG_TAG;
    private static final boolean VERBOSE_LOG = false; // DO NOT SUBMIT WITH TRUE
@@ -146,6 +152,10 @@ class DevicePolicyData {
    // apps were suspended or unsuspended.
    boolean mAppsSuspended = false;

    // Whether it's necessary to show a disclaimer (that the device is managed) after the user
    // starts.
    String mNewUserDisclaimer = NEW_USER_DISCLAIMER_NOT_NEEDED;

    DevicePolicyData(@UserIdInt int userId) {
        mUserId = userId;
    }
@@ -186,6 +196,9 @@ class DevicePolicyData {
            if (policyData.mPermissionPolicy != DevicePolicyManager.PERMISSION_POLICY_PROMPT) {
                out.attributeInt(null, ATTR_PERMISSION_POLICY, policyData.mPermissionPolicy);
            }
            if (NEW_USER_DISCLAIMER_NEEDED.equals(policyData.mNewUserDisclaimer)) {
                out.attribute(null, ATTR_NEW_USER_DISCLAIMER, policyData.mNewUserDisclaimer);
            }

            // Serialize delegations.
            for (int i = 0; i < policyData.mDelegationMap.size(); ++i) {
@@ -412,6 +425,7 @@ class DevicePolicyData {
            if (permissionPolicy != -1) {
                policy.mPermissionPolicy = permissionPolicy;
            }
            policy.mNewUserDisclaimer = parser.getAttributeValue(null, ATTR_NEW_USER_DISCLAIMER);

            int outerDepth = parser.getDepth();
            policy.mLockTaskPackages.clear();
@@ -588,6 +602,7 @@ class DevicePolicyData {
        pw.print("mAppsSuspended="); pw.println(mAppsSuspended);
        pw.print("mUserSetupComplete="); pw.println(mUserSetupComplete);
        pw.print("mAffiliationIds="); pw.println(mAffiliationIds);
        pw.print("mNewUserDisclaimer="); pw.println(mNewUserDisclaimer);
        pw.decreaseIndent();
    }
}
+73 −4
Original line number Diff line number Diff line
@@ -707,6 +707,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        public void onUserStopping(@NonNull TargetUser user) {
            mService.handleStopUser(user.getUserIdentifier());
        }
        @Override
        public void onUserUnlocked(@NonNull TargetUser user) {
            mService.handleOnUserUnlocked(user.getUserIdentifier());
        }
    }
    @GuardedBy("getLockObject()")
@@ -886,6 +891,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        }
    }
    private final class UserLifecycleListener implements UserManagerInternal.UserLifecycleListener {
        @Override
        public void onUserCreated(UserInfo user) {
            mHandler.post(() -> handleNewUserCreated(user));
        }
    }
    private void handlePackagesChanged(@Nullable String packageName, int userHandle) {
        boolean removedAdmin = false;
        if (VERBOSE_LOG) {
@@ -1561,6 +1574,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        mSetupContentObserver = new SetupContentObserver(mHandler);
        mUserManagerInternal.addUserRestrictionsListener(new RestrictionsListener(mContext));
        mUserManagerInternal.addUserLifecycleListener(new UserLifecycleListener());
        loadOwners();
    }
@@ -2901,6 +2915,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        startOwnerService(userId, "unlock-user");
    }
    @Override
    void handleOnUserUnlocked(int userId) {
        showNewUserDisclaimerIfNecessary(userId);
    }
    @Override
    void handleStopUser(int userId) {
        stopOwnerService(userId, "stop-user");
@@ -7687,8 +7706,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
                // Sets profile owner on current foreground user since
                // the human user will complete the DO setup workflow from there.
                manageUserUnchecked(/* deviceOwner= */ admin, /* profileOwner= */ admin,
                            /* managedUser= */ currentForegroundUser,
                            /* adminExtras= */ null);
                        /* managedUser= */ currentForegroundUser, /* adminExtras= */ null,
                        /* showDisclaimer= */ false);
            }
            return true;
        }
@@ -9740,7 +9759,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        final long id = mInjector.binderClearCallingIdentity();
        try {
            manageUserUnchecked(admin, profileOwner, userHandle, adminExtras);
            manageUserUnchecked(admin, profileOwner, userHandle, adminExtras,
                    /* showDisclaimer= */ true);
            if ((flags & DevicePolicyManager.SKIP_SETUP_WIZARD) != 0) {
                Settings.Secure.putIntForUser(mContext.getContentResolver(),
@@ -9762,7 +9782,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
    }
    private void manageUserUnchecked(ComponentName admin, ComponentName profileOwner,
            @UserIdInt int userId, PersistableBundle adminExtras) {
            @UserIdInt int userId, PersistableBundle adminExtras, boolean showDisclaimer) {
        final String adminPkg = admin.getPackageName();
        try {
            // Install the profile owner if not present.
@@ -9788,11 +9808,60 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
            DevicePolicyData policyData = getUserData(userId);
            policyData.mInitBundle = adminExtras;
            policyData.mAdminBroadcastPending = true;
            policyData.mNewUserDisclaimer = showDisclaimer
                    ? DevicePolicyData.NEW_USER_DISCLAIMER_NEEDED
                    : DevicePolicyData.NEW_USER_DISCLAIMER_NOT_NEEDED;
            saveSettingsLocked(userId);
        }
    }
    private void handleNewUserCreated(UserInfo user) {
        if (!mOwners.hasDeviceOwner()) return;
        final int userId = user.id;
        Log.i(LOG_TAG, "User " + userId + " added on DO mode; setting ShowNewUserDisclaimer");
        setShowNewUserDisclaimer(userId, DevicePolicyData.NEW_USER_DISCLAIMER_NEEDED);
    }
    @Override
    public void resetNewUserDisclaimer() {
        CallerIdentity callerIdentity = getCallerIdentity();
        canManageUsers(callerIdentity);
        setShowNewUserDisclaimer(callerIdentity.getUserId(),
                DevicePolicyData.NEW_USER_DISCLAIMER_SHOWN);
    }
    private void setShowNewUserDisclaimer(@UserIdInt int userId, String value) {
        Slog.i(LOG_TAG, "Setting new user disclaimer for user " + userId + " as " + value);
        synchronized (getLockObject()) {
            DevicePolicyData policyData = getUserData(userId);
            policyData.mNewUserDisclaimer = value;
            saveSettingsLocked(userId);
        }
    }
    private void showNewUserDisclaimerIfNecessary(@UserIdInt int userId) {
        boolean mustShow;
        synchronized (getLockObject()) {
            DevicePolicyData policyData = getUserData(userId);
            if (VERBOSE_LOG) {
                Slog.v(LOG_TAG, "showNewUserDisclaimerIfNecessary(" + userId + "): "
                        + policyData.mNewUserDisclaimer + ")");
            }
            mustShow = DevicePolicyData.NEW_USER_DISCLAIMER_NEEDED
                    .equals(policyData.mNewUserDisclaimer);
        }
        if (!mustShow) return;
        Intent intent = new Intent(DevicePolicyManager.ACTION_SHOW_NEW_USER_DISCLAIMER);
        // TODO(b/172691310): add CTS tests to make sure disclaimer is shown
        Slog.i(LOG_TAG, "Dispatching ACTION_SHOW_NEW_USER_DISCLAIMER intent");
        mContext.sendBroadcastAsUser(intent, UserHandle.of(userId));
    }
    @Override
    public boolean removeUser(ComponentName who, UserHandle userHandle) {
        Objects.requireNonNull(who, "ComponentName is null");