Merge "Propogate per-display IME status to SysUI" into qt-dev
am: f2087397ef
Change-Id: I1c8d3a110050cff9c413da2fdd689458c5bc8796
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -1063,4 +1063,9 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
|
||||
context.getSystemService(WindowManager.class).addView(navigationBarView, lp);
|
||||
return navigationBarView;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
int getNavigationIconHints() {
|
||||
return mNavigationIconHints;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) { }
|
||||
});
|
||||
}
|
||||
|
||||
@@ -475,6 +475,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.
|
||||
*/
|
||||
|
||||
@@ -7339,6 +7339,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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user