Introduce ImeTargetVisibilityPolicy
This class provides ime target visibility utility functions from IMMS to WM as: -. update ime screenshot -. update ime parent This change only build the class and no module rely on it so it shouldn't have behavior changes. Bug: 258048231 Test: atest WmTests:ZOrderingTests#testImeScreenshotLayer Change-Id: Ie567ba578dca65be0a9a11d9a4aa27a13fe69900
This commit is contained in:
@@ -4320,6 +4320,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
return mImeTarget;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
SurfaceControl getImeScreenshotSurface() {
|
||||
return mImeSurface;
|
||||
}
|
||||
|
||||
private SurfaceControl createImeSurface(ScreenCapture.ScreenshotHardwareBuffer b,
|
||||
Transaction t) {
|
||||
final HardwareBuffer buffer = b.getHardwareBuffer();
|
||||
@@ -4429,33 +4434,45 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
}
|
||||
}
|
||||
|
||||
private void attachAndShowImeScreenshotOnTarget() {
|
||||
private void attachImeScreenshotOnTargetIfNeeded() {
|
||||
// No need to attach screenshot if the IME target not exists or screen is off.
|
||||
if (!shouldImeAttachedToApp() || !mWmService.mPolicy.isScreenOn()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final SurfaceControl.Transaction t = getPendingTransaction();
|
||||
// Prepare IME screenshot for the target if it allows to attach into.
|
||||
if (mInputMethodWindow != null && mInputMethodWindow.isVisible()) {
|
||||
// Remove the obsoleted IME snapshot first in case the new snapshot happens to
|
||||
// override the current one before the transition finish and the surface never be
|
||||
// removed on the task.
|
||||
removeImeSurfaceImmediately();
|
||||
mImeScreenshot = new ImeScreenshot(
|
||||
mWmService.mSurfaceControlFactory.apply(null), mImeLayeringTarget);
|
||||
mImeScreenshot.attachAndShow(t);
|
||||
attachImeScreenshotOnTarget(mImeLayeringTarget);
|
||||
}
|
||||
}
|
||||
|
||||
private void attachImeScreenshotOnTarget(WindowState imeTarget) {
|
||||
final SurfaceControl.Transaction t = getPendingTransaction();
|
||||
// Remove the obsoleted IME snapshot first in case the new snapshot happens to
|
||||
// override the current one before the transition finish and the surface never be
|
||||
// removed on the task.
|
||||
removeImeSurfaceImmediately();
|
||||
mImeScreenshot = new ImeScreenshot(
|
||||
mWmService.mSurfaceControlFactory.apply(null), imeTarget);
|
||||
mImeScreenshot.attachAndShow(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the IME screenshot and attach to the IME target window.
|
||||
* Shows the IME screenshot and attach to the IME layering target window.
|
||||
*
|
||||
* Used when the IME target window with IME visible is transitioning to the next target.
|
||||
* e.g. App transitioning or swiping this the task of the IME target window to recents app.
|
||||
*/
|
||||
void showImeScreenshot() {
|
||||
attachAndShowImeScreenshotOnTarget();
|
||||
attachImeScreenshotOnTargetIfNeeded();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the IME screenshot and attach it to the given IME target window.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
void showImeScreenshot(WindowState imeTarget) {
|
||||
attachImeScreenshotOnTarget(imeTarget);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.server.wm;
|
||||
|
||||
|
||||
import android.os.IBinder;
|
||||
|
||||
/**
|
||||
* A class for {@link com.android.server.inputmethod.InputMethodManagerService} to
|
||||
* control IME visibility operations in {@link WindowManagerService}.
|
||||
*/
|
||||
public abstract class ImeTargetVisibilityPolicy {
|
||||
|
||||
/**
|
||||
* Shows the IME screenshot and attach it to the given IME target window.
|
||||
*
|
||||
* @param imeTarget The target window to show the IME screenshot.
|
||||
* @param displayId A unique id to identify the display.
|
||||
* @return {@code true} if success, {@code false} otherwise.
|
||||
*/
|
||||
public abstract boolean showImeScreenShot(IBinder imeTarget, int displayId);
|
||||
|
||||
/**
|
||||
* Updates the IME parent for target window.
|
||||
*
|
||||
* @param imeTarget The target window to update the IME parent.
|
||||
* @param displayId A unique id to identify the display.
|
||||
* @return {@code true} if success, {@code false} otherwise.
|
||||
*/
|
||||
public abstract boolean updateImeParent(IBinder imeTarget, int displayId);
|
||||
}
|
||||
@@ -1333,6 +1333,8 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
mConstants.start(new HandlerExecutor(mH));
|
||||
|
||||
LocalServices.addService(WindowManagerInternal.class, new LocalService());
|
||||
LocalServices.addService(
|
||||
ImeTargetVisibilityPolicy.class, new ImeTargetVisibilityPolicyImpl());
|
||||
mEmbeddedWindowController = new EmbeddedWindowController(mAtmService);
|
||||
|
||||
mDisplayAreaPolicyProvider = DisplayAreaPolicy.Provider.fromResources(
|
||||
@@ -8333,6 +8335,47 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
private final class ImeTargetVisibilityPolicyImpl extends ImeTargetVisibilityPolicy {
|
||||
|
||||
// TODO(b/258048231): Track IME visibility change in bugreport when invocations.
|
||||
@Override
|
||||
public boolean showImeScreenShot(@NonNull IBinder imeTarget, int displayId) {
|
||||
synchronized (mGlobalLock) {
|
||||
final WindowState imeTargetWindow = mWindowMap.get(imeTarget);
|
||||
if (imeTargetWindow == null) {
|
||||
return false;
|
||||
}
|
||||
final DisplayContent dc = mRoot.getDisplayContent(displayId);
|
||||
if (dc == null) {
|
||||
Slog.w(TAG, "Invalid displayId:" + displayId + ", fail to show ime screenshot");
|
||||
return false;
|
||||
}
|
||||
|
||||
dc.showImeScreenshot(imeTargetWindow);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(b/258048231): Track IME visibility change in bugreport when invocations.
|
||||
@Override
|
||||
public boolean updateImeParent(@NonNull IBinder imeTarget, int displayId) {
|
||||
synchronized (mGlobalLock) {
|
||||
final WindowState imeTargetWindow = mWindowMap.get(imeTarget);
|
||||
if (imeTargetWindow == null) {
|
||||
return false;
|
||||
}
|
||||
final DisplayContent dc = mRoot.getDisplayContent(displayId);
|
||||
if (dc == null) {
|
||||
Slog.w(TAG, "Invalid displayId:" + displayId + ", fail to update ime parent");
|
||||
return false;
|
||||
}
|
||||
|
||||
dc.updateImeParent();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void registerAppFreezeListener(AppFreezeListener listener) {
|
||||
if (!mAppFreezeListeners.contains(listener)) {
|
||||
mAppFreezeListeners.add(listener);
|
||||
|
||||
@@ -419,6 +419,7 @@ public class SystemServicesTestRule implements TestRule {
|
||||
LocalServices.removeServiceForTest(UsageStatsManagerInternal.class);
|
||||
LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
|
||||
LocalServices.removeServiceForTest(UserManagerInternal.class);
|
||||
LocalServices.removeServiceForTest(ImeTargetVisibilityPolicy.class);
|
||||
}
|
||||
|
||||
Description getDescription() {
|
||||
|
||||
@@ -45,16 +45,21 @@ import static com.android.server.wm.WindowStateAnimator.PRESERVED_SURFACE_LAYER;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Binder;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.view.IRecentsAnimationRunner;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.SurfaceSession;
|
||||
import android.window.ScreenCapture;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
@@ -569,4 +574,26 @@ public class ZOrderingTests extends WindowTestsBase {
|
||||
assertZOrderGreaterThan(mTransaction, systemDialogWindow.getSurfaceControl(),
|
||||
mDisplayContent.getImeContainer().getSurfaceControl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImeScreenshotLayer() {
|
||||
final Task task = createTask(mDisplayContent);
|
||||
final WindowState imeAppTarget = createAppWindow(task, TYPE_APPLICATION, "imeAppTarget");
|
||||
final Rect bounds = mImeWindow.getParentFrame();
|
||||
final ScreenCapture.ScreenshotHardwareBuffer imeBuffer =
|
||||
ScreenCapture.captureLayersExcluding(mImeWindow.getSurfaceControl(),
|
||||
bounds, 1.0f, PixelFormat.RGB_565, null);
|
||||
|
||||
spyOn(mDisplayContent.mWmService.mTaskSnapshotController);
|
||||
doReturn(imeBuffer).when(mDisplayContent.mWmService.mTaskSnapshotController)
|
||||
.snapshotImeFromAttachedTask(task);
|
||||
|
||||
mDisplayContent.showImeScreenshot(imeAppTarget);
|
||||
|
||||
assertEquals(imeAppTarget, mDisplayContent.mImeScreenshot.getImeTarget());
|
||||
assertNotNull(mDisplayContent.mImeScreenshot);
|
||||
assertZOrderGreaterThan(mTransaction,
|
||||
mDisplayContent.mImeScreenshot.getImeScreenshotSurface(),
|
||||
imeAppTarget.mSurfaceControl);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user