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

Commit 87de67b6 authored by Tom Natan's avatar Tom Natan Committed by Android (Google) Code Review
Browse files

Merge "[19/n] Letterbox Education: fix multi-user preference key" into tm-dev

parents a22ef255 f94b460f
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ public class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {

    /**
     * The name of the {@link SharedPreferences} that holds which user has seen the Letterbox
     * Education for specific packages and which user has seen the full dialog for any package.
     * Education dialog.
     */
    @VisibleForTesting
    static final String HAS_SEEN_LETTERBOX_EDUCATION_PREF_NAME =
@@ -66,6 +66,13 @@ public class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {

    private final Transitions mTransitions;

    /**
     * The id of the current user, to associate with a boolean in {@link
     * #HAS_SEEN_LETTERBOX_EDUCATION_PREF_NAME}, indicating whether that user has already seen the
     * Letterbox Education dialog.
     */
    private final int mUserId;

    // Remember the last reported state in case visibility changes due to keyguard or IME updates.
    private boolean mEligibleForLetterboxEducation;

@@ -98,6 +105,7 @@ public class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {
        mTransitions = transitions;
        mOnDismissCallback = onDismissCallback;
        mAnimationController = animationController;
        mUserId = taskInfo.userId;
        mEligibleForLetterboxEducation = taskInfo.topActivityEligibleForLetterboxEducation;
        mSharedPreferences = mContext.getSharedPreferences(HAS_SEEN_LETTERBOX_EDUCATION_PREF_NAME,
                Context.MODE_PRIVATE);
@@ -133,7 +141,6 @@ public class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {

    @Override
    protected View createLayout() {
        setSeenLetterboxEducation();
        mLayout = inflateLayout();
        updateDialogMargins();

@@ -177,6 +184,7 @@ public class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {
            // Dialog has already been released.
            return;
        }
        setSeenLetterboxEducation();
        mLayout.setDismissOnClickListener(this::onDismiss);
        // Focus on the dialog title for accessibility.
        mLayout.getDialogTitle().sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
@@ -241,7 +249,7 @@ public class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {
    }

    private String getPrefKey() {
        return String.valueOf(mContext.getUserId());
        return String.valueOf(mUserId);
    }

    @VisibleForTesting
+8 −21
Original line number Diff line number Diff line
@@ -143,9 +143,7 @@ public class CompatUIControllerTest extends ShellTestCase {

        // Verify that the compat controls and letterbox education are updated with new size compat
        // info.
        clearInvocations(mMockCompatLayout);
        clearInvocations(mMockLetterboxEduLayout);
        clearInvocations(mController);
        clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout, mController);
        taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
                CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
        mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
@@ -156,9 +154,7 @@ public class CompatUIControllerTest extends ShellTestCase {
                true);

        // Verify that compat controls and letterbox education are removed with null task listener.
        clearInvocations(mMockCompatLayout);
        clearInvocations(mMockLetterboxEduLayout);
        clearInvocations(mController);
        clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout, mController);
        mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
                /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN),
                /* taskListener= */ null);
@@ -181,9 +177,7 @@ public class CompatUIControllerTest extends ShellTestCase {
                eq(mMockTaskListener));

        // Verify that the layout is created again.
        clearInvocations(mMockCompatLayout);
        clearInvocations(mMockLetterboxEduLayout);
        clearInvocations(mController);
        clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout, mController);
        mController.onCompatInfoChanged(taskInfo, mMockTaskListener);

        verify(mMockCompatLayout, never()).updateCompatInfo(any(), any(), anyBoolean());
@@ -206,9 +200,7 @@ public class CompatUIControllerTest extends ShellTestCase {
        verify(mController).createLetterboxEduWindowManager(any(), eq(taskInfo),
                eq(mMockTaskListener));

        clearInvocations(mMockCompatLayout);
        clearInvocations(mMockLetterboxEduLayout);
        clearInvocations(mController);
        clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout, mController);
        mController.onCompatInfoChanged(taskInfo, mMockTaskListener);

        verify(mMockCompatLayout).updateCompatInfo(taskInfo, mMockTaskListener, /* canShow= */
@@ -217,9 +209,7 @@ public class CompatUIControllerTest extends ShellTestCase {
                true);

        // Verify that the layout is created again.
        clearInvocations(mMockCompatLayout);
        clearInvocations(mMockLetterboxEduLayout);
        clearInvocations(mController);
        clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout, mController);
        mController.onCompatInfoChanged(taskInfo, mMockTaskListener);

        verify(mMockCompatLayout, never()).updateCompatInfo(any(), any(), anyBoolean());
@@ -294,8 +284,7 @@ public class CompatUIControllerTest extends ShellTestCase {
        verify(mMockLetterboxEduLayout).updateDisplayLayout(mMockDisplayLayout);

        // No update if the insets state is the same.
        clearInvocations(mMockCompatLayout);
        clearInvocations(mMockLetterboxEduLayout);
        clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout);
        mOnInsetsChangedListenerCaptor.getValue().insetsChanged(new InsetsState(insetsState));
        verify(mMockCompatLayout, never()).updateDisplayLayout(mMockDisplayLayout);
        verify(mMockLetterboxEduLayout, never()).updateDisplayLayout(mMockDisplayLayout);
@@ -368,8 +357,7 @@ public class CompatUIControllerTest extends ShellTestCase {
        verify(mMockCompatLayout, times(2)).updateVisibility(false);
        verify(mMockLetterboxEduLayout, times(2)).updateVisibility(false);

        clearInvocations(mMockCompatLayout);
        clearInvocations(mMockLetterboxEduLayout);
        clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout);

        // Verify button remains hidden after keyguard becomes not showing since IME is showing.
        mController.onKeyguardShowingChanged(false);
@@ -395,8 +383,7 @@ public class CompatUIControllerTest extends ShellTestCase {
        verify(mMockCompatLayout, times(2)).updateVisibility(false);
        verify(mMockLetterboxEduLayout, times(2)).updateVisibility(false);

        clearInvocations(mMockCompatLayout);
        clearInvocations(mMockLetterboxEduLayout);
        clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout);

        // Verify button remains hidden after IME is hidden since keyguard is showing.
        mController.onImeVisibilityChanged(DISPLAY_ID, /* isShowing= */ false);
+73 −30
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -75,6 +76,12 @@ import org.mockito.MockitoAnnotations;
@SmallTest
public class LetterboxEduWindowManagerTest extends ShellTestCase {

    private static final int USER_ID_1 = 1;
    private static final int USER_ID_2 = 2;

    private static final String PREF_KEY_1 = String.valueOf(USER_ID_1);
    private static final String PREF_KEY_2 = String.valueOf(USER_ID_2);

    private static final int TASK_ID = 1;

    private static final int TASK_WIDTH = 200;
@@ -98,9 +105,10 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
    @Mock private Runnable mOnDismissCallback;

    private SharedPreferences mSharedPreferences;
    private String mPrefKey;
    @Nullable
    private Boolean mInitialPrefValue = null;
    private Boolean mInitialPrefValue1 = null;
    @Nullable
    private Boolean mInitialPrefValue2 = null;

    @Before
    public void setUp() {
@@ -109,20 +117,28 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
        mSharedPreferences = mContext.getSharedPreferences(
                LetterboxEduWindowManager.HAS_SEEN_LETTERBOX_EDUCATION_PREF_NAME,
                Context.MODE_PRIVATE);
        mPrefKey = String.valueOf(mContext.getUserId());
        if (mSharedPreferences.contains(mPrefKey)) {
            mInitialPrefValue = mSharedPreferences.getBoolean(mPrefKey, /* default= */ false);
            mSharedPreferences.edit().remove(mPrefKey).apply();
        if (mSharedPreferences.contains(PREF_KEY_1)) {
            mInitialPrefValue1 = mSharedPreferences.getBoolean(PREF_KEY_1, /* default= */ false);
            mSharedPreferences.edit().remove(PREF_KEY_1).apply();
        }
        if (mSharedPreferences.contains(PREF_KEY_2)) {
            mInitialPrefValue2 = mSharedPreferences.getBoolean(PREF_KEY_2, /* default= */ false);
            mSharedPreferences.edit().remove(PREF_KEY_2).apply();
        }
    }

    @After
    public void tearDown() {
        SharedPreferences.Editor editor = mSharedPreferences.edit();
        if (mInitialPrefValue == null) {
            editor.remove(mPrefKey);
        if (mInitialPrefValue1 == null) {
            editor.remove(PREF_KEY_1);
        } else {
            editor.putBoolean(mPrefKey, mInitialPrefValue);
            editor.putBoolean(PREF_KEY_1, mInitialPrefValue1);
        }
        if (mInitialPrefValue2 == null) {
            editor.remove(PREF_KEY_2);
        } else {
            editor.putBoolean(PREF_KEY_2, mInitialPrefValue2);
        }
        editor.apply();
    }
@@ -136,20 +152,10 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
        assertNull(windowManager.mLayout);
    }

    @Test
    public void testCreateLayout_alreadyShownToUser_doesNotCreateLayout() {
        LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
        mSharedPreferences.edit().putBoolean(mPrefKey, true).apply();

        assertFalse(windowManager.createLayout(/* canShow= */ true));

        assertNull(windowManager.mLayout);
    }

    @Test
    public void testCreateLayout_taskBarEducationIsShowing_doesNotCreateLayout() {
        LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */
                true, /* isTaskbarEduShowing= */ true);
                true, USER_ID_1, /* isTaskbarEduShowing= */ true);

        assertFalse(windowManager.createLayout(/* canShow= */ true));

@@ -162,7 +168,7 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {

        assertTrue(windowManager.createLayout(/* canShow= */ false));

        assertFalse(mSharedPreferences.getBoolean(mPrefKey, /* default= */ false));
        assertFalse(mSharedPreferences.getBoolean(PREF_KEY_1, /* default= */ false));
        assertNull(windowManager.mLayout);
    }

@@ -172,7 +178,6 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {

        assertTrue(windowManager.createLayout(/* canShow= */ true));

        assertTrue(mSharedPreferences.getBoolean(mPrefKey, /* default= */ false));
        LetterboxEduDialogLayout layout = windowManager.mLayout;
        assertNotNull(layout);
        verify(mViewHost).setView(eq(layout), mWindowAttrsCaptor.capture());
@@ -183,6 +188,8 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
        assertNotNull(dialogTitle);
        spyOn(dialogTitle);

        // The education shouldn't be marked as seen until enter animation is done.
        assertFalse(mSharedPreferences.getBoolean(PREF_KEY_1, /* default= */ false));
        // Clicking the layout does nothing until enter animation is done.
        layout.performClick();
        verify(mAnimationController, never()).startExitAnimation(any(), any());
@@ -191,6 +198,7 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {

        verifyAndFinishEnterAnimation(layout);

        assertTrue(mSharedPreferences.getBoolean(PREF_KEY_1, /* default= */ false));
        verify(dialogTitle).sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
        // Exit animation should start following a click on the layout.
        layout.performClick();
@@ -207,13 +215,42 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
        verify(mOnDismissCallback).run();
    }

    @Test
    public void testCreateLayout_alreadyShownToUser_createsLayoutForOtherUserOnly() {
        LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true,
                USER_ID_1, /* isTaskbarEduShowing= */ false);

        assertTrue(windowManager.createLayout(/* canShow= */ true));

        assertNotNull(windowManager.mLayout);
        verifyAndFinishEnterAnimation(windowManager.mLayout);
        assertTrue(mSharedPreferences.getBoolean(PREF_KEY_1, /* default= */ false));

        windowManager.release();
        windowManager = createWindowManager(/* eligible= */ true,
                USER_ID_1, /* isTaskbarEduShowing= */ false);

        assertFalse(windowManager.createLayout(/* canShow= */ true));
        assertNull(windowManager.mLayout);

        clearInvocations(mTransitions, mAnimationController);

        windowManager = createWindowManager(/* eligible= */ true,
                USER_ID_2, /* isTaskbarEduShowing= */ false);

        assertTrue(windowManager.createLayout(/* canShow= */ true));

        assertNotNull(windowManager.mLayout);
        verifyAndFinishEnterAnimation(windowManager.mLayout);
        assertTrue(mSharedPreferences.getBoolean(PREF_KEY_1, /* default= */ false));
    }

    @Test
    public void testCreateLayout_windowManagerReleasedBeforeTransitionsIsIdle_doesNotStartAnim() {
        LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);

        assertTrue(windowManager.createLayout(/* canShow= */ true));

        assertTrue(mSharedPreferences.getBoolean(mPrefKey, /* default= */ false));
        assertNotNull(windowManager.mLayout);

        verify(mTransitions).runOnIdle(mRunOnIdleCaptor.capture());

@@ -222,6 +259,7 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
        mRunOnIdleCaptor.getValue().run();

        verify(mAnimationController, never()).startEnterAnimation(any(), any());
        assertFalse(mSharedPreferences.getBoolean(PREF_KEY_1, /* default= */ false));
    }

    @Test
@@ -233,7 +271,7 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
        assertNotNull(layout);

        assertTrue(windowManager.updateCompatInfo(
                createTaskInfo(/* eligible= */ true, new Rect(50, 25, 150, 75)),
                createTaskInfo(/* eligible= */ true, USER_ID_1, new Rect(50, 25, 150, 75)),
                mTaskListener, /* canShow= */ true));

        verifyLayout(layout, layout.getLayoutParams(), /* expectedWidth= */ 100,
@@ -341,13 +379,13 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
    }

    private LetterboxEduWindowManager createWindowManager(boolean eligible) {
        return createWindowManager(eligible, /* isTaskbarEduShowing= */ false);
        return createWindowManager(eligible, USER_ID_1, /* isTaskbarEduShowing= */ false);
    }

    private LetterboxEduWindowManager createWindowManager(boolean eligible,
            boolean isTaskbarEduShowing) {
            int userId, boolean isTaskbarEduShowing) {
        LetterboxEduWindowManager windowManager = new LetterboxEduWindowManager(mContext,
                createTaskInfo(eligible), mSyncTransactionQueue, mTaskListener,
                createTaskInfo(eligible, userId), mSyncTransactionQueue, mTaskListener,
                createDisplayLayout(), mTransitions, mOnDismissCallback,
                mAnimationController);

@@ -375,11 +413,16 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
    }

    private static TaskInfo createTaskInfo(boolean eligible) {
        return createTaskInfo(eligible, new Rect(0, 0, TASK_WIDTH, TASK_HEIGHT));
        return createTaskInfo(eligible, USER_ID_1);
    }

    private static TaskInfo createTaskInfo(boolean eligible, int userId) {
        return createTaskInfo(eligible, userId, new Rect(0, 0, TASK_WIDTH, TASK_HEIGHT));
    }

    private static TaskInfo createTaskInfo(boolean eligible, Rect bounds) {
    private static TaskInfo createTaskInfo(boolean eligible, int userId, Rect bounds) {
        ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
        taskInfo.userId = userId;
        taskInfo.taskId = TASK_ID;
        taskInfo.topActivityEligibleForLetterboxEducation = eligible;
        taskInfo.configuration.windowConfiguration.setBounds(bounds);