Merge "Remove all size compat UIs when the keyguard becomes occluded" into sc-v2-dev am: 1bbc9f6355

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16212776

Change-Id: Ib3c178b3484c9df0b6aeac1e2b497209bb3c7839
This commit is contained in:
Tom Natan
2021-11-18 19:32:23 +00:00
committed by Automerger Merge Worker
11 changed files with 252 additions and 55 deletions

View File

@@ -74,6 +74,7 @@ import com.android.wm.shell.pip.phone.PipAppOpsListener;
import com.android.wm.shell.pip.phone.PipTouchHandler; import com.android.wm.shell.pip.phone.PipTouchHandler;
import com.android.wm.shell.recents.RecentTasks; import com.android.wm.shell.recents.RecentTasks;
import com.android.wm.shell.recents.RecentTasksController; import com.android.wm.shell.recents.RecentTasksController;
import com.android.wm.shell.sizecompatui.SizeCompatUI;
import com.android.wm.shell.sizecompatui.SizeCompatUIController; import com.android.wm.shell.sizecompatui.SizeCompatUIController;
import com.android.wm.shell.splitscreen.SplitScreen; import com.android.wm.shell.splitscreen.SplitScreen;
import com.android.wm.shell.splitscreen.SplitScreenController; import com.android.wm.shell.splitscreen.SplitScreenController;
@@ -169,13 +170,20 @@ public abstract class WMShellBaseModule {
return new ShellTaskOrganizer(mainExecutor, context, sizeCompatUI, recentTasksOptional); return new ShellTaskOrganizer(mainExecutor, context, sizeCompatUI, recentTasksOptional);
} }
@WMSingleton
@Provides
static SizeCompatUI provideSizeCompatUI(SizeCompatUIController sizeCompatUIController) {
return sizeCompatUIController.asSizeCompatUI();
}
@WMSingleton @WMSingleton
@Provides @Provides
static SizeCompatUIController provideSizeCompatUIController(Context context, static SizeCompatUIController provideSizeCompatUIController(Context context,
DisplayController displayController, DisplayInsetsController displayInsetsController, DisplayController displayController, DisplayInsetsController displayInsetsController,
DisplayImeController imeController, SyncTransactionQueue syncQueue) { DisplayImeController imeController, SyncTransactionQueue syncQueue,
@ShellMainThread ShellExecutor mainExecutor) {
return new SizeCompatUIController(context, displayController, displayInsetsController, return new SizeCompatUIController(context, displayController, displayInsetsController,
imeController, syncQueue); imeController, syncQueue, mainExecutor);
} }
@WMSingleton @WMSingleton

View File

@@ -0,0 +1,32 @@
/*
* Copyright (C) 2021 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.sizecompatui;
import com.android.wm.shell.common.annotations.ExternalThread;
/**
* Interface to engage size compat UI.
*/
@ExternalThread
public interface SizeCompatUI {
/**
* Called when the keyguard occluded state changes. Removes all size compat UIs if the
* keyguard is now occluded.
* @param occluded indicates if the keyguard is now occluded.
*/
void onKeyguardOccludedChanged(boolean occluded);
}

View File

@@ -35,13 +35,16 @@ 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.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.annotations.ExternalThread;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Predicate;
/** /**
* Controls to show/update restart-activity buttons on Tasks based on whether the foreground * Controls to show/update restart-activity buttons on Tasks based on whether the foreground
@@ -78,26 +81,37 @@ public class SizeCompatUIController implements OnDisplaysChangedListener,
private final DisplayInsetsController mDisplayInsetsController; private final DisplayInsetsController mDisplayInsetsController;
private final DisplayImeController mImeController; private final DisplayImeController mImeController;
private final SyncTransactionQueue mSyncQueue; private final SyncTransactionQueue mSyncQueue;
private final ShellExecutor mMainExecutor;
private final SizeCompatUIImpl mImpl = new SizeCompatUIImpl();
private SizeCompatUICallback mCallback; private SizeCompatUICallback mCallback;
/** Only show once automatically in the process life. */ /** Only show once automatically in the process life. */
private boolean mHasShownHint; private boolean mHasShownHint;
/** Indicates if the keyguard is currently occluded, in which case size compat UIs shouldn't
* be shown. */
private boolean mKeyguardOccluded;
public SizeCompatUIController(Context context, public SizeCompatUIController(Context context,
DisplayController displayController, DisplayController displayController,
DisplayInsetsController displayInsetsController, DisplayInsetsController displayInsetsController,
DisplayImeController imeController, DisplayImeController imeController,
SyncTransactionQueue syncQueue) { SyncTransactionQueue syncQueue,
ShellExecutor mainExecutor) {
mContext = context; mContext = context;
mDisplayController = displayController; mDisplayController = displayController;
mDisplayInsetsController = displayInsetsController; mDisplayInsetsController = displayInsetsController;
mImeController = imeController; mImeController = imeController;
mSyncQueue = syncQueue; mSyncQueue = syncQueue;
mMainExecutor = mainExecutor;
mDisplayController.addDisplayWindowListener(this); mDisplayController.addDisplayWindowListener(this);
mImeController.addPositionProcessor(this); mImeController.addPositionProcessor(this);
} }
public SizeCompatUI asSizeCompatUI() {
return mImpl;
}
/** Sets the callback for UI interactions. */ /** Sets the callback for UI interactions. */
public void setSizeCompatUICallback(SizeCompatUICallback callback) { public void setSizeCompatUICallback(SizeCompatUICallback callback) {
mCallback = callback; mCallback = callback;
@@ -106,6 +120,7 @@ public class SizeCompatUIController implements OnDisplaysChangedListener,
/** /**
* Called when the Task info changed. Creates and updates the size compat UI if there is an * Called when the Task info changed. Creates and updates the size compat UI if there is an
* activity in size compat, or removes the UI if there is no size compat activity. * activity in size compat, or removes the UI if there is no size compat activity.
*
* @param displayId display the task and activity are in. * @param displayId display the task and activity are in.
* @param taskId task the activity is in. * @param taskId task the activity is in.
* @param taskConfig task config to place the size compat UI with. * @param taskConfig task config to place the size compat UI with.
@@ -180,7 +195,19 @@ public class SizeCompatUIController implements OnDisplaysChangedListener,
} }
// Hide the size compat UIs when input method is showing. // Hide the size compat UIs when input method is showing.
forAllLayoutsOnDisplay(displayId, layout -> layout.updateImeVisibility(isShowing)); forAllLayoutsOnDisplay(displayId,
layout -> layout.updateVisibility(showOnDisplay(displayId)));
}
@VisibleForTesting
void onKeyguardOccludedChanged(boolean occluded) {
mKeyguardOccluded = occluded;
// Hide the size compat UIs when keyguard is occluded.
forAllLayouts(layout -> layout.updateVisibility(showOnDisplay(layout.getDisplayId())));
}
private boolean showOnDisplay(int displayId) {
return !mKeyguardOccluded && !isImeShowingOnDisplay(displayId);
} }
private boolean isImeShowingOnDisplay(int displayId) { private boolean isImeShowingOnDisplay(int displayId) {
@@ -198,7 +225,7 @@ public class SizeCompatUIController implements OnDisplaysChangedListener,
final SizeCompatUILayout layout = createLayout(context, displayId, taskId, taskConfig, final SizeCompatUILayout layout = createLayout(context, displayId, taskId, taskConfig,
taskListener); taskListener);
mActiveLayouts.put(taskId, layout); mActiveLayouts.put(taskId, layout);
layout.createSizeCompatButton(isImeShowingOnDisplay(displayId)); layout.createSizeCompatButton(showOnDisplay(displayId));
} }
@VisibleForTesting @VisibleForTesting
@@ -218,8 +245,7 @@ public class SizeCompatUIController implements OnDisplaysChangedListener,
if (layout == null) { if (layout == null) {
return; return;
} }
layout.updateSizeCompatInfo(taskConfig, taskListener, layout.updateSizeCompatInfo(taskConfig, taskListener, showOnDisplay(layout.getDisplayId()));
isImeShowingOnDisplay(layout.getDisplayId()));
} }
private void removeLayout(int taskId) { private void removeLayout(int taskId) {
@@ -250,15 +276,37 @@ public class SizeCompatUIController implements OnDisplaysChangedListener,
} }
private void forAllLayoutsOnDisplay(int displayId, Consumer<SizeCompatUILayout> callback) { private void forAllLayoutsOnDisplay(int displayId, Consumer<SizeCompatUILayout> callback) {
forAllLayouts(layout -> layout.getDisplayId() == displayId, callback);
}
private void forAllLayouts(Consumer<SizeCompatUILayout> callback) {
forAllLayouts(layout -> true, callback);
}
private void forAllLayouts(Predicate<SizeCompatUILayout> condition,
Consumer<SizeCompatUILayout> callback) {
for (int i = 0; i < mActiveLayouts.size(); i++) { for (int i = 0; i < mActiveLayouts.size(); i++) {
final int taskId = mActiveLayouts.keyAt(i); final int taskId = mActiveLayouts.keyAt(i);
final SizeCompatUILayout layout = mActiveLayouts.get(taskId); final SizeCompatUILayout layout = mActiveLayouts.get(taskId);
if (layout != null && layout.getDisplayId() == displayId) { if (layout != null && condition.test(layout)) {
callback.accept(layout); callback.accept(layout);
} }
} }
} }
/**
* The interface for calls from outside the Shell, within the host process.
*/
@ExternalThread
private class SizeCompatUIImpl implements SizeCompatUI {
@Override
public void onKeyguardOccludedChanged(boolean occluded) {
mMainExecutor.execute(() -> {
SizeCompatUIController.this.onKeyguardOccludedChanged(occluded);
});
}
}
/** An implementation of {@link OnInsetsChangedListener} for a given display id. */ /** An implementation of {@link OnInsetsChangedListener} for a given display id. */
private class PerDisplayOnInsetsChangedListener implements OnInsetsChangedListener { private class PerDisplayOnInsetsChangedListener implements OnInsetsChangedListener {
final int mDisplayId; final int mDisplayId;

View File

@@ -103,9 +103,9 @@ class SizeCompatUILayout {
} }
/** Creates the activity restart button window. */ /** Creates the activity restart button window. */
void createSizeCompatButton(boolean isImeShowing) { void createSizeCompatButton(boolean show) {
if (isImeShowing || mButton != null) { if (!show || mButton != null) {
// When ime is showing, wait until ime is dismiss to create UI. // Wait until button should be visible.
return; return;
} }
mButton = mButtonWindowManager.createSizeCompatButton(); mButton = mButtonWindowManager.createSizeCompatButton();
@@ -154,7 +154,7 @@ class SizeCompatUILayout {
/** Called when size compat info changed. */ /** Called when size compat info changed. */
void updateSizeCompatInfo(Configuration taskConfig, void updateSizeCompatInfo(Configuration taskConfig,
ShellTaskOrganizer.TaskListener taskListener, boolean isImeShowing) { ShellTaskOrganizer.TaskListener taskListener, boolean show) {
final Configuration prevTaskConfig = mTaskConfig; final Configuration prevTaskConfig = mTaskConfig;
final ShellTaskOrganizer.TaskListener prevTaskListener = mTaskListener; final ShellTaskOrganizer.TaskListener prevTaskListener = mTaskListener;
mTaskConfig = taskConfig; mTaskConfig = taskConfig;
@@ -170,7 +170,7 @@ class SizeCompatUILayout {
if (mButton == null || prevTaskListener != taskListener) { if (mButton == null || prevTaskListener != taskListener) {
// TaskListener changed, recreate the button for new surface parent. // TaskListener changed, recreate the button for new surface parent.
release(); release();
createSizeCompatButton(isImeShowing); createSizeCompatButton(show);
return; return;
} }
@@ -204,16 +204,16 @@ class SizeCompatUILayout {
} }
} }
/** Called when IME visibility changed. */ /** Called when the visibility of the UI should change. */
void updateImeVisibility(boolean isImeShowing) { void updateVisibility(boolean show) {
if (mButton == null) { if (mButton == null) {
// Button may not be created because ime is previous showing. // Button may not have been created because it was hidden previously.
createSizeCompatButton(isImeShowing); createSizeCompatButton(show);
return; return;
} }
// Hide size compat UIs when IME is showing. // Hide size compat UIs when IME is showing.
final int newVisibility = isImeShowing ? View.GONE : View.VISIBLE; final int newVisibility = show ? View.VISIBLE : View.GONE;
if (mButton.getVisibility() != newVisibility) { if (mButton.getVisibility() != newVisibility) {
mButton.setVisibility(newVisibility); mButton.setVisibility(newVisibility);
} }

View File

@@ -26,6 +26,7 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import android.content.Context; import android.content.Context;
@@ -43,6 +44,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.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SyncTransactionQueue;
import org.junit.Before; import org.junit.Before;
@@ -72,6 +74,7 @@ public class SizeCompatUIControllerTest extends ShellTestCase {
private @Mock DisplayImeController mMockImeController; private @Mock DisplayImeController mMockImeController;
private @Mock ShellTaskOrganizer.TaskListener mMockTaskListener; private @Mock ShellTaskOrganizer.TaskListener mMockTaskListener;
private @Mock SyncTransactionQueue mMockSyncQueue; private @Mock SyncTransactionQueue mMockSyncQueue;
private @Mock ShellExecutor mMockExecutor;
private @Mock SizeCompatUILayout mMockLayout; private @Mock SizeCompatUILayout mMockLayout;
@Captor @Captor
@@ -85,7 +88,7 @@ public class SizeCompatUIControllerTest extends ShellTestCase {
doReturn(DISPLAY_ID).when(mMockLayout).getDisplayId(); doReturn(DISPLAY_ID).when(mMockLayout).getDisplayId();
doReturn(TASK_ID).when(mMockLayout).getTaskId(); doReturn(TASK_ID).when(mMockLayout).getTaskId();
mController = new SizeCompatUIController(mContext, mMockDisplayController, mController = new SizeCompatUIController(mContext, mMockDisplayController,
mMockDisplayInsetsController, mMockImeController, mMockSyncQueue) { mMockDisplayInsetsController, mMockImeController, mMockSyncQueue, mMockExecutor) {
@Override @Override
SizeCompatUILayout createLayout(Context context, int displayId, int taskId, SizeCompatUILayout createLayout(Context context, int displayId, int taskId,
Configuration taskConfig, ShellTaskOrganizer.TaskListener taskListener) { Configuration taskConfig, ShellTaskOrganizer.TaskListener taskListener) {
@@ -106,19 +109,17 @@ public class SizeCompatUIControllerTest extends ShellTestCase {
final Configuration taskConfig = new Configuration(); final Configuration taskConfig = new Configuration();
// Verify that the restart button is added with non-null size compat info. // Verify that the restart button is added with non-null size compat info.
mController.onSizeCompatInfoChanged(DISPLAY_ID, TASK_ID, taskConfig, mController.onSizeCompatInfoChanged(DISPLAY_ID, TASK_ID, taskConfig, mMockTaskListener);
mMockTaskListener);
verify(mController).createLayout(any(), eq(DISPLAY_ID), eq(TASK_ID), eq(taskConfig), verify(mController).createLayout(any(), eq(DISPLAY_ID), eq(TASK_ID), eq(taskConfig),
eq(mMockTaskListener)); eq(mMockTaskListener));
// Verify that the restart button is updated with non-null new size compat info. // Verify that the restart button is updated with non-null new size compat info.
final Configuration newTaskConfig = new Configuration(); final Configuration newTaskConfig = new Configuration();
mController.onSizeCompatInfoChanged(DISPLAY_ID, TASK_ID, newTaskConfig, mController.onSizeCompatInfoChanged(DISPLAY_ID, TASK_ID, newTaskConfig, mMockTaskListener);
mMockTaskListener);
verify(mMockLayout).updateSizeCompatInfo(taskConfig, mMockTaskListener, verify(mMockLayout).updateSizeCompatInfo(taskConfig, mMockTaskListener,
false /* isImeShowing */); true /* show */);
// Verify that the restart button is removed with null size compat info. // Verify that the restart button is removed with null size compat info.
mController.onSizeCompatInfoChanged(DISPLAY_ID, TASK_ID, null, mMockTaskListener); mController.onSizeCompatInfoChanged(DISPLAY_ID, TASK_ID, null, mMockTaskListener);
@@ -196,15 +197,90 @@ public class SizeCompatUIControllerTest extends ShellTestCase {
@Test @Test
public void testChangeButtonVisibilityOnImeShowHide() { public void testChangeButtonVisibilityOnImeShowHide() {
final Configuration taskConfig = new Configuration(); final Configuration taskConfig = new Configuration();
mController.onSizeCompatInfoChanged(DISPLAY_ID, TASK_ID, taskConfig, mController.onSizeCompatInfoChanged(DISPLAY_ID, TASK_ID, taskConfig, mMockTaskListener);
mMockTaskListener);
// Verify that the restart button is hidden after IME is showing.
mController.onImeVisibilityChanged(DISPLAY_ID, true /* isShowing */); mController.onImeVisibilityChanged(DISPLAY_ID, true /* isShowing */);
verify(mMockLayout).updateImeVisibility(true); verify(mMockLayout).updateVisibility(false);
// Verify button remains hidden while IME is showing.
mController.onSizeCompatInfoChanged(DISPLAY_ID, TASK_ID, taskConfig, mMockTaskListener);
verify(mMockLayout).updateSizeCompatInfo(taskConfig, mMockTaskListener,
false /* show */);
// Verify button is shown after IME is hidden.
mController.onImeVisibilityChanged(DISPLAY_ID, false /* isShowing */); mController.onImeVisibilityChanged(DISPLAY_ID, false /* isShowing */);
verify(mMockLayout).updateImeVisibility(false); verify(mMockLayout).updateVisibility(true);
}
@Test
public void testChangeButtonVisibilityOnKeyguardOccludedChanged() {
final Configuration taskConfig = new Configuration();
mController.onSizeCompatInfoChanged(DISPLAY_ID, TASK_ID, taskConfig, mMockTaskListener);
// Verify that the restart button is hidden after keyguard becomes occluded.
mController.onKeyguardOccludedChanged(true);
verify(mMockLayout).updateVisibility(false);
// Verify button remains hidden while keyguard is occluded.
mController.onSizeCompatInfoChanged(DISPLAY_ID, TASK_ID, taskConfig, mMockTaskListener);
verify(mMockLayout).updateSizeCompatInfo(taskConfig, mMockTaskListener,
false /* show */);
// Verify button is shown after keyguard becomes not occluded.
mController.onKeyguardOccludedChanged(false);
verify(mMockLayout).updateVisibility(true);
}
@Test
public void testButtonRemainsHiddenOnKeyguardOccludedFalseWhenImeIsShowing() {
final Configuration taskConfig = new Configuration();
mController.onSizeCompatInfoChanged(DISPLAY_ID, TASK_ID, taskConfig, mMockTaskListener);
mController.onImeVisibilityChanged(DISPLAY_ID, true /* isShowing */);
mController.onKeyguardOccludedChanged(true);
verify(mMockLayout, times(2)).updateVisibility(false);
clearInvocations(mMockLayout);
// Verify button remains hidden after keyguard becomes not occluded since IME is showing.
mController.onKeyguardOccludedChanged(false);
verify(mMockLayout).updateVisibility(false);
// Verify button is shown after IME is not showing.
mController.onImeVisibilityChanged(DISPLAY_ID, false /* isShowing */);
verify(mMockLayout).updateVisibility(true);
}
@Test
public void testButtonRemainsHiddenOnImeHideWhenKeyguardIsOccluded() {
final Configuration taskConfig = new Configuration();
mController.onSizeCompatInfoChanged(DISPLAY_ID, TASK_ID, taskConfig, mMockTaskListener);
mController.onImeVisibilityChanged(DISPLAY_ID, true /* isShowing */);
mController.onKeyguardOccludedChanged(true);
verify(mMockLayout, times(2)).updateVisibility(false);
clearInvocations(mMockLayout);
// Verify button remains hidden after IME is hidden since keyguard is occluded.
mController.onImeVisibilityChanged(DISPLAY_ID, false /* isShowing */);
verify(mMockLayout).updateVisibility(false);
// Verify button is shown after keyguard becomes not occluded.
mController.onKeyguardOccludedChanged(false);
verify(mMockLayout).updateVisibility(true);
} }
} }

View File

@@ -96,8 +96,8 @@ public class SizeCompatUILayoutTest extends ShellTestCase {
@Test @Test
public void testCreateSizeCompatButton() { public void testCreateSizeCompatButton() {
// Not create button if IME is showing. // Not create button if show is false.
mLayout.createSizeCompatButton(true /* isImeShowing */); mLayout.createSizeCompatButton(false /* show */);
verify(mLayout.mButtonWindowManager, never()).createSizeCompatButton(); verify(mLayout.mButtonWindowManager, never()).createSizeCompatButton();
assertNull(mLayout.mButton); assertNull(mLayout.mButton);
@@ -106,7 +106,7 @@ public class SizeCompatUILayoutTest extends ShellTestCase {
// Not create hint popup. // Not create hint popup.
mLayout.mShouldShowHint = false; mLayout.mShouldShowHint = false;
mLayout.createSizeCompatButton(false /* isImeShowing */); mLayout.createSizeCompatButton(true /* show */);
verify(mLayout.mButtonWindowManager).createSizeCompatButton(); verify(mLayout.mButtonWindowManager).createSizeCompatButton();
assertNotNull(mLayout.mButton); assertNotNull(mLayout.mButton);
@@ -116,7 +116,7 @@ public class SizeCompatUILayoutTest extends ShellTestCase {
// Create hint popup. // Create hint popup.
mLayout.release(); mLayout.release();
mLayout.mShouldShowHint = true; mLayout.mShouldShowHint = true;
mLayout.createSizeCompatButton(false /* isImeShowing */); mLayout.createSizeCompatButton(true /* show */);
verify(mLayout.mButtonWindowManager, times(2)).createSizeCompatButton(); verify(mLayout.mButtonWindowManager, times(2)).createSizeCompatButton();
assertNotNull(mLayout.mButton); assertNotNull(mLayout.mButton);
@@ -128,7 +128,7 @@ public class SizeCompatUILayoutTest extends ShellTestCase {
@Test @Test
public void testRelease() { public void testRelease() {
mLayout.createSizeCompatButton(false /* isImeShowing */); mLayout.createSizeCompatButton(true /* show */);
final SizeCompatUIWindowManager hintWindowManager = mLayout.mHintWindowManager; final SizeCompatUIWindowManager hintWindowManager = mLayout.mHintWindowManager;
mLayout.release(); mLayout.release();
@@ -142,12 +142,11 @@ public class SizeCompatUILayoutTest extends ShellTestCase {
@Test @Test
public void testUpdateSizeCompatInfo() { public void testUpdateSizeCompatInfo() {
mLayout.createSizeCompatButton(false /* isImeShowing */); mLayout.createSizeCompatButton(true /* show */);
// No diff // No diff
clearInvocations(mLayout); clearInvocations(mLayout);
mLayout.updateSizeCompatInfo(mTaskConfig, mTaskListener, mLayout.updateSizeCompatInfo(mTaskConfig, mTaskListener, true /* show */);
false /* isImeShowing */);
verify(mLayout, never()).updateButtonSurfacePosition(); verify(mLayout, never()).updateButtonSurfacePosition();
verify(mLayout, never()).release(); verify(mLayout, never()).release();
@@ -158,7 +157,7 @@ public class SizeCompatUILayoutTest extends ShellTestCase {
final ShellTaskOrganizer.TaskListener newTaskListener = mock( final ShellTaskOrganizer.TaskListener newTaskListener = mock(
ShellTaskOrganizer.TaskListener.class); ShellTaskOrganizer.TaskListener.class);
mLayout.updateSizeCompatInfo(mTaskConfig, newTaskListener, mLayout.updateSizeCompatInfo(mTaskConfig, newTaskListener,
false /* isImeShowing */); true /* show */);
verify(mLayout).release(); verify(mLayout).release();
verify(mLayout).createSizeCompatButton(anyBoolean()); verify(mLayout).createSizeCompatButton(anyBoolean());
@@ -168,7 +167,7 @@ public class SizeCompatUILayoutTest extends ShellTestCase {
final Configuration newTaskConfiguration = new Configuration(); final Configuration newTaskConfiguration = new Configuration();
newTaskConfiguration.windowConfiguration.setBounds(new Rect(0, 1000, 0, 2000)); newTaskConfiguration.windowConfiguration.setBounds(new Rect(0, 1000, 0, 2000));
mLayout.updateSizeCompatInfo(newTaskConfiguration, newTaskListener, mLayout.updateSizeCompatInfo(newTaskConfiguration, newTaskListener,
false /* isImeShowing */); true /* show */);
verify(mLayout).updateButtonSurfacePosition(); verify(mLayout).updateButtonSurfacePosition();
verify(mLayout).updateHintSurfacePosition(); verify(mLayout).updateHintSurfacePosition();
@@ -220,24 +219,24 @@ public class SizeCompatUILayoutTest extends ShellTestCase {
} }
@Test @Test
public void testUpdateImeVisibility() { public void testUpdateVisibility() {
// Create button if it is not created. // Create button if it is not created.
mLayout.mButton = null; mLayout.mButton = null;
mLayout.updateImeVisibility(false /* isImeShowing */); mLayout.updateVisibility(true /* show */);
verify(mLayout).createSizeCompatButton(false /* isImeShowing */); verify(mLayout).createSizeCompatButton(true /* show */);
// Hide button if ime is shown. // Hide button.
clearInvocations(mLayout); clearInvocations(mLayout);
doReturn(View.VISIBLE).when(mButton).getVisibility(); doReturn(View.VISIBLE).when(mButton).getVisibility();
mLayout.updateImeVisibility(true /* isImeShowing */); mLayout.updateVisibility(false /* show */);
verify(mLayout, never()).createSizeCompatButton(anyBoolean()); verify(mLayout, never()).createSizeCompatButton(anyBoolean());
verify(mButton).setVisibility(View.GONE); verify(mButton).setVisibility(View.GONE);
// Show button if ime is not shown. // Show button.
doReturn(View.GONE).when(mButton).getVisibility(); doReturn(View.GONE).when(mButton).getVisibility();
mLayout.updateImeVisibility(false /* isImeShowing */); mLayout.updateVisibility(true /* show */);
verify(mLayout, never()).createSizeCompatButton(anyBoolean()); verify(mLayout, never()).createSizeCompatButton(anyBoolean());
verify(mButton).setVisibility(View.VISIBLE); verify(mButton).setVisibility(View.VISIBLE);

View File

@@ -31,8 +31,6 @@ import com.android.systemui.dagger.WMComponent;
import com.android.systemui.navigationbar.gestural.BackGestureTfClassifierProvider; import com.android.systemui.navigationbar.gestural.BackGestureTfClassifierProvider;
import com.android.systemui.screenshot.ScreenshotNotificationSmartActionsProvider; import com.android.systemui.screenshot.ScreenshotNotificationSmartActionsProvider;
import com.android.wm.shell.transition.ShellTransitions; import com.android.wm.shell.transition.ShellTransitions;
import com.android.wm.shell.transition.Transitions;
import com.android.wm.shell.recents.RecentTasks;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
@@ -122,7 +120,8 @@ public class SystemUIFactory {
.setStartingSurface(mWMComponent.getStartingSurface()) .setStartingSurface(mWMComponent.getStartingSurface())
.setDisplayAreaHelper(mWMComponent.getDisplayAreaHelper()) .setDisplayAreaHelper(mWMComponent.getDisplayAreaHelper())
.setTaskSurfaceHelper(mWMComponent.getTaskSurfaceHelper()) .setTaskSurfaceHelper(mWMComponent.getTaskSurfaceHelper())
.setRecentTasks(mWMComponent.getRecentTasks()); .setRecentTasks(mWMComponent.getRecentTasks())
.setSizeCompatUI(Optional.of(mWMComponent.getSizeCompatUI()));
} else { } else {
// TODO: Call on prepareSysUIComponentBuilder but not with real components. Other option // TODO: Call on prepareSysUIComponentBuilder but not with real components. Other option
// is separating this logic into newly creating SystemUITestsFactory. // is separating this logic into newly creating SystemUITestsFactory.
@@ -140,7 +139,8 @@ public class SystemUIFactory {
.setDisplayAreaHelper(Optional.ofNullable(null)) .setDisplayAreaHelper(Optional.ofNullable(null))
.setStartingSurface(Optional.ofNullable(null)) .setStartingSurface(Optional.ofNullable(null))
.setTaskSurfaceHelper(Optional.ofNullable(null)) .setTaskSurfaceHelper(Optional.ofNullable(null))
.setRecentTasks(Optional.ofNullable(null)); .setRecentTasks(Optional.ofNullable(null))
.setSizeCompatUI(Optional.ofNullable(null));
} }
mSysUIComponent = builder.build(); mSysUIComponent = builder.build();
if (mInitializeComponents) { if (mInitializeComponents) {

View File

@@ -37,6 +37,7 @@ import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
import com.android.wm.shell.onehanded.OneHanded; import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.pip.Pip; import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.recents.RecentTasks; import com.android.wm.shell.recents.RecentTasks;
import com.android.wm.shell.sizecompatui.SizeCompatUI;
import com.android.wm.shell.splitscreen.SplitScreen; import com.android.wm.shell.splitscreen.SplitScreen;
import com.android.wm.shell.startingsurface.StartingSurface; import com.android.wm.shell.startingsurface.StartingSurface;
import com.android.wm.shell.tasksurfacehelper.TaskSurfaceHelper; import com.android.wm.shell.tasksurfacehelper.TaskSurfaceHelper;
@@ -107,6 +108,9 @@ public interface SysUIComponent {
@BindsInstance @BindsInstance
Builder setRecentTasks(Optional<RecentTasks> r); Builder setRecentTasks(Optional<RecentTasks> r);
@BindsInstance
Builder setSizeCompatUI(Optional<SizeCompatUI> s);
SysUIComponent build(); SysUIComponent build();
} }

View File

@@ -20,13 +20,13 @@ import android.content.Context;
import com.android.systemui.SystemUIFactory; import com.android.systemui.SystemUIFactory;
import com.android.systemui.tv.TvWMComponent; import com.android.systemui.tv.TvWMComponent;
import com.android.wm.shell.dagger.TvWMShellModule;
import com.android.wm.shell.dagger.WMShellModule;
import com.android.wm.shell.ShellCommandHandler; import com.android.wm.shell.ShellCommandHandler;
import com.android.wm.shell.ShellInit; import com.android.wm.shell.ShellInit;
import com.android.wm.shell.TaskViewFactory; import com.android.wm.shell.TaskViewFactory;
import com.android.wm.shell.apppairs.AppPairs; import com.android.wm.shell.apppairs.AppPairs;
import com.android.wm.shell.bubbles.Bubbles; import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.dagger.TvWMShellModule;
import com.android.wm.shell.dagger.WMShellModule;
import com.android.wm.shell.dagger.WMSingleton; import com.android.wm.shell.dagger.WMSingleton;
import com.android.wm.shell.displayareahelper.DisplayAreaHelper; import com.android.wm.shell.displayareahelper.DisplayAreaHelper;
import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout; import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
@@ -34,6 +34,7 @@ import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
import com.android.wm.shell.onehanded.OneHanded; import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.pip.Pip; import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.recents.RecentTasks; import com.android.wm.shell.recents.RecentTasks;
import com.android.wm.shell.sizecompatui.SizeCompatUI;
import com.android.wm.shell.splitscreen.SplitScreen; import com.android.wm.shell.splitscreen.SplitScreen;
import com.android.wm.shell.startingsurface.StartingSurface; import com.android.wm.shell.startingsurface.StartingSurface;
import com.android.wm.shell.tasksurfacehelper.TaskSurfaceHelper; import com.android.wm.shell.tasksurfacehelper.TaskSurfaceHelper;
@@ -115,4 +116,7 @@ public interface WMComponent {
@WMSingleton @WMSingleton
Optional<RecentTasks> getRecentTasks(); Optional<RecentTasks> getRecentTasks();
@WMSingleton
SizeCompatUI getSizeCompatUI();
} }

View File

@@ -65,6 +65,7 @@ import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
import com.android.wm.shell.onehanded.OneHandedUiEventLogger; import com.android.wm.shell.onehanded.OneHandedUiEventLogger;
import com.android.wm.shell.pip.Pip; import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.protolog.ShellProtoLogImpl; import com.android.wm.shell.protolog.ShellProtoLogImpl;
import com.android.wm.shell.sizecompatui.SizeCompatUI;
import com.android.wm.shell.splitscreen.SplitScreen; import com.android.wm.shell.splitscreen.SplitScreen;
import java.io.FileDescriptor; import java.io.FileDescriptor;
@@ -112,6 +113,7 @@ public final class WMShell extends SystemUI
private final Optional<OneHanded> mOneHandedOptional; private final Optional<OneHanded> mOneHandedOptional;
private final Optional<HideDisplayCutout> mHideDisplayCutoutOptional; private final Optional<HideDisplayCutout> mHideDisplayCutoutOptional;
private final Optional<ShellCommandHandler> mShellCommandHandler; private final Optional<ShellCommandHandler> mShellCommandHandler;
private final Optional<SizeCompatUI> mSizeCompatUIOptional;
private final CommandQueue mCommandQueue; private final CommandQueue mCommandQueue;
private final ConfigurationController mConfigurationController; private final ConfigurationController mConfigurationController;
@@ -128,6 +130,7 @@ public final class WMShell extends SystemUI
private KeyguardUpdateMonitorCallback mSplitScreenKeyguardCallback; private KeyguardUpdateMonitorCallback mSplitScreenKeyguardCallback;
private KeyguardUpdateMonitorCallback mPipKeyguardCallback; private KeyguardUpdateMonitorCallback mPipKeyguardCallback;
private KeyguardUpdateMonitorCallback mOneHandedKeyguardCallback; private KeyguardUpdateMonitorCallback mOneHandedKeyguardCallback;
private KeyguardUpdateMonitorCallback mSizeCompatUIKeyguardCallback;
private WakefulnessLifecycle.Observer mWakefulnessObserver; private WakefulnessLifecycle.Observer mWakefulnessObserver;
@Inject @Inject
@@ -138,6 +141,7 @@ public final class WMShell extends SystemUI
Optional<OneHanded> oneHandedOptional, Optional<OneHanded> oneHandedOptional,
Optional<HideDisplayCutout> hideDisplayCutoutOptional, Optional<HideDisplayCutout> hideDisplayCutoutOptional,
Optional<ShellCommandHandler> shellCommandHandler, Optional<ShellCommandHandler> shellCommandHandler,
Optional<SizeCompatUI> sizeCompatUIOptional,
CommandQueue commandQueue, CommandQueue commandQueue,
ConfigurationController configurationController, ConfigurationController configurationController,
KeyguardUpdateMonitor keyguardUpdateMonitor, KeyguardUpdateMonitor keyguardUpdateMonitor,
@@ -162,6 +166,7 @@ public final class WMShell extends SystemUI
mWakefulnessLifecycle = wakefulnessLifecycle; mWakefulnessLifecycle = wakefulnessLifecycle;
mProtoTracer = protoTracer; mProtoTracer = protoTracer;
mShellCommandHandler = shellCommandHandler; mShellCommandHandler = shellCommandHandler;
mSizeCompatUIOptional = sizeCompatUIOptional;
mSysUiMainExecutor = sysUiMainExecutor; mSysUiMainExecutor = sysUiMainExecutor;
} }
@@ -176,6 +181,7 @@ public final class WMShell extends SystemUI
mSplitScreenOptional.ifPresent(this::initSplitScreen); mSplitScreenOptional.ifPresent(this::initSplitScreen);
mOneHandedOptional.ifPresent(this::initOneHanded); mOneHandedOptional.ifPresent(this::initOneHanded);
mHideDisplayCutoutOptional.ifPresent(this::initHideDisplayCutout); mHideDisplayCutoutOptional.ifPresent(this::initHideDisplayCutout);
mSizeCompatUIOptional.ifPresent(this::initSizeCompatUi);
} }
@VisibleForTesting @VisibleForTesting
@@ -367,6 +373,17 @@ public final class WMShell extends SystemUI
}); });
} }
@VisibleForTesting
void initSizeCompatUi(SizeCompatUI sizeCompatUI) {
mSizeCompatUIKeyguardCallback = new KeyguardUpdateMonitorCallback() {
@Override
public void onKeyguardOccludedChanged(boolean occluded) {
sizeCompatUI.onKeyguardOccludedChanged(occluded);
}
};
mKeyguardUpdateMonitor.registerCallback(mSizeCompatUIKeyguardCallback);
}
@Override @Override
public void writeToProto(SystemUiTraceProto proto) { public void writeToProto(SystemUiTraceProto proto) {
if (proto.wmShell == null) { if (proto.wmShell == null) {

View File

@@ -41,6 +41,7 @@ import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.onehanded.OneHandedEventCallback; import com.android.wm.shell.onehanded.OneHandedEventCallback;
import com.android.wm.shell.onehanded.OneHandedTransitionCallback; import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
import com.android.wm.shell.pip.Pip; import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.sizecompatui.SizeCompatUI;
import com.android.wm.shell.splitscreen.SplitScreen; import com.android.wm.shell.splitscreen.SplitScreen;
import org.junit.Before; import org.junit.Before;
@@ -76,6 +77,7 @@ public class WMShellTest extends SysuiTestCase {
@Mock WakefulnessLifecycle mWakefulnessLifecycle; @Mock WakefulnessLifecycle mWakefulnessLifecycle;
@Mock ProtoTracer mProtoTracer; @Mock ProtoTracer mProtoTracer;
@Mock ShellCommandHandler mShellCommandHandler; @Mock ShellCommandHandler mShellCommandHandler;
@Mock SizeCompatUI mSizeCompatUI;
@Mock ShellExecutor mSysUiMainExecutor; @Mock ShellExecutor mSysUiMainExecutor;
@Before @Before
@@ -84,10 +86,10 @@ public class WMShellTest extends SysuiTestCase {
mWMShell = new WMShell(mContext, Optional.of(mPip), Optional.of(mLegacySplitScreen), mWMShell = new WMShell(mContext, Optional.of(mPip), Optional.of(mLegacySplitScreen),
Optional.of(mSplitScreen), Optional.of(mOneHanded), Optional.of(mHideDisplayCutout), Optional.of(mSplitScreen), Optional.of(mOneHanded), Optional.of(mHideDisplayCutout),
Optional.of(mShellCommandHandler), mCommandQueue, mConfigurationController, Optional.of(mShellCommandHandler), Optional.of(mSizeCompatUI),
mKeyguardUpdateMonitor, mNavigationModeController, mCommandQueue, mConfigurationController, mKeyguardUpdateMonitor,
mScreenLifecycle, mSysUiState, mProtoTracer, mWakefulnessLifecycle, mNavigationModeController, mScreenLifecycle, mSysUiState, mProtoTracer,
mSysUiMainExecutor); mWakefulnessLifecycle, mSysUiMainExecutor);
} }
@Test @Test
@@ -129,4 +131,11 @@ public class WMShellTest extends SysuiTestCase {
verify(mConfigurationController).addCallback( verify(mConfigurationController).addCallback(
any(ConfigurationController.ConfigurationListener.class)); any(ConfigurationController.ConfigurationListener.class));
} }
@Test
public void initSizeCompatUI_registersCallbacks() {
mWMShell.initSizeCompatUi(mSizeCompatUI);
verify(mKeyguardUpdateMonitor).registerCallback(any(KeyguardUpdateMonitorCallback.class));
}
} }