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

Commit f6eead18 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Cleanup up device-specific settings on virtual device removal" into main

parents 1dd1b577 f735c7b1
Loading
Loading
Loading
Loading
+45 −1
Original line number Diff line number Diff line
@@ -395,6 +395,9 @@ public class SettingsProvider extends ContentProvider {

    private PackageMonitor mPackageMonitor;

    @GuardedBy("mLock")
    private VirtualDeviceManager.VirtualDeviceListener mVirtualDeviceListener;

    @GuardedBy("mLock")
    private boolean mSyncConfigDisabledUntilReboot;

@@ -3192,9 +3195,50 @@ public class SettingsProvider extends ContentProvider {
    }

    private int getDeviceId() {
        return android.companion.virtualdevice.flags.Flags.deviceAwareSettingsOverride()
        int deviceId = android.companion.virtualdevice.flags.Flags.deviceAwareSettingsOverride()
                && canUidAccessDeviceAwareSettings(Binder.getCallingUid())
                ? getCallingDeviceId() : Context.DEVICE_ID_DEFAULT;
        if (deviceId != Context.DEVICE_ID_DEFAULT) {
            // We have received a call for a non-default device id, so now would be a good time
            // to initialize a virtual device listener.
            initVirtualDeviceListener();
        }
        return deviceId;
    }

    private void initVirtualDeviceListener() {
        synchronized (mLock) {
            // We already have a listener, just return.
            if (mVirtualDeviceListener != null) {
                return;
            }
        }

        VirtualDeviceManager virtualDeviceManager =
                getContext().getSystemService(VirtualDeviceManager.class);
        if (virtualDeviceManager == null) {
            return;
        }

        VirtualDeviceManager.VirtualDeviceListener listener;
        synchronized (mLock) {
            mVirtualDeviceListener = new VirtualDeviceManager.VirtualDeviceListener() {
                @Override
                public void onVirtualDeviceClosed(int deviceId) {
                    // Clean up any device-specific settings when a virtual device is closed.
                    List<UserInfo> userInfos = mUserManager.getAliveUsers();
                    for (UserInfo userInfo : userInfos) {
                        synchronized (mLock) {
                            mSettingsRegistry.removeUserAndDeviceStateLocked(
                                    userInfo.id, deviceId, true /* permanently */);
                        }
                    }
                }
            };
            listener = mVirtualDeviceListener;
        }
        virtualDeviceManager.registerVirtualDeviceListener(
                mHandlerThread.getThreadExecutor(), listener);
    }

    private List<Integer> getDeviceIds() {
+2 −1
Original line number Diff line number Diff line
@@ -315,7 +315,8 @@ abstract class BaseSettingsProviderTest {
            }
        }
        // Remove trailing line breaks from the output.
        return new String(result, StandardCharsets.UTF_8).replaceAll("\n", "");
        String resultStr = new String(result, StandardCharsets.UTF_8).replaceAll("\n", "");
        return "null".equals(resultStr) ? null : resultStr;
    }

    protected static void setSettingViaShell(int type, String name, String value,
+68 −13
Original line number Diff line number Diff line
@@ -190,6 +190,42 @@ public class SettingsProviderTest extends BaseSettingsProviderTest {
        performSetAndGetSettingTestViaProviderApi(SETTING_TYPE_SYSTEM);
    }

    @Test
    @RequiresFlagsEnabled(Flags.FLAG_DEVICE_AWARE_SETTINGS_OVERRIDE)
    public void testSystemSettingClearedOnVirtualDeviceRemovalForSystemUser() throws Exception {
        verifySettingsClearedOnVirtualDeviceRemoval(SETTING_TYPE_SYSTEM, UserHandle.USER_SYSTEM);
    }

    @Test
    @RequiresFlagsEnabled(Flags.FLAG_DEVICE_AWARE_SETTINGS_OVERRIDE)
    public void testSecureSettingClearedOnVirtualDeviceRemovalForSystemUser() throws Exception {
        verifySettingsClearedOnVirtualDeviceRemoval(SETTING_TYPE_SECURE, UserHandle.USER_SYSTEM);
    }

    @Test
    @RequiresFlagsEnabled(Flags.FLAG_DEVICE_AWARE_SETTINGS_OVERRIDE)
    public void testSystemSettingClearedOnVirtualDeviceRemovalForNonSystemUser() throws Exception {
        final int secondaryUserId = getSecondaryUserId();
        if (secondaryUserId == UserHandle.USER_SYSTEM) {
            Log.w(LOG_TAG, "No secondary user. Skipping "
                    + "testSystemSettingClearedOnVirtualDeviceRemovalForNonSystemUser");
            return;
        }
        verifySettingsClearedOnVirtualDeviceRemoval(SETTING_TYPE_SYSTEM, secondaryUserId);
    }

    @Test
    @RequiresFlagsEnabled(Flags.FLAG_DEVICE_AWARE_SETTINGS_OVERRIDE)
    public void testSecureSettingClearedOnVirtualDeviceRemovalForNonSystemUser() throws Exception {
        final int secondaryUserId = getSecondaryUserId();
        if (secondaryUserId == UserHandle.USER_SYSTEM) {
            Log.w(LOG_TAG, "No secondary user. Skipping "
                    + "testSecureSettingClearedOnVirtualDeviceRemovalForNonSystemUser");
            return;
        }
        verifySettingsClearedOnVirtualDeviceRemoval(SETTING_TYPE_SECURE, secondaryUserId);
    }

    @Test
    public void testSelectAllGlobalViaProviderApi() throws Exception {
        setSettingViaProviderApiAndAssertSuccessfulChange(SETTING_TYPE_GLOBAL,
@@ -674,19 +710,8 @@ public class SettingsProviderTest extends BaseSettingsProviderTest {
    private void performSetAndGetSettingTestViaShell(int type, int userId, int deviceId)
            throws Exception {
        try {
            // Change the setting and assert a successful change.
            setSettingAndAssertSuccessfulChange(
                    () -> {
                        try {
                            setSettingViaShell(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE, userId,
                                    deviceId);
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    },
                    BaseSettingsProviderTest::getSettingViaShell, type, FAKE_SETTING_NAME,
                    FAKE_SETTING_VALUE, userId,
                    deviceId);
            setSettingViaShellAndAssertSuccessfulChange(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE,
                    userId, deviceId);
        } finally {
            // Remove the setting.
            setSettingViaShell(type, FAKE_SETTING_NAME, null /* value */, userId, deviceId);
@@ -735,6 +760,22 @@ public class SettingsProviderTest extends BaseSettingsProviderTest {
        }
    }

    private void verifySettingsClearedOnVirtualDeviceRemoval(int type, int userId)
            throws Exception {
        VirtualDeviceManager.VirtualDevice virtualDevice = mRule.createManagedVirtualDevice();
        int deviceId = virtualDevice.getDeviceId();
        // Change the setting and assert a successful change.
        setSettingViaShellAndAssertSuccessfulChange(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE,
                userId, deviceId);

        virtualDevice.close();

        // Wait for settings cleanup in SettingsProvider.
        SystemClock.sleep(2000L);
        String value = getSettingViaShell(type, FAKE_SETTING_NAME, userId, deviceId);
        assertNull(value);
    }

    private void setSettingViaFrontEndApiAndAssertSuccessfulChange(final int type,
            final String name, final String value, final int userId) {
        setSettingAndAssertSuccessfulChangeViaFrontEndApi(() ->
@@ -750,6 +791,20 @@ public class SettingsProviderTest extends BaseSettingsProviderTest {
                name, value, getContext().getUserId());
    }

    private void setSettingViaShellAndAssertSuccessfulChange(final int type, final String name,
            final String value, final int userId, final int deviceId) {
        setSettingAndAssertSuccessfulChange(
                () -> {
                    try {
                        setSettingViaShell(type, name, value, userId, deviceId);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                },
                BaseSettingsProviderTest::getSettingViaShell, type, name, value, userId,
                deviceId);
    }

    private void setSettingAndAssertSuccessfulChangeViaFrontEndApi(Runnable setCommand,
            final int type, final String name, final String value, final int userId) {
        setSettingAndAssertSuccessfulChange(setCommand,