summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBarService.aidl3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java42
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java170
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java36
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerService.java14
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerInternal.java5
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java7
-rw-r--r--tests/testables/src/android/testing/BaseFragmentTest.java2
9 files changed, 254 insertions, 30 deletions
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 5fee2c9bbdd3..8f8e4d8dc108 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -48,8 +48,7 @@ interface IStatusBarService
void setIconVisibility(String slot, boolean visible);
@UnsupportedAppUsage
void removeIcon(String slot);
- // TODO(b/117478341): support back button change when IME is showing on a external display.
- void setImeWindowStatus(in IBinder token, int vis, int backDisposition,
+ void setImeWindowStatus(int displayId, in IBinder token, int vis, int backDisposition,
boolean showImeSwitcher);
void expandSettingsPanel(String subPanel);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 2f99cf311eec..d5849598342f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -18,7 +18,10 @@ package com.android.systemui.statusbar;
import static android.app.StatusBarManager.DISABLE2_NONE;
import static android.app.StatusBarManager.DISABLE_NONE;
+import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_DEFAULT;
+import static android.inputmethodservice.InputMethodService.IME_INVISIBLE;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.INVALID_DISPLAY;
import static com.android.systemui.statusbar.phone.StatusBar.ONLY_CORE_APPS;
@@ -40,6 +43,7 @@ import android.os.Looper;
import android.os.Message;
import android.util.Pair;
import android.util.SparseArray;
+import android.view.inputmethod.InputMethodSystemProperty;
import androidx.annotation.VisibleForTesting;
@@ -127,6 +131,11 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
private Handler mHandler = new H(Looper.getMainLooper());
/** A map of display id - disable flag pair */
private SparseArray<Pair<Integer, Integer>> mDisplayDisabled = new SparseArray<>();
+ /**
+ * The last ID of the display where IME window for which we received setImeWindowStatus
+ * event.
+ */
+ private int mLastUpdatedImeDisplayId = INVALID_DISPLAY;
/**
* These methods are called back on the main thread.
@@ -785,6 +794,32 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
}
}
+ private void handleShowImeButton(int displayId, IBinder token, int vis, int backDisposition,
+ boolean showImeSwitcher) {
+ if (displayId == INVALID_DISPLAY) return;
+
+ if (!InputMethodSystemProperty.MULTI_CLIENT_IME_ENABLED
+ && mLastUpdatedImeDisplayId != displayId
+ && mLastUpdatedImeDisplayId != INVALID_DISPLAY) {
+ // Set previous NavBar's IME window status as invisible when IME
+ // window switched to another display for single-session IME case.
+ sendImeInvisibleStatusForPrevNavBar();
+ }
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ mCallbacks.get(i).setImeWindowStatus(displayId, token, vis, backDisposition,
+ showImeSwitcher);
+ }
+ mLastUpdatedImeDisplayId = displayId;
+ }
+
+ private void sendImeInvisibleStatusForPrevNavBar() {
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ mCallbacks.get(i).setImeWindowStatus(mLastUpdatedImeDisplayId,
+ null /* token */, IME_INVISIBLE, BACK_DISPOSITION_DEFAULT,
+ false /* showImeSwitcher */);
+ }
+ }
+
private final class H extends Handler {
private H(Looper l) {
super(l);
@@ -852,10 +887,9 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
break;
case MSG_SHOW_IME_BUTTON:
args = (SomeArgs) msg.obj;
- for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).setImeWindowStatus(args.argi1, (IBinder) args.arg1,
- args.argi2, args.argi3, args.argi4 != 0 /* showImeSwitcher */);
- }
+ handleShowImeButton(args.argi1 /* displayId */, (IBinder) args.arg1 /* token */,
+ args.argi2 /* vis */, args.argi3 /* backDisposition */,
+ args.argi4 != 0 /* showImeSwitcher */);
break;
case MSG_SHOW_RECENT_APPS:
for (int i = 0; i < mCallbacks.size(); i++) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 591b1b48ddc2..083b3dfb9b65 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -1064,4 +1064,9 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
context.getSystemService(WindowManager.class).addView(navigationBarView, lp);
return navigationBarView;
}
+
+ @VisibleForTesting
+ int getNavigationIconHints() {
+ return mNavigationIconHints;
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
index 6a0d61dc13c9..3ae57e391005 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
@@ -14,18 +14,38 @@
package com.android.systemui.statusbar.phone;
+import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
+import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
+import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_DEFAULT;
+import static android.inputmethodservice.InputMethodService.IME_VISIBLE;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import android.annotation.LayoutRes;
+import android.annotation.Nullable;
import android.app.Fragment;
+import android.app.FragmentController;
+import android.app.FragmentHostCallback;
import android.content.Context;
+import android.hardware.display.DisplayManagerGlobal;
import android.os.Bundle;
+import android.os.Handler;
import android.os.Looper;
import android.testing.AndroidTestingRunner;
import android.testing.LeakCheck.Tracker;
+import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.view.Display;
+import android.view.DisplayInfo;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener;
@@ -34,6 +54,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
import com.android.systemui.Dependency;
import com.android.systemui.SysuiBaseFragmentTest;
+import com.android.systemui.SysuiTestableContext;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.recents.Recents;
@@ -50,9 +71,16 @@ import org.junit.runner.RunWith;
@RunWithLooper()
@SmallTest
public class NavigationBarFragmentTest extends SysuiBaseFragmentTest {
+ private static final int EXTERNAL_DISPLAY_ID = 2;
+ private static final int NAV_BAR_VIEW_ID = 43;
+
+ private Fragment mFragmentExternalDisplay;
+ private FragmentController mControllerExternalDisplay;
+ private SysuiTestableContext mSysuiTestableContextExternal;
private OverviewProxyService mOverviewProxyService =
mDependency.injectMockDependency(OverviewProxyService.class);
+ private CommandQueue mCommandQueue;
private AccessibilityManagerWrapper mAccessibilityWrapper =
new AccessibilityManagerWrapper(mContext) {
Tracker mTracker = mLeakCheck.getTracker("accessibility_manager");
@@ -73,15 +101,51 @@ public class NavigationBarFragmentTest extends SysuiBaseFragmentTest {
}
protected void createRootView() {
- mView = new NavigationBarFrame(mContext);
+ mView = new NavigationBarFrame(mSysuiContext);
+ mView.setId(NAV_BAR_VIEW_ID);
}
@Before
- public void setup() {
- mSysuiContext.putComponent(CommandQueue.class, mock(CommandQueue.class));
+ public void setupFragment() throws Exception {
+ setupSysuiDependency();
+ createRootView();
+ TestableLooper.get(this).runWithLooper(() -> {
+ mHandler = new Handler();
+
+ mFragment = instantiate(mSysuiContext, NavigationBarFragment.class.getName(), null);
+ mFragments = FragmentController.createController(
+ new HostCallbacksForExternalDisplay(mSysuiContext));
+ mFragments.attachHost(null);
+ mFragments.getFragmentManager().beginTransaction()
+ .replace(NAV_BAR_VIEW_ID, mFragment)
+ .commit();
+ mControllerExternalDisplay = FragmentController.createController(
+ new HostCallbacksForExternalDisplay(mSysuiTestableContextExternal));
+ mControllerExternalDisplay.attachHost(null);
+ mFragmentExternalDisplay = instantiate(mSysuiTestableContextExternal,
+ NavigationBarFragment.class.getName(), null);
+ mControllerExternalDisplay.getFragmentManager().beginTransaction()
+ .replace(NAV_BAR_VIEW_ID, mFragmentExternalDisplay)
+ .commit();
+ });
+ }
+
+ private void setupSysuiDependency() {
+ mCommandQueue = new CommandQueue(mContext);
+ mSysuiContext.putComponent(CommandQueue.class, mCommandQueue);
mSysuiContext.putComponent(StatusBar.class, mock(StatusBar.class));
mSysuiContext.putComponent(Recents.class, mock(Recents.class));
mSysuiContext.putComponent(Divider.class, mock(Divider.class));
+
+ Display display = new Display(DisplayManagerGlobal.getInstance(), EXTERNAL_DISPLAY_ID,
+ new DisplayInfo(), DEFAULT_DISPLAY_ADJUSTMENTS);
+ mSysuiTestableContextExternal = (SysuiTestableContext) mSysuiContext.createDisplayContext(
+ display);
+ mSysuiTestableContextExternal.putComponent(CommandQueue.class, mCommandQueue);
+ mSysuiTestableContextExternal.putComponent(StatusBar.class, mock(StatusBar.class));
+ mSysuiTestableContextExternal.putComponent(Recents.class, mock(Recents.class));
+ mSysuiTestableContextExternal.putComponent(Divider.class, mock(Divider.class));
+
injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
WindowManager windowManager = mock(WindowManager.class);
Display defaultDisplay = mContext.getSystemService(WindowManager.class).getDefaultDisplay();
@@ -102,15 +166,111 @@ public class NavigationBarFragmentTest extends SysuiBaseFragmentTest {
navigationBarFragment.onHomeLongClick(navigationBarFragment.getView());
}
+ @Test
+ public void testSetImeWindowStatusWhenImeSwitchOnDisplay() {
+ // Create default & external NavBar fragment.
+ NavigationBarFragment defaultNavBar = (NavigationBarFragment) mFragment;
+ NavigationBarFragment externalNavBar = (NavigationBarFragment) mFragmentExternalDisplay;
+ mFragments.dispatchCreate();
+ processAllMessages();
+ mFragments.dispatchResume();
+ processAllMessages();
+ mControllerExternalDisplay.dispatchCreate();
+ processAllMessages();
+ mControllerExternalDisplay.dispatchResume();
+ processAllMessages();
+
+ // Set IME window status for default NavBar.
+ mCommandQueue.setImeWindowStatus(DEFAULT_DISPLAY, null, IME_VISIBLE,
+ BACK_DISPOSITION_DEFAULT, true);
+ Handler.getMain().runWithScissors(() -> { }, 500);
+
+ // Verify IME window state will be updated in default NavBar & external NavBar state reset.
+ assertEquals(NAVIGATION_HINT_BACK_ALT | NAVIGATION_HINT_IME_SHOWN,
+ defaultNavBar.getNavigationIconHints());
+ assertFalse((externalNavBar.getNavigationIconHints() & NAVIGATION_HINT_BACK_ALT) != 0);
+ assertFalse((externalNavBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SHOWN) != 0);
+
+ // Set IME window status for external NavBar.
+ mCommandQueue.setImeWindowStatus(EXTERNAL_DISPLAY_ID, null,
+ IME_VISIBLE, BACK_DISPOSITION_DEFAULT, true);
+ Handler.getMain().runWithScissors(() -> { }, 500);
+
+ // Verify IME window state will be updated in external NavBar & default NavBar state reset.
+ assertEquals(NAVIGATION_HINT_BACK_ALT | NAVIGATION_HINT_IME_SHOWN,
+ externalNavBar.getNavigationIconHints());
+ assertFalse((defaultNavBar.getNavigationIconHints() & NAVIGATION_HINT_BACK_ALT) != 0);
+ assertFalse((defaultNavBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SHOWN) != 0);
+ }
+
@Override
protected Fragment instantiate(Context context, String className, Bundle arguments) {
DeviceProvisionedController deviceProvisionedController =
mock(DeviceProvisionedController.class);
assertNotNull(mAccessibilityWrapper);
- return new NavigationBarFragment(mAccessibilityWrapper,
+ return new NavigationBarFragment(
+ context.getDisplayId() == DEFAULT_DISPLAY ? mAccessibilityWrapper
+ : mock(AccessibilityManagerWrapper.class),
deviceProvisionedController,
new MetricsLogger(),
- new AssistManager(deviceProvisionedController, mContext),
+ mock(AssistManager.class),
mOverviewProxyService);
}
+
+ private class HostCallbacksForExternalDisplay extends
+ FragmentHostCallback<NavigationBarFragmentTest> {
+ private Context mDisplayContext;
+
+ HostCallbacksForExternalDisplay(Context context) {
+ super(context, mHandler, 0);
+ mDisplayContext = context;
+ }
+
+ @Override
+ public NavigationBarFragmentTest onGetHost() {
+ return NavigationBarFragmentTest.this;
+ }
+
+ @Override
+ public Fragment instantiate(Context context, String className, Bundle arguments) {
+ return NavigationBarFragmentTest.this.instantiate(context, className, arguments);
+ }
+
+ @Override
+ public View onFindViewById(int id) {
+ return mView.findViewById(id);
+ }
+
+ @Override
+ public LayoutInflater onGetLayoutInflater() {
+ return new LayoutInflaterWrapper(mDisplayContext);
+ }
+ }
+
+ private static class LayoutInflaterWrapper extends LayoutInflater {
+ protected LayoutInflaterWrapper(Context context) {
+ super(context);
+ }
+
+ @Override
+ public LayoutInflater cloneInContext(Context newContext) {
+ return null;
+ }
+
+ @Override
+ public View inflate(@LayoutRes int resource, @Nullable ViewGroup root,
+ boolean attachToRoot) {
+ NavigationBarView view = mock(NavigationBarView.class);
+ when(view.getDisplay()).thenReturn(mContext.getDisplay());
+ when(view.getBackButton()).thenReturn(mock(ButtonDispatcher.class));
+ when(view.getHomeButton()).thenReturn(mock(ButtonDispatcher.class));
+ when(view.getRecentsButton()).thenReturn(mock(ButtonDispatcher.class));
+ when(view.getAccessibilityButton()).thenReturn(mock(ButtonDispatcher.class));
+ when(view.getRotateSuggestionButton()).thenReturn(mock(RotationContextButton.class));
+ when(view.getBarTransitions()).thenReturn(mock(BarTransitions.class));
+ when(view.getLightTransitionsController()).thenReturn(
+ mock(LightBarTransitionsController.class));
+ return view;
+ }
+ }
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index e88d62f58507..de2fd42d398c 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -575,6 +575,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
*/
int mCurTokenDisplayId = INVALID_DISPLAY;
+ /**
+ * The display ID of the input method indicates the fallback display which returned by
+ * {@link #computeImeDisplayIdForTarget}.
+ */
+ private static final int FALLBACK_DISPLAY_ID = DEFAULT_DISPLAY;
+
final ImeDisplayValidator mImeDisplayValidator;
/**
@@ -625,7 +631,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
* currently invisible.
* </dd>
* </dl>
- * <em>Do not update this value outside of setImeWindowStatus.</em>
+ * <em>Do not update this value outside of {@link #setImeWindowStatus(IBinder, int, int)} and
+ * {@link #unbindCurrentMethodLocked()}.</em>
*/
int mImeWindowVis;
@@ -2124,12 +2131,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
*/
static int computeImeDisplayIdForTarget(int displayId, @NonNull ImeDisplayValidator checker) {
if (displayId == DEFAULT_DISPLAY || displayId == INVALID_DISPLAY) {
- // We always assume that the default display id suitable to show the IME window.
- return DEFAULT_DISPLAY;
+ return FALLBACK_DISPLAY_ID;
}
- // Show IME in default display when the display with IME target doesn't support system
- // decorations.
- return checker.displayCanShowIme(displayId) ? displayId : DEFAULT_DISPLAY;
+ // Show IME window on fallback display when the display is not allowed.
+ return checker.displayCanShowIme(displayId) ? displayId : FALLBACK_DISPLAY_ID;
}
@Override
@@ -2198,6 +2203,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mIWindowManager.removeWindowToken(mCurToken, mCurTokenDisplayId);
} catch (RemoteException e) {
}
+ // Set IME window status as invisible when unbind current method.
+ mImeWindowVis = 0;
+ mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT;
+ updateSystemUiLocked(mImeWindowVis, mBackDisposition);
mCurToken = null;
mCurTokenDisplayId = INVALID_DISPLAY;
}
@@ -2399,10 +2408,20 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@BinderThread
@SuppressWarnings("deprecation")
private void setImeWindowStatus(@NonNull IBinder token, int vis, int backDisposition) {
+ final int topFocusedDisplayId = mWindowManagerInternal.getTopFocusedDisplayId();
+
synchronized (mMethodMap) {
if (!calledWithValidTokenLocked(token)) {
return;
}
+ // Skip update IME status when current token display is not same as focused display.
+ // Note that we still need to update IME status when focusing external display
+ // that does not support system decoration and fallback to show IME on default
+ // display since it is intentional behavior.
+ if (mCurTokenDisplayId != topFocusedDisplayId
+ && mCurTokenDisplayId != FALLBACK_DISPLAY_ID) {
+ return;
+ }
mImeWindowVis = vis;
mBackDisposition = backDisposition;
updateSystemUiLocked(vis, backDisposition);
@@ -2447,7 +2466,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
if (DEBUG) {
Slog.d(TAG, "IME window vis: " + vis
+ " active: " + (vis & InputMethodService.IME_ACTIVE)
- + " inv: " + (vis & InputMethodService.IME_INVISIBLE));
+ + " inv: " + (vis & InputMethodService.IME_INVISIBLE)
+ + " displayId: " + mCurTokenDisplayId);
}
// TODO: Move this clearing calling identity block to setImeWindowStatus after making sure
@@ -2461,7 +2481,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// mImeWindowVis should be updated before calling shouldShowImeSwitcherLocked().
final boolean needsToShowImeSwitcher = shouldShowImeSwitcherLocked(vis);
if (mStatusBar != null) {
- mStatusBar.setImeWindowStatus(mCurToken, vis, backDisposition,
+ mStatusBar.setImeWindowStatus(mCurTokenDisplayId, mCurToken, vis, backDisposition,
needsToShowImeSwitcher);
}
final InputMethodInfo imi = mMethodMap.get(mCurMethodId);
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index aaf3df39d429..9cbf00b85e8b 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -843,10 +843,9 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
}
}
- // TODO(b/117478341): support back button change when IME is showing on a external display.
@Override
- public void setImeWindowStatus(final IBinder token, final int vis, final int backDisposition,
- final boolean showImeSwitcher) {
+ public void setImeWindowStatus(int displayId, final IBinder token, final int vis,
+ final int backDisposition, final boolean showImeSwitcher) {
enforceStatusBar();
if (SPEW) {
@@ -857,18 +856,13 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
// In case of IME change, we need to call up setImeWindowStatus() regardless of
// mImeWindowVis because mImeWindowVis may not have been set to false when the
// previous IME was destroyed.
- // TODO(b/117478341): support back button change when IME is showing on a external
- // display.
- getUiState(DEFAULT_DISPLAY)
- .setImeWindowState(vis, backDisposition, showImeSwitcher, token);
+ getUiState(displayId).setImeWindowState(vis, backDisposition, showImeSwitcher, token);
mHandler.post(() -> {
if (mBar == null) return;
try {
- // TODO(b/117478341): support back button change when IME is showing on a
- // external display.
mBar.setImeWindowStatus(
- DEFAULT_DISPLAY, token, vis, backDisposition, showImeSwitcher);
+ displayId, token, vis, backDisposition, showImeSwitcher);
} catch (RemoteException ex) { }
});
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 9d80425435ef..78c5dbddee41 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -476,6 +476,11 @@ public abstract class WindowManagerInternal {
public abstract int getDisplayIdForWindow(IBinder windowToken);
/**
+ * @return The top focused display ID.
+ */
+ public abstract int getTopFocusedDisplayId();
+
+ /**
* Checks whether this display should support showing system decorations.
*/
public abstract boolean shouldShowSystemDecorOnDisplay(int displayId);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ce496f47be54..0215b7556215 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -7340,6 +7340,13 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
+ public int getTopFocusedDisplayId() {
+ synchronized (mGlobalLock) {
+ return mRoot.getTopFocusedDisplayContent().getDisplayId();
+ }
+ }
+
+ @Override
public boolean shouldShowSystemDecorOnDisplay(int displayId) {
synchronized (mGlobalLock) {
return WindowManagerService.this.shouldShowSystemDecors(displayId);
diff --git a/tests/testables/src/android/testing/BaseFragmentTest.java b/tests/testables/src/android/testing/BaseFragmentTest.java
index 9f60cce61bce..6cd88b51cb82 100644
--- a/tests/testables/src/android/testing/BaseFragmentTest.java
+++ b/tests/testables/src/android/testing/BaseFragmentTest.java
@@ -52,7 +52,7 @@ public abstract class BaseFragmentTest {
private static final int VIEW_ID = 42;
private final Class<? extends Fragment> mCls;
- private Handler mHandler;
+ protected Handler mHandler;
protected FrameLayout mView;
protected FragmentController mFragments;
protected Fragment mFragment;