From 94a7bda92bb2a30ece3549551ea7b0d610b50542 Mon Sep 17 00:00:00 2001 From: Bryce Lee Date: Fri, 19 May 2023 15:11:04 +0000 Subject: [PATCH] Update DreamManagerService to be aware of user switching. This changelist makes sure dream manager updates any cached settings when the current user is updated. Test: atest DreamManagerServiceMockingTest#testSettingsQueryUserChange Fixes: 282044057 Change-Id: I121cd007d3a44d7da8abf01e639776fa65f2e097 --- .../server/dreams/DreamManagerService.java | 27 ++-- .../DreamManagerServiceMockingTest.java | 120 ++++++++++++++++++ 2 files changed, 135 insertions(+), 12 deletions(-) create mode 100644 services/tests/mockingservicestests/src/com/android/server/dreams/DreamManagerServiceMockingTest.java diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java index d2dcc508d01f8..3fba7eee4bed1 100644 --- a/services/core/java/com/android/server/dreams/DreamManagerService.java +++ b/services/core/java/com/android/server/dreams/DreamManagerService.java @@ -202,9 +202,7 @@ public final class DreamManagerService extends SystemService { @Override public void onChange(boolean selfChange, Uri uri) { - synchronized (mLock) { - updateWhenToDreamSettings(); - } + updateWhenToDreamSettings(); } } @@ -253,15 +251,7 @@ public final class DreamManagerService extends SystemService { if (Build.IS_DEBUGGABLE) { SystemProperties.addChangeCallback(mSystemPropertiesChanged); } - mContext.registerReceiver(new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - writePulseGestureEnabled(); - synchronized (mLock) { - stopDreamLocked(false /*immediate*/, "user switched"); - } - } - }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler); + mContext.getContentResolver().registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.DOZE_DOUBLE_TAP_GESTURE), false, mDozeEnabledObserver, UserHandle.USER_ALL); @@ -299,6 +289,18 @@ public final class DreamManagerService extends SystemService { } } + @Override + public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) { + updateWhenToDreamSettings(); + + mHandler.post(() -> { + writePulseGestureEnabled(); + synchronized (mLock) { + stopDreamLocked(false /*immediate*/, "user switched"); + } + }); + } + private void dumpInternal(PrintWriter pw) { synchronized (mLock) { pw.println("DREAM MANAGER (dumpsys dreams)"); @@ -314,6 +316,7 @@ public final class DreamManagerService extends SystemService { pw.println("mWhenToDream=" + mWhenToDream); pw.println("mKeepDreamingWhenUnpluggingDefault=" + mKeepDreamingWhenUnpluggingDefault); pw.println("getDozeComponent()=" + getDozeComponent()); + pw.println("mDreamOverlayServiceName=" + mDreamOverlayServiceName.flattenToString()); pw.println(); DumpUtils.dumpAsync(mHandler, (pw1, prefix) -> mController.dump(pw1), pw, "", 200); diff --git a/services/tests/mockingservicestests/src/com/android/server/dreams/DreamManagerServiceMockingTest.java b/services/tests/mockingservicestests/src/com/android/server/dreams/DreamManagerServiceMockingTest.java new file mode 100644 index 0000000000000..c02cbd1c9d087 --- /dev/null +++ b/services/tests/mockingservicestests/src/com/android/server/dreams/DreamManagerServiceMockingTest.java @@ -0,0 +1,120 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.dreams; + +import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import android.app.ActivityManagerInternal; +import android.content.ContextWrapper; +import android.content.pm.UserInfo; +import android.content.res.Resources; +import android.os.PowerManagerInternal; +import android.os.UserHandle; +import android.os.UserManager; +import android.provider.Settings; + +import androidx.test.InstrumentationRegistry; + +import com.android.server.LocalServices; +import com.android.server.SystemService; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.MockitoSession; +import org.mockito.quality.Strictness; + +/** + * Collection of tests for exercising the {@link DreamManagerService} lifecycle. + */ +public class DreamManagerServiceMockingTest { + private ContextWrapper mContextSpy; + private Resources mResourcesSpy; + + @Mock + private ActivityManagerInternal mActivityManagerInternalMock; + + @Mock + private PowerManagerInternal mPowerManagerInternalMock; + + @Mock + private UserManager mUserManagerMock; + + private MockitoSession mMockitoSession; + + private static void addLocalServiceMock(Class clazz, T mock) { + LocalServices.removeServiceForTest(clazz); + LocalServices.addService(clazz, mock); + } + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext())); + mResourcesSpy = spy(mContextSpy.getResources()); + when(mContextSpy.getResources()).thenReturn(mResourcesSpy); + + addLocalServiceMock(ActivityManagerInternal.class, mActivityManagerInternalMock); + addLocalServiceMock(PowerManagerInternal.class, mPowerManagerInternalMock); + + when(mContextSpy.getSystemService(UserManager.class)).thenReturn(mUserManagerMock); + mMockitoSession = mockitoSession() + .initMocks(this) + .strictness(Strictness.LENIENT) + .mockStatic(Settings.Secure.class) + .startMocking(); + } + + @After + public void tearDown() throws Exception { + mMockitoSession.finishMocking(); + LocalServices.removeServiceForTest(ActivityManagerInternal.class); + LocalServices.removeServiceForTest(PowerManagerInternal.class); + } + + private DreamManagerService createService() { + return new DreamManagerService(mContextSpy); + } + + @Test + public void testSettingsQueryUserChange() { + final DreamManagerService service = createService(); + + final SystemService.TargetUser from = + new SystemService.TargetUser(mock(UserInfo.class)); + final SystemService.TargetUser to = + new SystemService.TargetUser(mock(UserInfo.class)); + + service.onUserSwitching(from, to); + + verify(() -> Settings.Secure.getIntForUser(any(), + eq(Settings.Secure.SCREENSAVER_ENABLED), + anyInt(), + eq(UserHandle.USER_CURRENT))); + } +}