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

Commit 1216ae5d authored by Mahaver Chopra's avatar Mahaver Chopra
Browse files

Update DPM.reboot with new restriction

DPM.reboot() should not be called when there is an ongoing call on the
device.

Bug:27531799
Change-Id: Idc1fa4c7aa79b20ec9c2afcccf855455ee316787
parent 0efa9e12
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ import android.provider.ContactsContract.Directory;
import android.provider.Settings;
import android.security.Credentials;
import android.service.restrictions.RestrictionsReceiver;
import android.telephony.TelephonyManager;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;
@@ -5566,7 +5567,10 @@ public class DevicePolicyManager {
    }

    /**
     * Called by device owner to reboot the device.
     * Called by device owner to reboot the device. If there is an ongoing call on the device,
     * throws an {@link IllegalStateException}.
     * @throws IllegalStateException if device has an ongoing call.
     * @see TelephonyManager#CALL_STATE_IDLE
     */
    public void reboot(@NonNull ComponentName admin) {
        try {
+11 −0
Original line number Diff line number Diff line
@@ -115,6 +115,7 @@ import android.security.IKeyChainService;
import android.security.KeyChain;
import android.security.KeyChain.KeyChainConnection;
import android.service.persistentdata.PersistentDataBlockManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -306,6 +307,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
    final IPackageManager mIPackageManager;
    final UserManager mUserManager;
    final UserManagerInternal mUserManagerInternal;
    final TelephonyManager mTelephonyManager;
    private final LockPatternUtils mLockPatternUtils;

    /**
@@ -1354,6 +1356,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            return LocalServices.getService(PowerManagerInternal.class);
        }

        TelephonyManager getTelephonyManager() {
            return TelephonyManager.from(mContext);
        }

        IWindowManager getIWindowManager() {
            return IWindowManager.Stub
                    .asInterface(ServiceManager.getService(Context.WINDOW_SERVICE));
@@ -1542,6 +1548,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        mUserManager = Preconditions.checkNotNull(injector.getUserManager());
        mUserManagerInternal = Preconditions.checkNotNull(injector.getUserManagerInternal());
        mIPackageManager = Preconditions.checkNotNull(injector.getIPackageManager());
        mTelephonyManager = Preconditions.checkNotNull(injector.getTelephonyManager());

        mLocalService = new LocalService();
        mLockPatternUtils = injector.newLockPatternUtils();
@@ -8309,6 +8316,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        }
        long ident = mInjector.binderClearCallingIdentity();
        try {
            // Make sure there are no ongoing calls on the device.
            if (mTelephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE) {
                throw new IllegalStateException("Cannot be called with ongoing call on the device");
            }
            mInjector.powerManagerReboot(PowerManager.REBOOT_REQUESTED_BY_DEVICE_OWNER);
        } finally {
            mInjector.binderRestoreCallingIdentity(ident);
+6 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManagerInternal;
import android.os.storage.StorageManager;
import android.telephony.TelephonyManager;
import android.view.IWindowManager;

import java.io.File;
@@ -322,5 +323,10 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi
        boolean securityLogIsLoggingEnabled() {
            return context.settings.securityLogIsLoggingEnabled();
        }

        @Override
        TelephonyManager getTelephonyManager() {
            return context.telephonyManager;
        }
    }
}
+25 −1
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.test.MoreAsserts;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.ArraySet;
@@ -1491,7 +1492,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
        assertEquals("11:22:33:44:55:66", dpm.getWifiMacAddress(admin1));
    }

    public void testRebootCanOnlyBeCalledByDeviceOwner() throws Exception {
    public void testReboot() throws Exception {
        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);

@@ -1524,6 +1525,29 @@ public class DevicePolicyManagerTest extends DpmTestBase {
        dpm.clearProfileOwner(admin1);
        assertTrue(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM));

        // admin1 is DO.
        // Set current call state of device to ringing.
        when(mContext.telephonyManager.getCallState())
                .thenReturn(TelephonyManager.CALL_STATE_RINGING);
        try {
            dpm.reboot(admin1);
            fail("DPM.reboot() called when receiveing a call, should thrown IllegalStateException");
        } catch (IllegalStateException expected) {
            MoreAsserts.assertContainsRegex("ongoing call on the device", expected.getMessage());
        }

        // Set current call state of device to dialing/active.
        when(mContext.telephonyManager.getCallState())
                .thenReturn(TelephonyManager.CALL_STATE_OFFHOOK);
        try {
            dpm.reboot(admin1);
            fail("DPM.reboot() called when dialing, should thrown IllegalStateException");
        } catch (IllegalStateException expected) {
            MoreAsserts.assertContainsRegex("ongoing call on the device", expected.getMessage());
        }

        // Set current call state of device to idle.
        when(mContext.telephonyManager.getCallState()).thenReturn(TelephonyManager.CALL_STATE_IDLE);
        dpm.reboot(admin1);
    }

+3 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManagerInternal;
import android.os.storage.StorageManager;
import android.telephony.TelephonyManager;
import android.test.mock.MockContentResolver;
import android.test.mock.MockContext;
import android.view.IWindowManager;
@@ -262,6 +263,7 @@ public class DpmMockContext extends MockContext {
    public final WifiManager wifiManager;
    public final SettingsForMock settings;
    public final MockContentResolver contentResolver;
    public final TelephonyManager telephonyManager;

    /** Note this is a partial mock, not a real mock. */
    public final PackageManager packageManager;
@@ -295,6 +297,7 @@ public class DpmMockContext extends MockContext {
        storageManager = mock(StorageManagerForMock.class);
        wifiManager = mock(WifiManager.class);
        settings = mock(SettingsForMock.class);
        telephonyManager = mock(TelephonyManager.class);

        // Package manager is huge, so we use a partial mock instead.
        packageManager = spy(context.getPackageManager());