Merge "LetterboxEdu not visible when device is docked" into tm-qpr-dev

This commit is contained in:
Massimo Carli
2022-10-05 08:12:39 +00:00
committed by Android (Google) Code Review
6 changed files with 107 additions and 12 deletions

View File

@@ -0,0 +1,57 @@
/*
* Copyright (C) 2022 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.wm.shell.common;
import static android.content.Intent.EXTRA_DOCK_STATE;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import com.android.wm.shell.dagger.WMSingleton;
import javax.inject.Inject;
/**
* Provides information about the docked state of the device.
*/
@WMSingleton
public class DockStateReader {
private static final IntentFilter DOCK_INTENT_FILTER = new IntentFilter(
Intent.ACTION_DOCK_EVENT);
private final Context mContext;
@Inject
public DockStateReader(Context context) {
mContext = context;
}
/**
* @return True if the device is docked and false otherwise.
*/
public boolean isDocked() {
Intent dockStatus = mContext.registerReceiver(/* receiver */ null, DOCK_INTENT_FILTER);
if (dockStatus != null) {
int dockState = dockStatus.getIntExtra(EXTRA_DOCK_STATE,
Intent.EXTRA_DOCK_STATE_UNDOCKED);
return dockState != Intent.EXTRA_DOCK_STATE_UNDOCKED;
}
return false;
}
}

View File

@@ -37,6 +37,7 @@ import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.DisplayInsetsController.OnInsetsChangedListener; import com.android.wm.shell.common.DisplayInsetsController.OnInsetsChangedListener;
import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.DockStateReader;
import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.compatui.CompatUIWindowManager.CompatUIHintsState; import com.android.wm.shell.compatui.CompatUIWindowManager.CompatUIHintsState;
@@ -109,6 +110,7 @@ public class CompatUIController implements OnDisplaysChangedListener,
private final SyncTransactionQueue mSyncQueue; private final SyncTransactionQueue mSyncQueue;
private final ShellExecutor mMainExecutor; private final ShellExecutor mMainExecutor;
private final Lazy<Transitions> mTransitionsLazy; private final Lazy<Transitions> mTransitionsLazy;
private final DockStateReader mDockStateReader;
private CompatUICallback mCallback; private CompatUICallback mCallback;
@@ -127,7 +129,8 @@ public class CompatUIController implements OnDisplaysChangedListener,
DisplayImeController imeController, DisplayImeController imeController,
SyncTransactionQueue syncQueue, SyncTransactionQueue syncQueue,
ShellExecutor mainExecutor, ShellExecutor mainExecutor,
Lazy<Transitions> transitionsLazy) { Lazy<Transitions> transitionsLazy,
DockStateReader dockStateReader) {
mContext = context; mContext = context;
mShellController = shellController; mShellController = shellController;
mDisplayController = displayController; mDisplayController = displayController;
@@ -138,6 +141,7 @@ public class CompatUIController implements OnDisplaysChangedListener,
mTransitionsLazy = transitionsLazy; mTransitionsLazy = transitionsLazy;
mCompatUIHintsState = new CompatUIHintsState(); mCompatUIHintsState = new CompatUIHintsState();
shellInit.addInitCallback(this::onInit, this); shellInit.addInitCallback(this::onInit, this);
mDockStateReader = dockStateReader;
} }
private void onInit() { private void onInit() {
@@ -315,7 +319,8 @@ public class CompatUIController implements OnDisplaysChangedListener,
return new LetterboxEduWindowManager(context, taskInfo, return new LetterboxEduWindowManager(context, taskInfo,
mSyncQueue, taskListener, mDisplayController.getDisplayLayout(taskInfo.displayId), mSyncQueue, taskListener, mDisplayController.getDisplayLayout(taskInfo.displayId),
mTransitionsLazy.get(), mTransitionsLazy.get(),
this::onLetterboxEduDismissed); this::onLetterboxEduDismissed,
mDockStateReader);
} }
private void onLetterboxEduDismissed() { private void onLetterboxEduDismissed() {

View File

@@ -34,6 +34,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.wm.shell.R; import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.DockStateReader;
import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.compatui.CompatUIWindowManagerAbstract; import com.android.wm.shell.compatui.CompatUIWindowManagerAbstract;
import com.android.wm.shell.transition.Transitions; import com.android.wm.shell.transition.Transitions;
@@ -88,19 +89,21 @@ public class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {
*/ */
private final int mDialogVerticalMargin; private final int mDialogVerticalMargin;
private final DockStateReader mDockStateReader;
public LetterboxEduWindowManager(Context context, TaskInfo taskInfo, public LetterboxEduWindowManager(Context context, TaskInfo taskInfo,
SyncTransactionQueue syncQueue, ShellTaskOrganizer.TaskListener taskListener, SyncTransactionQueue syncQueue, ShellTaskOrganizer.TaskListener taskListener,
DisplayLayout displayLayout, Transitions transitions, DisplayLayout displayLayout, Transitions transitions,
Runnable onDismissCallback) { Runnable onDismissCallback, DockStateReader dockStateReader) {
this(context, taskInfo, syncQueue, taskListener, displayLayout, transitions, this(context, taskInfo, syncQueue, taskListener, displayLayout, transitions,
onDismissCallback, new LetterboxEduAnimationController(context)); onDismissCallback, new LetterboxEduAnimationController(context), dockStateReader);
} }
@VisibleForTesting @VisibleForTesting
LetterboxEduWindowManager(Context context, TaskInfo taskInfo, LetterboxEduWindowManager(Context context, TaskInfo taskInfo,
SyncTransactionQueue syncQueue, ShellTaskOrganizer.TaskListener taskListener, SyncTransactionQueue syncQueue, ShellTaskOrganizer.TaskListener taskListener,
DisplayLayout displayLayout, Transitions transitions, Runnable onDismissCallback, DisplayLayout displayLayout, Transitions transitions, Runnable onDismissCallback,
LetterboxEduAnimationController animationController) { LetterboxEduAnimationController animationController, DockStateReader dockStateReader) {
super(context, taskInfo, syncQueue, taskListener, displayLayout); super(context, taskInfo, syncQueue, taskListener, displayLayout);
mTransitions = transitions; mTransitions = transitions;
mOnDismissCallback = onDismissCallback; mOnDismissCallback = onDismissCallback;
@@ -111,6 +114,7 @@ public class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {
Context.MODE_PRIVATE); Context.MODE_PRIVATE);
mDialogVerticalMargin = (int) mContext.getResources().getDimension( mDialogVerticalMargin = (int) mContext.getResources().getDimension(
R.dimen.letterbox_education_dialog_margin); R.dimen.letterbox_education_dialog_margin);
mDockStateReader = dockStateReader;
} }
@Override @Override
@@ -130,13 +134,15 @@ public class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {
@Override @Override
protected boolean eligibleToShowLayout() { protected boolean eligibleToShowLayout() {
// - The letterbox education should not be visible if the device is docked.
// - If taskbar education is showing, the letterbox education shouldn't be shown for the // - If taskbar education is showing, the letterbox education shouldn't be shown for the
// given task until the taskbar education is dismissed and the compat info changes (then // given task until the taskbar education is dismissed and the compat info changes (then
// the controller will create a new instance of this class since this one isn't eligible). // the controller will create a new instance of this class since this one isn't eligible).
// - If the layout isn't null then it was previously showing, and we shouldn't check if the // - If the layout isn't null then it was previously showing, and we shouldn't check if the
// user has seen the letterbox education before. // user has seen the letterbox education before.
return mEligibleForLetterboxEducation && !isTaskbarEduShowing() && (mLayout != null return mEligibleForLetterboxEducation && !isTaskbarEduShowing()
|| !getHasSeenLetterboxEducation()); && (mLayout != null || !getHasSeenLetterboxEducation())
&& !mDockStateReader.isDocked();
} }
@Override @Override

View File

@@ -46,6 +46,7 @@ import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.DockStateReader;
import com.android.wm.shell.common.FloatingContentCoordinator; import com.android.wm.shell.common.FloatingContentCoordinator;
import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SyncTransactionQueue;
@@ -196,9 +197,11 @@ public abstract class WMShellBaseModule {
ShellController shellController, ShellController shellController,
DisplayController displayController, DisplayInsetsController displayInsetsController, DisplayController displayController, DisplayInsetsController displayInsetsController,
DisplayImeController imeController, SyncTransactionQueue syncQueue, DisplayImeController imeController, SyncTransactionQueue syncQueue,
@ShellMainThread ShellExecutor mainExecutor, Lazy<Transitions> transitionsLazy) { @ShellMainThread ShellExecutor mainExecutor, Lazy<Transitions> transitionsLazy,
DockStateReader dockStateReader) {
return new CompatUIController(context, shellInit, shellController, displayController, return new CompatUIController(context, shellInit, shellController, displayController,
displayInsetsController, imeController, syncQueue, mainExecutor, transitionsLazy); displayInsetsController, imeController, syncQueue, mainExecutor, transitionsLazy,
dockStateReader);
} }
@WMSingleton @WMSingleton

View File

@@ -51,6 +51,7 @@ import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.DisplayInsetsController.OnInsetsChangedListener; import com.android.wm.shell.common.DisplayInsetsController.OnInsetsChangedListener;
import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.DockStateReader;
import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.compatui.letterboxedu.LetterboxEduWindowManager; import com.android.wm.shell.compatui.letterboxedu.LetterboxEduWindowManager;
@@ -93,6 +94,7 @@ public class CompatUIControllerTest extends ShellTestCase {
private @Mock Lazy<Transitions> mMockTransitionsLazy; private @Mock Lazy<Transitions> mMockTransitionsLazy;
private @Mock CompatUIWindowManager mMockCompatLayout; private @Mock CompatUIWindowManager mMockCompatLayout;
private @Mock LetterboxEduWindowManager mMockLetterboxEduLayout; private @Mock LetterboxEduWindowManager mMockLetterboxEduLayout;
private @Mock DockStateReader mDockStateReader;
@Captor @Captor
ArgumentCaptor<OnInsetsChangedListener> mOnInsetsChangedListenerCaptor; ArgumentCaptor<OnInsetsChangedListener> mOnInsetsChangedListenerCaptor;
@@ -113,7 +115,7 @@ public class CompatUIControllerTest extends ShellTestCase {
mShellInit = spy(new ShellInit(mMockExecutor)); mShellInit = spy(new ShellInit(mMockExecutor));
mController = new CompatUIController(mContext, mShellInit, mMockShellController, mController = new CompatUIController(mContext, mShellInit, mMockShellController,
mMockDisplayController, mMockDisplayInsetsController, mMockImeController, mMockDisplayController, mMockDisplayInsetsController, mMockImeController,
mMockSyncQueue, mMockExecutor, mMockTransitionsLazy) { mMockSyncQueue, mMockExecutor, mMockTransitionsLazy, mDockStateReader) {
@Override @Override
CompatUIWindowManager createCompatUiWindowManager(Context context, TaskInfo taskInfo, CompatUIWindowManager createCompatUiWindowManager(Context context, TaskInfo taskInfo,
ShellTaskOrganizer.TaskListener taskListener) { ShellTaskOrganizer.TaskListener taskListener) {

View File

@@ -54,6 +54,7 @@ import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.DockStateReader;
import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.transition.Transitions; import com.android.wm.shell.transition.Transitions;
@@ -103,6 +104,7 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
@Mock private SurfaceControlViewHost mViewHost; @Mock private SurfaceControlViewHost mViewHost;
@Mock private Transitions mTransitions; @Mock private Transitions mTransitions;
@Mock private Runnable mOnDismissCallback; @Mock private Runnable mOnDismissCallback;
@Mock private DockStateReader mDockStateReader;
private SharedPreferences mSharedPreferences; private SharedPreferences mSharedPreferences;
@Nullable @Nullable
@@ -152,6 +154,16 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
assertNull(windowManager.mLayout); assertNull(windowManager.mLayout);
} }
@Test
public void testCreateLayout_eligibleAndDocked_doesNotCreateLayout() {
LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */
true, /* isDocked */ true);
assertFalse(windowManager.createLayout(/* canShow= */ true));
assertNull(windowManager.mLayout);
}
@Test @Test
public void testCreateLayout_taskBarEducationIsShowing_doesNotCreateLayout() { public void testCreateLayout_taskBarEducationIsShowing_doesNotCreateLayout() {
LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */
@@ -382,17 +394,27 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
return createWindowManager(eligible, USER_ID_1, /* isTaskbarEduShowing= */ false); return createWindowManager(eligible, USER_ID_1, /* isTaskbarEduShowing= */ false);
} }
private LetterboxEduWindowManager createWindowManager(boolean eligible, boolean isDocked) {
return createWindowManager(eligible, USER_ID_1, /* isTaskbarEduShowing= */
false, isDocked);
}
private LetterboxEduWindowManager createWindowManager(boolean eligible, private LetterboxEduWindowManager createWindowManager(boolean eligible,
int userId, boolean isTaskbarEduShowing) { int userId, boolean isTaskbarEduShowing) {
return createWindowManager(eligible, userId, isTaskbarEduShowing, /* isDocked */false);
}
private LetterboxEduWindowManager createWindowManager(boolean eligible,
int userId, boolean isTaskbarEduShowing, boolean isDocked) {
doReturn(isDocked).when(mDockStateReader).isDocked();
LetterboxEduWindowManager windowManager = new LetterboxEduWindowManager(mContext, LetterboxEduWindowManager windowManager = new LetterboxEduWindowManager(mContext,
createTaskInfo(eligible, userId), mSyncTransactionQueue, mTaskListener, createTaskInfo(eligible, userId), mSyncTransactionQueue, mTaskListener,
createDisplayLayout(), mTransitions, mOnDismissCallback, createDisplayLayout(), mTransitions, mOnDismissCallback,
mAnimationController); mAnimationController, mDockStateReader);
spyOn(windowManager); spyOn(windowManager);
doReturn(mViewHost).when(windowManager).createSurfaceViewHost(); doReturn(mViewHost).when(windowManager).createSurfaceViewHost();
doReturn(isTaskbarEduShowing).when(windowManager).isTaskbarEduShowing(); doReturn(isTaskbarEduShowing).when(windowManager).isTaskbarEduShowing();
return windowManager; return windowManager;
} }