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

Commit 3577ed25 authored by Victor Chang's avatar Victor Chang
Browse files

forceUpdateUserSetupComplete should have no effect in user build

Bug:30031808
Change-Id: I908a495633e03ace770a8ec19196841d19dfd41d
parent 9bfc65f3
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -6467,7 +6467,10 @@ public class DevicePolicyManager {

    /**
     * @hide
     * Force update user setup completed status
     * Force update user setup completed status. This API has no effect on user build.
     * @throws {@link SecurityException} if the caller has no
     *         {@link android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS} or the caller is
     *         not {@link UserHandle.SYSTEM_USER}
     */
    public void forceUpdateUserSetupComplete() {
        try {
+24 −11
Original line number Diff line number Diff line
@@ -1392,6 +1392,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            return IAudioService.Stub.asInterface(ServiceManager.getService(Context.AUDIO_SERVICE));
        }

        boolean isBuildDebuggable() {
            return Build.IS_DEBUGGABLE;
        }

        LockPatternUtils newLockPatternUtils() {
            return new LockPatternUtils(mContext);
        }
@@ -8978,6 +8982,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS, null);
    }

    private void enforceCallerSystemUserHandle() {
        final int callingUid = mInjector.binderGetCallingUid();
        final int userId = UserHandle.getUserId(callingUid);
        if (userId != UserHandle.USER_SYSTEM) {
            throw new SecurityException("Caller has to be in user 0");
        }
    }

    @Override
    public boolean isUninstallInQueue(final String packageName) {
        enforceCanManageDeviceAdmin();
@@ -9142,17 +9154,18 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
    @Override
    public void forceUpdateUserSetupComplete() {
        enforceCanManageProfileAndDeviceOwners();
        List<UserInfo> users = mUserManager.getUsers(true);
        final int N = users.size();
        for (int i = 0; i < N; i++) {
            int userHandle = users.get(i).id;
        enforceCallerSystemUserHandle();
        // no effect if it's called from user build
        if (!mInjector.isBuildDebuggable()) {
            return;
        }
        final int userId = UserHandle.USER_SYSTEM;
        boolean isUserCompleted = mInjector.settingsSecureGetIntForUser(
                    Settings.Secure.USER_SETUP_COMPLETE, 0, userHandle) != 0;
            DevicePolicyData policy = getUserData(userHandle);
                Settings.Secure.USER_SETUP_COMPLETE, 0, userId) != 0;
        DevicePolicyData policy = getUserData(userId);
        policy.mUserSetupComplete = isUserCompleted;
        synchronized (this) {
                saveSettingsLocked(userHandle);
            }
            saveSettingsLocked(userId);
        }
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -357,5 +357,10 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi
        TelephonyManager getTelephonyManager() {
            return context.telephonyManager;
        }

        @Override
        boolean isBuildDebuggable() {
            return context.buildMock.isDebuggable;
        }
    }
}
+70 −0
Original line number Diff line number Diff line
@@ -2117,6 +2117,76 @@ public class DevicePolicyManagerTest extends DpmTestBase {
        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true);
    }

    public void testForceUpdateUserSetupComplete_permission() {
        // GIVEN the permission MANAGE_PROFILE_AND_DEVICE_OWNERS is not granted
        try {
            dpm.forceUpdateUserSetupComplete();
            fail("Didn't throw SecurityException");
        } catch (SecurityException expected) {
        }
    }

    public void testForceUpdateUserSetupComplete_systemUser() {
        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
        // GIVEN calling from user 20
        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
        try {
            dpm.forceUpdateUserSetupComplete();
            fail("Didn't throw SecurityException");
        } catch (SecurityException expected) {
        }
    }

    public void testForceUpdateUserSetupComplete_userbuild() {
        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;

        final int userId = UserHandle.USER_SYSTEM;
        // GIVEN userComplete is false in SettingsProvider
        setUserSetupCompleteForUser(false, userId);

        // GIVEN userComplete is true in DPM
        DevicePolicyManagerService.DevicePolicyData userData =
                new DevicePolicyManagerService.DevicePolicyData(userId);
        userData.mUserSetupComplete = true;
        dpms.mUserData.put(UserHandle.USER_SYSTEM, userData);

        // GIVEN it's user build
        mContext.buildMock.isDebuggable = false;

        assertTrue(dpms.hasUserSetupCompleted());

        dpm.forceUpdateUserSetupComplete();

        // THEN the state in dpms is not changed
        assertTrue(dpms.hasUserSetupCompleted());
    }

    public void testForceUpdateUserSetupComplete_userDebugbuild() {
        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;

        final int userId = UserHandle.USER_SYSTEM;
        // GIVEN userComplete is false in SettingsProvider
        setUserSetupCompleteForUser(false, userId);

        // GIVEN userComplete is true in DPM
        DevicePolicyManagerService.DevicePolicyData userData =
                new DevicePolicyManagerService.DevicePolicyData(userId);
        userData.mUserSetupComplete = true;
        dpms.mUserData.put(UserHandle.USER_SYSTEM, userData);

        // GIVEN it's userdebug build
        mContext.buildMock.isDebuggable = true;

        assertTrue(dpms.hasUserSetupCompleted());

        dpm.forceUpdateUserSetupComplete();

        // THEN the state in dpms is not changed
        assertFalse(dpms.hasUserSetupCompleted());
    }

    private void setUserSetupCompleteForUser(boolean isUserSetupComplete, int userhandle) {
        when(mContext.settings.settingsSecureGetIntForUser(Settings.Secure.USER_SETUP_COMPLETE, 0,
                userhandle)).thenReturn(isUserSetupComplete ? 1 : 0);
+6 −0
Original line number Diff line number Diff line
@@ -132,6 +132,10 @@ public class DpmMockContext extends MockContext {
        }
    }

    public static class BuildMock {
        public boolean isDebuggable = true;
    }

    public static class PowerManagerForMock {
        public WakeLock newWakeLock(int levelAndFlags, String tag) {
            return null;
@@ -272,6 +276,8 @@ public class DpmMockContext extends MockContext {

    private final ArrayList<UserInfo> mUserInfos = new ArrayList<>();

    public final BuildMock buildMock = new BuildMock();

    public DpmMockContext(Context context, File dataDir) {
        realTestContext = context;