WM changes to support new screenshot functionality.

Bug: 251205791
Test: CTS test
Change-Id: Ib854829b9aca4c2f5c54afa99a49701c95170a49
This commit is contained in:
Ajinkya Chalke
2023-01-25 00:53:42 +00:00
parent 7b16c91deb
commit d263cdca17
5 changed files with 69 additions and 6 deletions

View File

@@ -68,10 +68,14 @@ import android.service.notification.NotificationListenerService.RankingMap;
import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;
import android.view.IWindowManager;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.window.ScreenCapture;
import android.window.ScreenCapture.ScreenCaptureListener;
import android.window.ScreenCapture.ScreenshotSync;
import androidx.annotation.MainThread;
import androidx.annotation.Nullable;
@@ -143,6 +147,7 @@ public class BubbleController implements ConfigurationChangeListener {
private final SyncTransactionQueue mSyncQueue;
private final ShellController mShellController;
private final ShellCommandHandler mShellCommandHandler;
private final IWindowManager mWmService;
// Used to post to main UI thread
private final ShellExecutor mMainExecutor;
@@ -237,7 +242,8 @@ public class BubbleController implements ConfigurationChangeListener {
@ShellMainThread Handler mainHandler,
@ShellBackgroundThread ShellExecutor bgExecutor,
TaskViewTransitions taskViewTransitions,
SyncTransactionQueue syncQueue) {
SyncTransactionQueue syncQueue,
IWindowManager wmService) {
mContext = context;
mShellCommandHandler = shellCommandHandler;
mShellController = shellController;
@@ -269,6 +275,7 @@ public class BubbleController implements ConfigurationChangeListener {
mOneHandedOptional = oneHandedOptional;
mDragAndDropController = dragAndDropController;
mSyncQueue = syncQueue;
mWmService = wmService;
shellInit.addInitCallback(this::onInit, this);
}
@@ -1036,6 +1043,21 @@ public class BubbleController implements ConfigurationChangeListener {
}
}
/**
* Performs a screenshot that may exclude the bubble layer, if one is present. The screenshot
* can be access via the supplied {@link ScreenshotSync#get()} asynchronously.
*
* TODO(b/267324693): Implement the exclude layer functionality in screenshot.
*/
public void getScreenshotExcludingBubble(int displayId,
Pair<ScreenCaptureListener, ScreenshotSync> screenCaptureListener) {
try {
mWmService.captureDisplay(displayId, null, screenCaptureListener.first);
} catch (RemoteException e) {
Log.e(TAG, "Failed to capture screenshot");
}
}
/**
* Fills the overflow bubbles by loading them from disk.
*/
@@ -1749,6 +1771,25 @@ public class BubbleController implements ConfigurationChangeListener {
});
}
@Override
public boolean isAppBubbleTaskId(int taskId) {
Bubble appBubble = mBubbleData.getBubbleInStackWithKey(KEY_APP_BUBBLE);
return appBubble != null && appBubble.getTaskId() == taskId;
}
@Override
@Nullable
public ScreenshotSync getScreenshotExcludingBubble(int displayId) {
Pair<ScreenCaptureListener, ScreenshotSync> screenCaptureListener =
ScreenCapture.createSyncCaptureListener();
mMainExecutor.execute(
() -> BubbleController.this.getScreenshotExcludingBubble(displayId,
screenCaptureListener));
return screenCaptureListener.second;
}
@Override
public boolean handleDismissalInterception(BubbleEntry entry,
@Nullable List<BubbleEntry> children, IntConsumer removeCallback,

View File

@@ -16,6 +16,8 @@
package com.android.wm.shell.bubbles;
import static android.window.ScreenCapture.ScreenshotSync;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.PARAMETER;
@@ -24,11 +26,13 @@ import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.app.NotificationChannel;
import android.content.Intent;
import android.content.pm.UserInfo;
import android.hardware.HardwareBuffer;
import android.os.UserHandle;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationListenerService.RankingMap;
import android.util.Pair;
import android.util.SparseArray;
import android.window.ScreenCapture.ScreenshotHardwareBuffer;
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
@@ -132,6 +136,18 @@ public interface Bubbles {
*/
void showOrHideAppBubble(Intent intent);
/** @return true if the specified {@code taskId} corresponds to app bubble's taskId. */
boolean isAppBubbleTaskId(int taskId);
/**
* @return a {@link ScreenshotSync} after performing a screenshot that may exclude the bubble
* layer, if one is present. The underlying {@link ScreenshotHardwareBuffer} can be access via
* {@link ScreenshotSync#get()} asynchronously and care should be taken to
* {@link HardwareBuffer#close()} the associated
* {@link ScreenshotHardwareBuffer#getHardwareBuffer()} when no longer required.
*/
ScreenshotSync getScreenshotExcludingBubble(int displayId);
/**
* @return a bubble that matches the provided shortcutId, if one exists.
*/

View File

@@ -21,6 +21,7 @@ import android.content.pm.LauncherApps;
import android.os.Handler;
import android.os.UserManager;
import android.view.Choreographer;
import android.view.IWindowManager;
import android.view.WindowManager;
import com.android.internal.jank.InteractionJankMonitor;
@@ -170,14 +171,15 @@ public abstract class WMShellModule {
@ShellMainThread Handler mainHandler,
@ShellBackgroundThread ShellExecutor bgExecutor,
TaskViewTransitions taskViewTransitions,
SyncTransactionQueue syncQueue) {
SyncTransactionQueue syncQueue,
IWindowManager wmService) {
return new BubbleController(context, shellInit, shellCommandHandler, shellController, data,
null /* synchronizer */, floatingContentCoordinator,
new BubbleDataRepository(context, launcherApps, mainExecutor),
statusBarService, windowManager, windowManagerShellWrapper, userManager,
launcherApps, logger, taskStackListener, organizer, positioner, displayController,
oneHandedOptional, dragAndDropController, mainExecutor, mainHandler, bgExecutor,
taskViewTransitions, syncQueue);
taskViewTransitions, syncQueue, wmService);
}
//

View File

@@ -74,6 +74,7 @@ import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.Pair;
import android.util.SparseArray;
import android.view.IWindowManager;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
@@ -392,7 +393,8 @@ public class BubblesTest extends SysuiTestCase {
syncExecutor,
mock(Handler.class),
mTaskViewTransitions,
mock(SyncTransactionQueue.class));
mock(SyncTransactionQueue.class),
mock(IWindowManager.class));
mBubbleController.setExpandListener(mBubbleExpandListener);
spyOn(mBubbleController);

View File

@@ -20,6 +20,7 @@ import android.content.Context;
import android.content.pm.LauncherApps;
import android.os.Handler;
import android.os.UserManager;
import android.view.IWindowManager;
import android.view.WindowManager;
import com.android.internal.statusbar.IStatusBarService;
@@ -72,13 +73,14 @@ public class TestableBubbleController extends BubbleController {
ShellExecutor shellMainExecutor,
Handler shellMainHandler,
TaskViewTransitions taskViewTransitions,
SyncTransactionQueue syncQueue) {
SyncTransactionQueue syncQueue,
IWindowManager wmService) {
super(context, shellInit, shellCommandHandler, shellController, data, Runnable::run,
floatingContentCoordinator, dataRepository, statusBarService, windowManager,
windowManagerShellWrapper, userManager, launcherApps, bubbleLogger,
taskStackListener, shellTaskOrganizer, positioner, displayController,
oneHandedOptional, dragAndDropController, shellMainExecutor, shellMainHandler,
new SyncExecutor(), taskViewTransitions, syncQueue);
new SyncExecutor(), taskViewTransitions, syncQueue, wmService);
setInflateSynchronously(true);
onInit();
}